mirror of
https://github.com/hanzoai/ingress.git
synced 2026-10-26 02:47:15 +00:00
When the middleware decides not to compress a response (its type is excluded or not included, it is already encoded, or its type does not parse), Write sent the held status but left headersSent false, so close sent it again. net/http logs that second call as "superfluous response.WriteHeader call", once per such response: under a config that compresses only text bodies, once per streamed completion. The four branches now go through pass, which sends the status, marks it sent, and writes the body through. Co-authored-by: Hanzo Dev <[email protected]>
66 lines
2.3 KiB
Go
66 lines
2.3 KiB
Go
package compress
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/hanzoai/ingress/pkg/config/dynamic"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// statusCounter records every WriteHeader the client-facing writer receives.
|
|
type statusCounter struct {
|
|
*httptest.ResponseRecorder
|
|
statuses []int
|
|
}
|
|
|
|
func (s *statusCounter) WriteHeader(code int) {
|
|
s.statuses = append(s.statuses, code)
|
|
s.ResponseRecorder.WriteHeader(code)
|
|
}
|
|
|
|
// A response the middleware decides not to compress sends its status once. The
|
|
// second send is what net/http logs as "superfluous response.WriteHeader call",
|
|
// once per such response — every streamed completion, under a config that
|
|
// compresses only text bodies.
|
|
func TestUncompressedResponseSendsStatusOnce(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
conf dynamic.Compress
|
|
ct string
|
|
ce string
|
|
}{
|
|
{desc: "not included", conf: dynamic.Compress{Encodings: []string{"zstd", "br"}, IncludedContentTypes: []string{"application/json"}}, ct: "text/event-stream"},
|
|
{desc: "excluded", conf: dynamic.Compress{Encodings: []string{"zstd", "br"}, ExcludedContentTypes: []string{"text/event-stream"}}, ct: "text/event-stream"},
|
|
{desc: "already encoded", conf: dynamic.Compress{Encodings: []string{"zstd", "br"}}, ct: "application/json", ce: "gzip"},
|
|
{desc: "unparsable type", conf: dynamic.Compress{Encodings: []string{"zstd", "br"}}, ct: "not a type;;"},
|
|
}
|
|
for _, enc := range []string{"zstd", "br"} {
|
|
for _, tc := range cases {
|
|
t.Run(enc+"/"+tc.desc, func(t *testing.T) {
|
|
h, err := New(context.Background(), http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
|
|
rw.Header().Set("Content-Type", tc.ct)
|
|
if tc.ce != "" {
|
|
rw.Header().Set("Content-Encoding", tc.ce)
|
|
}
|
|
rw.WriteHeader(http.StatusCreated)
|
|
_, _ = rw.Write(bigTestBody)
|
|
}), tc.conf, "test")
|
|
require.NoError(t, err)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.Header.Set(acceptEncodingHeader, enc)
|
|
rw := &statusCounter{ResponseRecorder: httptest.NewRecorder()}
|
|
h.ServeHTTP(rw, req)
|
|
|
|
assert.Equal(t, []int{http.StatusCreated}, rw.statuses)
|
|
assert.Equal(t, tc.ce, rw.Header().Get(contentEncoding))
|
|
assert.Equal(t, bigTestBody, rw.Body.Bytes())
|
|
})
|
|
}
|
|
}
|
|
}
|