From ac3c2994c20967aeb0010fec550f73ae2937d649 Mon Sep 17 00:00:00 2001 From: xkx Date: Wed, 20 Nov 2024 15:23:35 +0000 Subject: [PATCH] fix(compress): correct content encoding negotiation Signed-off-by: xkx --- .../lifted/influx/httpd/handler_compress.go | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/lib/util/lifted/influx/httpd/handler_compress.go b/lib/util/lifted/influx/httpd/handler_compress.go index f4fa493e..9a1b67ee 100644 --- a/lib/util/lifted/influx/httpd/handler_compress.go +++ b/lib/util/lifted/influx/httpd/handler_compress.go @@ -37,36 +37,44 @@ type lazyCompressResponseWriter struct { func compressFilter(inner http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var writer io.Writer = w - contentEncoding := r.Header.Get("Content-Encoding") - switch { - case strings.Contains(contentEncoding, "gzip"): - gz := getGzipWriter(w) - defer gz.Close() - writer = gz - w.Header().Set("Content-Encoding", "gzip") - case strings.Contains(contentEncoding, "zstd"): - enc := getZstdWriter(w) - defer enc.Close() - writer = enc - w.Header().Set("Content-Encoding", "zstd") - default: - inner.ServeHTTP(w, r) - return - } - - compressEnabledWriter := &lazyCompressResponseWriter{ResponseWriter: w, Writer: writer} - - if f, ok := w.(http.Flusher); ok { - compressEnabledWriter.Flusher = f + acceptEncoding := r.Header.Get("Accept-Encoding") + encodings := strings.Split(acceptEncoding, ",") + + // if mutliple encodings are supported, server will use the first one that is supported + for _, encoding := range encodings { + encoding = strings.TrimSpace(encoding) + switch encoding { + case "gzip": + gz := getGzipWriter(w) + defer gz.Close() + writer = gz + w.Header().Set("Content-Encoding", "gzip") + break + case "zstd": + enc := getZstdWriter(w) + defer enc.Close() + writer = enc + w.Header().Set("Content-Encoding", "zstd") + break + } + if writer != w { + break + } } - if cn, ok := w.(http.CloseNotifier); ok { - compressEnabledWriter.CloseNotifier = cn + if writer == w { + inner.ServeHTTP(w, r) + } else { + compressEnabledWriter := &lazyCompressResponseWriter{ResponseWriter: w, Writer: writer} + if f, ok := w.(http.Flusher); ok { + compressEnabledWriter.Flusher = f + } + if cn, ok := w.(http.CloseNotifier); ok { + compressEnabledWriter.CloseNotifier = cn + } + defer compressEnabledWriter.Close() + inner.ServeHTTP(compressEnabledWriter, r) } - - defer compressEnabledWriter.Close() - - inner.ServeHTTP(compressEnabledWriter, r) }) }