Skip to content

Commit d93e027

Browse files
committed
reverseproxy: Reuse buffered request body even if partially drained
Previous commit only works when the backends don't read any of the body first.
1 parent 613d544 commit d93e027

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

modules/caddyhttp/reverseproxy/reverseproxy.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,15 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
439439
var proxyErr error
440440
var retries int
441441
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+
442451
var done bool
443452
done, proxyErr = h.proxyLoopIteration(clonedReq, r, w, proxyErr, start, retries, repl, reqHeader, reqHost, next)
444453
if done {

0 commit comments

Comments
 (0)