diff --git a/middlewares/compress.go b/middlewares/compress.go index 810f58904..4f1fb751d 100644 --- a/middlewares/compress.go +++ b/middlewares/compress.go @@ -3,6 +3,7 @@ package middlewares import ( "compress/gzip" "net/http" + "strings" "github.com/NYTimes/gziphandler" "github.com/containous/traefik/log" @@ -13,7 +14,12 @@ type Compress struct{} // ServerHTTP is a function used by Negroni func (c *Compress) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { - gzipHandler(next).ServeHTTP(rw, r) + contentType := r.Header.Get("Content-Type") + if strings.HasPrefix(contentType, "application/grpc") { + next.ServeHTTP(rw, r) + } else { + gzipHandler(next).ServeHTTP(rw, r) + } } func gzipHandler(h http.Handler) http.Handler { diff --git a/middlewares/compress_test.go b/middlewares/compress_test.go index 605349e50..743a02dba 100644 --- a/middlewares/compress_test.go +++ b/middlewares/compress_test.go @@ -16,6 +16,7 @@ import ( const ( acceptEncodingHeader = "Accept-Encoding" contentEncodingHeader = "Content-Encoding" + contentTypeHeader = "Content-Type" varyHeader = "Vary" gzipValue = "gzip" ) @@ -81,6 +82,26 @@ func TestShouldNotCompressWhenNoAcceptEncodingHeader(t *testing.T) { assert.EqualValues(t, rw.Body.Bytes(), fakeBody) } +func TestShouldNotCompressWhenGRPC(t *testing.T) { + handler := &Compress{} + + req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost", nil) + req.Header.Add(acceptEncodingHeader, gzipValue) + req.Header.Add(contentTypeHeader, "application/grpc") + + baseBody := generateBytes(gziphandler.DefaultMinSize) + next := func(rw http.ResponseWriter, r *http.Request) { + rw.Write(baseBody) + } + + rw := httptest.NewRecorder() + handler.ServeHTTP(rw, req, next) + + assert.Empty(t, rw.Header().Get(acceptEncodingHeader)) + assert.Empty(t, rw.Header().Get(contentEncodingHeader)) + assert.EqualValues(t, rw.Body.Bytes(), baseBody) +} + func TestIntegrationShouldNotCompress(t *testing.T) { fakeCompressedBody := generateBytes(100000) comp := &Compress{}