@marcel91200 / caddy Mirror · read-only / commits / d93e027e
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 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 {