Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 12, 13:15 UTC
reverseproxy: Reuse buffered request body even if partially drained
Previous commit only works when the backends don't read any of the body first.
Matthew Holt committed
Apr 22, 2024 at 15:22 UTC
d93e027e01905406671ed8df295d5e48d16645c2
1 file changed
+9
modules/caddyhttp/reverseproxy/reverseproxy.go
+9
@@ -439,6 +439,15 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
439
var proxyErr error
440
var retries int
441
for {
442
+ // if the request body was buffered (and only the entire body, hence no body
443
+ // set to read from after the buffer), make reading from the body idempotent
444
+ // and reusable, so if a backend partially or fully reads the body but then
445
+ // produces an error, the request can be repeated to the next backend with
446
+ // the full body (retries should only happen for idempotent requests) (see #6259)
447
+ if reqBodyBuf, ok := r.Body.(bodyReadCloser); ok && reqBodyBuf.body == nil {
448
+ r.Body = io.NopCloser(bytes.NewReader(reqBodyBuf.buf.Bytes()))
449
+ }
450
+
451
var done bool
452
done, proxyErr = h.proxyLoopIteration(clonedReq, r, w, proxyErr, start, retries, repl, reqHeader, reqHost, next)
453
if done {