diff --git a/cmd/main.go b/cmd/main.go index 5e0ce6f..10b5cbc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -20,6 +20,7 @@ import ( "codeberg.org/codeberg/pages/server/certificates" "codeberg.org/codeberg/pages/server/database" "codeberg.org/codeberg/pages/server/gitea" + "codeberg.org/codeberg/pages/server/gzip" ) // AllowedCorsDomains lists the domains for which Cross-Origin Resource Sharing is allowed. @@ -88,14 +89,13 @@ func Serve(ctx *cli.Context) error { } // Create handler based on settings - handler := server.Handler(mainDomainSuffix, rawDomain, + httpsHandler := gzip.SetupCompression(server.Handler(mainDomainSuffix, rawDomain, giteaClient, giteaRoot, rawInfoPage, BlacklistedPaths, allowedCorsDomains, - dnsLookupCache, canonicalDomainCache) + dnsLookupCache, canonicalDomainCache)) - fastServer := server.SetupServer(handler) - httpServer := server.SetupHTTPACMEChallengeServer(challengeCache) + httpHandler := server.SetupHTTPACMEChallengeServer(challengeCache) // Setup listener and TLS log.Info().Msgf("Listening on https://%s", listeningAddress) @@ -135,7 +135,7 @@ func Serve(ctx *cli.Context) error { if enableHTTPServer { go func() { log.Info().Msg("Start HTTP server listening on :80") - err := http.ListenAndServe("[::]:80", httpServer) + err := http.ListenAndServe("[::]:80", httpHandler) if err != nil { log.Panic().Err(err).Msg("Couldn't start HTTP fastServer") } @@ -144,7 +144,7 @@ func Serve(ctx *cli.Context) error { // Start the web fastServer log.Info().Msgf("Start listening on %s", listener.Addr()) - if err := http.Serve(listener, fastServer); err != nil { + if err := http.Serve(listener, httpsHandler); err != nil { log.Panic().Err(err).Msg("Couldn't start fastServer") } diff --git a/server/gzip/gzip.go b/server/gzip/gzip.go new file mode 100644 index 0000000..fb77eaa --- /dev/null +++ b/server/gzip/gzip.go @@ -0,0 +1,37 @@ +package gzip + +import ( + "compress/gzip" + "net/http" + "strings" +) + +type gzipResponseWriter struct { + Writer *gzip.Writer + ResponseWriter http.ResponseWriter +} + +func (gz gzipResponseWriter) Header() http.Header { + return gz.ResponseWriter.Header() +} + +func (gz gzipResponseWriter) Write(b []byte) (int, error) { + return gz.Writer.Write(b) +} + +func (gz gzipResponseWriter) WriteHeader(statusCode int) { + gz.ResponseWriter.WriteHeader(statusCode) +} + +func SetupCompression(handler http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { + handler(w, r) + return + } + w.Header().Set("Content-Encoding", "gzip") + gz := gzip.NewWriter(w) + defer gz.Close() + handler(gzipResponseWriter{Writer: gz, ResponseWriter: w}, r) + } +} diff --git a/server/setup.go b/server/setup.go index 33204c0..e7194ed 100644 --- a/server/setup.go +++ b/server/setup.go @@ -9,11 +9,6 @@ import ( "codeberg.org/codeberg/pages/server/utils" ) -func SetupServer(handler http.HandlerFunc) http.HandlerFunc { - // TODO: enagle gzip compression - return handler -} - func SetupHTTPACMEChallengeServer(challengeCache cache.SetGetKey) http.HandlerFunc { challengePath := "/.well-known/acme-challenge/"