@@ -622,8 +622,9 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.
622622 // attacks, so it is strongly recommended to only use this
623623 // feature if absolutely required, if read timeouts are
624624 // set, and if body size is limited
625- if h .BufferRequests && req .Body != nil {
626- req .Body = h .bufferedBody (req .Body )
625+ if (h .BufferRequests || isChunkedRequest (req )) && req .Body != nil {
626+ req .Body , req .ContentLength = h .bufferedBody (req .Body )
627+ req .Header .Set ("Content-Length" , strconv .FormatInt (req .ContentLength , 10 ))
627628 }
628629
629630 if req .ContentLength == 0 {
@@ -854,7 +855,7 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe
854855
855856 // if enabled, buffer the response body
856857 if h .BufferResponses {
857- res .Body = h .bufferedBody (res .Body )
858+ res .Body , _ = h .bufferedBody (res .Body )
858859 }
859860
860861 // see if any response handler is configured for this response from the backend
@@ -1125,7 +1126,8 @@ func (h Handler) provisionUpstream(upstream *Upstream) {
11251126
11261127// bufferedBody reads originalBody into a buffer, then returns a reader for the buffer.
11271128// Always close the return value when done with it, just like if it was the original body!
1128- func (h Handler ) bufferedBody (originalBody io.ReadCloser ) io.ReadCloser {
1129+ func (h Handler ) bufferedBody (originalBody io.ReadCloser ) (io.ReadCloser , int64 ) {
1130+ var written int64
11291131 buf := bufPool .Get ().(* bytes.Buffer )
11301132 buf .Reset ()
11311133 if h .MaxBufferSize > 0 {
@@ -1135,16 +1137,25 @@ func (h Handler) bufferedBody(originalBody io.ReadCloser) io.ReadCloser {
11351137 Reader : io .MultiReader (buf , originalBody ),
11361138 buf : buf ,
11371139 body : originalBody ,
1138- }
1140+ }, n
11391141 }
11401142 } else {
1141- _ , _ = io .Copy (buf , originalBody )
1143+ written , _ = io .Copy (buf , originalBody )
11421144 }
11431145 originalBody .Close () // no point in keeping it open
11441146 return bodyReadCloser {
11451147 Reader : buf ,
11461148 buf : buf ,
1149+ }, written
1150+ }
1151+
1152+ func isChunkedRequest (req * http.Request ) bool {
1153+ for _ , transferEncoding := range req .TransferEncoding {
1154+ if transferEncoding == "chunked" {
1155+ return true
1156+ }
11471157 }
1158+ return false
11481159}
11491160
11501161// cloneRequest makes a semi-deep clone of origReq.
0 commit comments