mirror of
https://github.com/caddyserver/caddy.git
synced 2025-12-08 06:09:53 +00:00
no copy
This commit is contained in:
parent
f9aefaff3e
commit
880d1af665
1 changed files with 19 additions and 10 deletions
|
|
@ -437,9 +437,17 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
|
||||||
reqHost := clonedReq.Host
|
reqHost := clonedReq.Host
|
||||||
reqHeader := clonedReq.Header
|
reqHeader := clonedReq.Header
|
||||||
|
|
||||||
var bufferedReqBody []byte
|
// If the cloned request body was fully buffered, keep a reference to its
|
||||||
if reqBodyBuf, ok := clonedReq.Body.(bodyReadCloser); ok && reqBodyBuf.body == nil {
|
// buffer so we can reuse it across retries and return it to the pool
|
||||||
bufferedReqBody = append([]byte(nil), reqBodyBuf.buf.Bytes()...)
|
// once we’re done.
|
||||||
|
var bufferedReqBody *bytes.Buffer
|
||||||
|
if reqBodyBuf, ok := clonedReq.Body.(bodyReadCloser); ok && reqBodyBuf.body == nil && reqBodyBuf.buf != nil {
|
||||||
|
bufferedReqBody = reqBodyBuf.buf
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
bufferedReqBody.Reset()
|
||||||
|
bufPool.Put(bufferedReqBody)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
@ -461,7 +469,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
|
||||||
// produces an error, the request can be repeated to the next backend with
|
// 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)
|
// the full body (retries should only happen for idempotent requests) (see #6259)
|
||||||
if bufferedReqBody != nil {
|
if bufferedReqBody != nil {
|
||||||
clonedReq.Body = io.NopCloser(bytes.NewReader(bufferedReqBody))
|
clonedReq.Body = io.NopCloser(bytes.NewReader(bufferedReqBody.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var done bool
|
var done bool
|
||||||
|
|
@ -1534,18 +1542,19 @@ type BufferedTransport interface {
|
||||||
// roundtrip succeeded, but an error occurred after-the-fact.
|
// roundtrip succeeded, but an error occurred after-the-fact.
|
||||||
type roundtripSucceededError struct{ error }
|
type roundtripSucceededError struct{ error }
|
||||||
|
|
||||||
// bodyReadCloser is a reader that, upon closing, will return
|
// bodyReadCloser is a reader that wraps an optional buffer and
|
||||||
// its buffer to the pool and close the underlying body reader.
|
// an underlying body reader. Close will only close the underlying
|
||||||
|
// body (if any); the buffer's lifetime is managed by the caller.
|
||||||
type bodyReadCloser struct {
|
type bodyReadCloser struct {
|
||||||
io.Reader
|
io.Reader
|
||||||
buf *bytes.Buffer
|
buf *bytes.Buffer
|
||||||
body io.ReadCloser
|
body io.ReadCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brc bodyReadCloser) Close() error {
|
func (b bodyReadCloser) Close() error {
|
||||||
bufPool.Put(brc.buf)
|
// For fully-buffered bodies, body is nil, so Close is a no-op.
|
||||||
if brc.body != nil {
|
if b.body != nil {
|
||||||
return brc.body.Close()
|
return b.body.Close()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue