From 6f90742dec93cedee6424b25ccbf180bcfbdb431 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Mon, 13 Feb 2017 19:12:58 -0800 Subject: [PATCH] Set the Content-Encoding header earlier for Static Static uses ServeContent, which looks to see if the Content-Encoding header is set or not to determine if it should set the Content-Length. If Content-Length is set by something it will be wrong after the gzip compression happens and stricter routers (and tools like curl) will have problems with the request. Fixes #806 --- middleware/compress.go | 5 +++-- middleware/compress_test.go | 27 +++++++++++++++++++++++++++ middleware/testdata/compress/data | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 middleware/testdata/compress/data diff --git a/middleware/compress.go b/middleware/compress.go index 3d4a7622..d3bed847 100644 --- a/middleware/compress.go +++ b/middleware/compress.go @@ -66,6 +66,7 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc { res := c.Response() res.Header().Add(echo.HeaderVary, echo.HeaderAcceptEncoding) + res.Header().Add(echo.HeaderContentEncoding, gzipScheme) // issue #806 if strings.Contains(c.Request().Header.Get(echo.HeaderAcceptEncoding), gzipScheme) { rw := res.Writer w, err := gzip.NewWriterLevel(rw, config.Level) @@ -92,8 +93,8 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc { } func (w *gzipResponseWriter) WriteHeader(code int) { - if code != http.StatusNoContent { // Issue #489 - w.ResponseWriter.Header().Set(echo.HeaderContentEncoding, gzipScheme) + if code == http.StatusNoContent { // Issue #489 + w.ResponseWriter.Header().Del(echo.HeaderContentEncoding) } w.ResponseWriter.WriteHeader(code) } diff --git a/middleware/compress_test.go b/middleware/compress_test.go index a31ddcc4..409ec8a1 100644 --- a/middleware/compress_test.go +++ b/middleware/compress_test.go @@ -3,6 +3,7 @@ package middleware import ( "bytes" "compress/gzip" + "io/ioutil" "net/http" "net/http/httptest" "testing" @@ -71,3 +72,29 @@ func TestGzipErrorReturned(t *testing.T) { assert.Equal(t, http.StatusNotFound, rec.Code) assert.Empty(t, rec.Header().Get(echo.HeaderContentEncoding)) } + +// Issue #806 +func TestGzipWithStatic(t *testing.T) { + e := echo.New() + e.Use(Gzip()) + e.Static("/test", "testdata/compress") + req, _ := http.NewRequest(echo.GET, "/test/data", nil) + req.Header.Set(echo.HeaderAcceptEncoding, gzipScheme) + rec := httptest.NewRecorder() + e.ServeHTTP(rec, req) + assert.Equal(t, http.StatusOK, rec.Code) + // Data is written out in chunks when Content-Length == "", so only + // validate the content length if it's not set. + if cl := rec.Header().Get("Content-Length"); cl != "" { + assert.Equal(t, cl, rec.Body.Len()) + } + r, err := gzip.NewReader(rec.Body) + assert.NoError(t, err) + defer r.Close() + want, err := ioutil.ReadFile("testdata/compress/data") + if assert.NoError(t, err) { + var buf bytes.Buffer + buf.ReadFrom(r) + assert.Equal(t, want, buf.Bytes()) + } +} diff --git a/middleware/testdata/compress/data b/middleware/testdata/compress/data new file mode 100644 index 00000000..0aa6fb54 --- /dev/null +++ b/middleware/testdata/compress/data @@ -0,0 +1 @@ +test data \ No newline at end of file