mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-26 10:49:10 +02:00
fix(middleware): gate only body response modifiers
Replace the rewrite requirement check with a BodyResponseModifier marker and treat header and body modifiers separately. This ensures header/status rewrites still apply when body rewriting is blocked (for binary, encoded, or chunked responses), while body changes are skipped safely. It also avoids body reset/close side effects and returns early on passthrough responses. Update middleware tests to cover split header/body behavior and themed middleware body-skip scenarios.
This commit is contained in:
@@ -54,7 +54,11 @@ type (
|
||||
RequestModifier interface {
|
||||
before(w http.ResponseWriter, r *http.Request) (proceed bool)
|
||||
}
|
||||
ResponseModifier interface{ modifyResponse(r *http.Response) error }
|
||||
ResponseModifier interface{ modifyResponse(r *http.Response) error }
|
||||
BodyResponseModifier interface {
|
||||
ResponseModifier
|
||||
isBodyResponseModifier()
|
||||
}
|
||||
MiddlewareWithSetup interface{ setup() }
|
||||
MiddlewareFinalizer interface{ finalize() }
|
||||
MiddlewareFinalizerWithError interface {
|
||||
@@ -208,8 +212,15 @@ func (m *Middleware) ServeHTTP(next http.HandlerFunc, w http.ResponseWriter, r *
|
||||
next(w, r)
|
||||
return
|
||||
}
|
||||
isBodyModifier := isBodyResponseModifier(exec)
|
||||
|
||||
lrm := httputils.NewLazyResponseModifier(w, canBufferAndModifyResponseBody)
|
||||
shouldBuffer := canBufferAndModifyResponseBody
|
||||
if !isBodyModifier {
|
||||
// Header-only response modifiers do not need body rewrite capability checks.
|
||||
// We still respect max buffer limits and may fall back to passthrough for large bodies.
|
||||
shouldBuffer = func(http.Header) bool { return true }
|
||||
}
|
||||
lrm := httputils.NewLazyResponseModifier(w, shouldBuffer)
|
||||
lrm.SetMaxBufferedBytes(maxModifiableBody)
|
||||
defer func() {
|
||||
_, err := lrm.FlushRelease()
|
||||
@@ -225,6 +236,9 @@ func (m *Middleware) ServeHTTP(next http.HandlerFunc, w http.ResponseWriter, r *
|
||||
}
|
||||
|
||||
rm := lrm.ResponseModifier()
|
||||
if rm.IsPassthrough() {
|
||||
return
|
||||
}
|
||||
currentBody := rm.BodyReader()
|
||||
currentResp := &http.Response{
|
||||
StatusCode: rm.StatusCode(),
|
||||
@@ -246,7 +260,7 @@ func (m *Middleware) ServeHTTP(next http.HandlerFunc, w http.ResponseWriter, r *
|
||||
maps.Copy(rm.Header(), respToModify.Header)
|
||||
|
||||
// override the body if changed
|
||||
if respToModify.Body != currentBody {
|
||||
if isBodyModifier && respToModify.Body != currentBody {
|
||||
err := rm.SetBody(respToModify.Body)
|
||||
if err != nil {
|
||||
m.LogError(r).Err(err).Msg("failed to set response body")
|
||||
|
||||
Reference in New Issue
Block a user