aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/caddyhttp/reverseproxy/reverseproxy.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp/reverseproxy/reverseproxy.go')
-rw-r--r--modules/caddyhttp/reverseproxy/reverseproxy.go9
1 files changed, 9 insertions, 0 deletions
diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go
index 048539e93..980e259c9 100644
--- a/modules/caddyhttp/reverseproxy/reverseproxy.go
+++ b/modules/caddyhttp/reverseproxy/reverseproxy.go
@@ -439,6 +439,15 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
var proxyErr error
var retries int
for {
+ // if the request body was buffered (and only the entire body, hence no body
+ // set to read from after the buffer), make reading from the body idempotent
+ // and reusable, so if a backend partially or fully reads the body but then
+ // produces an error, the request can be repeated to the next backend with
+ // the full body (retries should only happen for idempotent requests) (see #6259)
+ if reqBodyBuf, ok := r.Body.(bodyReadCloser); ok && reqBodyBuf.body == nil {
+ r.Body = io.NopCloser(bytes.NewReader(reqBodyBuf.buf.Bytes()))
+ }
+
var done bool
done, proxyErr = h.proxyLoopIteration(clonedReq, r, w, proxyErr, start, retries, repl, reqHeader, reqHost, next)
if done {