From 951d61bfcd44135bb2bb7a00a8ed890fb67e438e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doumenjou <925513+jbdoumenjou@users.noreply.github.com> Date: Fri, 12 Feb 2021 12:12:03 +0100 Subject: [PATCH] Apply content type exclusion on response Co-authored-by: kevinpollet --- docs/content/middlewares/compress.md | 4 +-- go.mod | 4 +-- go.sum | 6 ++-- pkg/middlewares/compress/compress.go | 9 +++--- pkg/middlewares/compress/compress_test.go | 36 +++++++++++++++-------- 5 files changed, 37 insertions(+), 22 deletions(-) diff --git a/docs/content/middlewares/compress.md b/docs/content/middlewares/compress.md index 40e7aad24..311820e67 100644 --- a/docs/content/middlewares/compress.md +++ b/docs/content/middlewares/compress.md @@ -71,9 +71,9 @@ http: ### `excludedContentTypes` -`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests to before compressing. +`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests and responses before compressing. -The requests with content types defined in `excludedContentTypes` are not compressed. +The responses with content types defined in `excludedContentTypes` are not compressed. Content types are compared in a case-insensitive, whitespace-ignored manner. diff --git a/go.mod b/go.mod index 548f4c645..11a9ff6d1 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/Masterminds/semver v1.4.2 // indirect github.com/Masterminds/sprig v2.22.0+incompatible github.com/Microsoft/hcsshim v0.8.7 // indirect - github.com/NYTimes/gziphandler v1.1.1 github.com/Shopify/sarama v1.23.1 // indirect github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000 github.com/abronan/valkeyrie v0.0.0-20200127174252-ef4277a138cd @@ -68,9 +67,10 @@ require ( github.com/prometheus/client_model v0.2.0 github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac github.com/sirupsen/logrus v1.7.0 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/tinylib/msgp v1.0.2 // indirect + github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888 github.com/traefik/paerser v0.1.1 github.com/traefik/yaegi v0.9.8 github.com/uber/jaeger-client-go v2.25.0+incompatible diff --git a/go.sum b/go.sum index 024679a81..4d14d54ff 100644 --- a/go.sum +++ b/go.sum @@ -89,8 +89,6 @@ github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tT github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= @@ -868,6 +866,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 h1:XGopsea1Dw7ecQ8JscCNQXDGYAKDiWjDeXnpN/+BY9g= github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -877,6 +877,8 @@ github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888 h1:GMY0C+M/w8xO+/NP3Kq6sroMd+z2KbbdVr1K8o2NLHk= +github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888/go.mod h1:sLqwoN03tkluITKL+lPEZbfsJQU2suYoKbrR/HeV9aM= github.com/traefik/paerser v0.1.1 h1:Suj0iA4hTAV6E4Dh5/++TXAj5u6iTwydBlFssIUz+9w= github.com/traefik/paerser v0.1.1/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE= github.com/traefik/yaegi v0.9.8 h1:sYGKV2d911B9olVsSO/nRmjIh+CQTffAUSzoyv4a4/4= diff --git a/pkg/middlewares/compress/compress.go b/pkg/middlewares/compress/compress.go index eb8e1af3d..42b0d01ea 100644 --- a/pkg/middlewares/compress/compress.go +++ b/pkg/middlewares/compress/compress.go @@ -6,8 +6,8 @@ import ( "mime" "net/http" - "github.com/NYTimes/gziphandler" "github.com/opentracing/opentracing-go/ext" + "github.com/traefik/gziphandler" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/middlewares" @@ -52,7 +52,7 @@ func (c *compress) ServeHTTP(rw http.ResponseWriter, req *http.Request) { c.next.ServeHTTP(rw, req) } else { ctx := middlewares.GetLoggerCtx(req.Context(), c.name, typeName) - gzipHandler(ctx, c.next).ServeHTTP(rw, req) + c.gzipHandler(ctx).ServeHTTP(rw, req) } } @@ -60,15 +60,16 @@ func (c *compress) GetTracingInformation() (string, ext.SpanKindEnum) { return c.name, tracing.SpanKindNoneEnum } -func gzipHandler(ctx context.Context, h http.Handler) http.Handler { +func (c *compress) gzipHandler(ctx context.Context) http.Handler { wrapper, err := gziphandler.GzipHandlerWithOpts( + gziphandler.ContentTypeExceptions(c.excludes), gziphandler.CompressionLevel(gzip.DefaultCompression), gziphandler.MinSize(gziphandler.DefaultMinSize)) if err != nil { log.FromContext(ctx).Error(err) } - return wrapper(h) + return wrapper(c.next) } func contains(values []string, val string) bool { diff --git a/pkg/middlewares/compress/compress_test.go b/pkg/middlewares/compress/compress_test.go index 2c7fb97f4..93f1d6575 100644 --- a/pkg/middlewares/compress/compress_test.go +++ b/pkg/middlewares/compress/compress_test.go @@ -7,9 +7,9 @@ import ( "net/http/httptest" "testing" - "github.com/NYTimes/gziphandler" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traefik/gziphandler" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/testhelpers" ) @@ -91,25 +91,26 @@ func TestShouldNotCompressWhenNoAcceptEncodingHeader(t *testing.T) { func TestShouldNotCompressWhenSpecificContentType(t *testing.T) { baseBody := generateBytes(gziphandler.DefaultMinSize) - next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - _, err := rw.Write(baseBody) - if err != nil { - http.Error(rw, err.Error(), http.StatusInternalServerError) - } - }) - testCases := []struct { - desc string - conf dynamic.Compress - reqContentType string + desc string + conf dynamic.Compress + reqContentType string + respContentType string }{ { - desc: "text/event-stream", + desc: "Exclude Request Content-Type", conf: dynamic.Compress{ ExcludedContentTypes: []string{"text/event-stream"}, }, reqContentType: "text/event-stream", }, + { + desc: "Exclude Response Content-Type", + conf: dynamic.Compress{ + ExcludedContentTypes: []string{"text/event-stream"}, + }, + respContentType: "text/event-stream", + }, { desc: "application/grpc", conf: dynamic.Compress{}, @@ -128,6 +129,17 @@ func TestShouldNotCompressWhenSpecificContentType(t *testing.T) { req.Header.Add(contentTypeHeader, test.reqContentType) } + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + if len(test.respContentType) > 0 { + rw.Header().Set(contentTypeHeader, test.respContentType) + } + + _, err := rw.Write(baseBody) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + }) + handler, err := New(context.Background(), next, test.conf, "test") require.NoError(t, err)