From f73ab1e79f98362cca776cf09fc6c0c84842c87e Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Thu, 3 Oct 2024 17:54:56 +0200 Subject: [PATCH] Do not set the content-type when response has no body (#1013) --- gzhttp/compress.go | 23 +++++++++++++---------- gzhttp/compress_test.go | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/gzhttp/compress.go b/gzhttp/compress.go index 7b697dd87..52e3077ec 100644 --- a/gzhttp/compress.go +++ b/gzhttp/compress.go @@ -131,15 +131,15 @@ func (w *GzipResponseWriter) Write(b []byte) (int, error) { // If the Content-Length is larger than minSize or the current buffer is larger than minSize, then continue. if cl >= w.minSize || len(w.buf) >= w.minSize { - // If a Content-Type wasn't specified, infer it from the current buffer. - if ct == "" { + // If a Content-Type wasn't specified, infer it from the current buffer when the response has a body. + if ct == "" && bodyAllowedForStatus(w.code) && len(w.buf) > 0 { ct = http.DetectContentType(w.buf) - } - // Handles the intended case of setting a nil Content-Type (as for http/server or http/fs) - // Set the header only if the key does not exist - if _, ok := hdr[contentType]; w.setContentType && !ok { - hdr.Set(contentType, ct) + // Handles the intended case of setting a nil Content-Type (as for http/server or http/fs) + // Set the header only if the key does not exist + if _, ok := hdr[contentType]; w.setContentType && !ok { + hdr.Set(contentType, ct) + } } // If the Content-Type is acceptable to GZIP, initialize the GZIP writer. @@ -349,12 +349,14 @@ func (w *GzipResponseWriter) Close() error { ce = w.Header().Get(contentEncoding) cr = w.Header().Get(contentRange) ) - if ct == "" { + + // Detects the response content-type when it does not exist and the response has a body. + if ct == "" && bodyAllowedForStatus(w.code) && len(w.buf) > 0 { ct = http.DetectContentType(w.buf) // Handles the intended case of setting a nil Content-Type (as for http/server or http/fs) // Set the header only if the key does not exist - if _, ok := w.Header()[contentType]; bodyAllowedForStatus(w.code) && w.setContentType && !ok { + if _, ok := w.Header()[contentType]; w.setContentType && !ok { w.Header().Set(contentType, ct) } } @@ -393,7 +395,8 @@ func (w *GzipResponseWriter) Flush() { cr = w.Header().Get(contentRange) ) - if ct == "" { + // Detects the response content-type when it does not exist and the response has a body. + if ct == "" && bodyAllowedForStatus(w.code) && len(w.buf) > 0 { ct = http.DetectContentType(w.buf) // Handles the intended case of setting a nil Content-Type (as for http/server or http/fs) diff --git a/gzhttp/compress_test.go b/gzhttp/compress_test.go index 94ff0f332..0f610cbcf 100644 --- a/gzhttp/compress_test.go +++ b/gzhttp/compress_test.go @@ -1617,6 +1617,25 @@ func TestNoContentTypeWhenNoContent(t *testing.T) { } +func TestNoContentTypeWhenNoBody(t *testing.T) { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + wrapper, err := NewWrapper() + assertNil(t, err) + + req, _ := http.NewRequest("GET", "/", nil) + req.Header.Set("Accept-Encoding", "gzip") + resp := httptest.NewRecorder() + wrapper(handler).ServeHTTP(resp, req) + res := resp.Result() + + assertEqual(t, http.StatusOK, res.StatusCode) + assertEqual(t, "", res.Header.Get("Content-Type")) + +} + func TestContentTypeDetect(t *testing.T) { for _, tt := range sniffTests { t.Run(tt.desc, func(t *testing.T) {