@marcel91200 / caddy Mirror · read-only / commits / a7885aab
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 19:45 UTC

intercept: use already buffered response if possible when intercepting (#7028)

WeidiDeng committed Oct 21, 2025 at 12:48 UTC a7885aabec375db38ac6c221c7c709dc83122535
1 file changed +28 -2
modules/caddyhttp/intercept/intercept.go
+28 -2
@@ -17,6 +17,7 @@ package intercept
17 import (
18 "bytes"
19 "fmt"
20 + "io"
21 "net/http"
22 "strconv"
23 "strings"
@@ -175,10 +176,35 @@ func (ir Intercept) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddy
176 c.Write(zap.Int("handler", rec.handlerIndex))
177 }
178
178 - // pass the request through the response handler routes
179 - return rec.handler.Routes.Compile(next).ServeHTTP(w, r)
179 + // response recorder doesn't create a new copy of the original headers, they're
180 + // present in the original response writer
181 + // create a new recorder to see if any response body from the new handler is present,
182 + // if not, use the already buffered response body
183 + recorder := caddyhttp.NewResponseRecorder(w, nil, nil)
184 + if err := rec.handler.Routes.Compile(emptyHandler).ServeHTTP(recorder, r); err != nil {
185 + return err
186 + }
187 +
188 + // no new response status and the status is not 0
189 + if recorder.Status() == 0 && rec.Status() != 0 {
190 + w.WriteHeader(rec.Status())
191 + }
192 +
193 + // no new response body and there is some in the original response
194 + // TODO: what if the new response doesn't have a body by design?
195 + // see: https://github.com/caddyserver/caddy/pull/6232#issue-2235224400
196 + if recorder.Size() == 0 && buf.Len() > 0 {
197 + _, err := io.Copy(w, buf)
198 + return err
199 + }
200 + return nil
201 }
202
203 +// this handler does nothing because everything we need is already buffered
204 +var emptyHandler caddyhttp.Handler = caddyhttp.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) error {
205 + return nil
206 +})
207 +
208 // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax:
209 //
210 // intercept [<matcher>] {