fix(middleware): stream header-only response rewrites without body buffering

Header-only modifiers no longer use LazyResponseModifier with buffering
always enabled. They wrap the response with ModifyResponseWriter and
return after invoking the next handler.

Body modifiers still use LazyResponseModifier with canBufferAndModifyResponseBody.
Add a regression test that uses a 64MiB Content-Length with a small body.
This commit is contained in:
yusing
2026-04-18 14:12:00 +08:00
parent 64fc885815
commit 61f00516dd
2 changed files with 35 additions and 6 deletions

View File

@@ -260,6 +260,36 @@ func TestMiddlewareResponseRewriteGateServeHTTP(t *testing.T) {
}
}
func TestMiddlewareHeaderRewriteDoesNotBufferLargeBody(t *testing.T) {
headerMid, err := responseHeaderRewrite.New(OptionsRaw{
"status_code": http.StatusAccepted,
"header_key": "X-Rewrite",
"header_val": "1",
})
expect.NoError(t, err)
req := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
rw := httptest.NewRecorder()
next := func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "video/mp4")
w.Header().Set("Content-Length", strconv.Itoa(64*1024*1024))
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("video"))
}
headerMid.ServeHTTP(next, rw, req)
resp := rw.Result()
defer resp.Body.Close()
data, readErr := io.ReadAll(resp.Body)
expect.NoError(t, readErr)
expect.Equal(t, resp.StatusCode, http.StatusAccepted)
expect.Equal(t, resp.Header.Get("X-Rewrite"), "1")
expect.Equal(t, string(data), "video")
}
func TestThemedSkipsBodyRewriteWhenRewriteBlocked(t *testing.T) {
result, err := newMiddlewareTest(Themed, &testArgs{
middlewareOpt: OptionsRaw{