diff --git a/gzip.go b/gzip.go index 3ff4f08..901c455 100644 --- a/gzip.go +++ b/gzip.go @@ -192,10 +192,16 @@ func (w *GzipResponseWriter) Close() error { // http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter // an http.Flusher. func (w *GzipResponseWriter) Flush() { - if w.gw != nil { - w.gw.Flush() + if w.gw == nil { + // Only flush once startGzip has been called. + // + // Flush is thus a no-op until the written body + // exceeds minSize. + return } + w.gw.Flush() + if fw, ok := w.ResponseWriter.(http.Flusher); ok { fw.Flush() } diff --git a/gzip_test.go b/gzip_test.go index 3f6f6f4..633a86c 100644 --- a/gzip_test.go +++ b/gzip_test.go @@ -306,6 +306,24 @@ func TestStatusCodes(t *testing.T) { } } +func TestFlushBeforeWrite(t *testing.T) { + b := []byte(testBody) + handler := GzipHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.WriteHeader(http.StatusNotFound) + rw.(http.Flusher).Flush() + rw.Write(b) + })) + r := httptest.NewRequest(http.MethodGet, "/", nil) + r.Header.Set("Accept-Encoding", "gzip") + w := httptest.NewRecorder() + handler.ServeHTTP(w, r) + + res := w.Result() + assert.Equal(t, http.StatusNotFound, res.StatusCode) + assert.Equal(t, "gzip", res.Header.Get("Content-Encoding")) + assert.NotEqual(t, b, w.Body.Bytes()) +} + func TestIgnoreSubsequentWriteHeader(t *testing.T) { handler := GzipHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500)