aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/server.go
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2023-02-09 14:24:46 -0800
committerDamien Neil <dneil@google.com>2023-02-10 16:34:44 +0000
commitb02d5d325a4e93c88ecfc83a094c252148caa748 (patch)
treeacd16cfa1d3a7dac9dc014a02b15abc7ff054c40 /src/net/http/server.go
parent6e5c26084f9f3bc910181854a4ff20851188e222 (diff)
downloadgo-b02d5d325a4e93c88ecfc83a094c252148caa748.tar.xz
Revert "io: allocate copy buffers from a pool"
This reverts CL 456555. Reason for revert: This seems too likely to exercise race conditions in code where a Write call continues to access its buffer after returning. The HTTP/2 ResponseWriter is one such example. Reverting this change while we think about this some more. For #57202 Change-Id: Ic86823f81d7da410ea6b3f17fb5b3f9a979e3340 Reviewed-on: https://go-review.googlesource.com/c/go/+/467095 Reviewed-by: Bryan Mills <bcmills@google.com> Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/net/http/server.go')
-rw-r--r--src/net/http/server.go17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go
index bb31761ade..c15f0f58cb 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -567,12 +567,16 @@ type writerOnly struct {
// to a *net.TCPConn with sendfile, or from a supported src type such
// as a *net.TCPConn on Linux with splice.
func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
+ bufp := copyBufPool.Get().(*[]byte)
+ buf := *bufp
+ defer copyBufPool.Put(bufp)
+
// Our underlying w.conn.rwc is usually a *TCPConn (with its
// own ReadFrom method). If not, just fall back to the normal
// copy method.
rf, ok := w.conn.rwc.(io.ReaderFrom)
if !ok {
- return io.Copy(writerOnly{w}, src)
+ return io.CopyBuffer(writerOnly{w}, src, buf)
}
// Copy the first sniffLen bytes before switching to ReadFrom.
@@ -580,7 +584,7 @@ func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
// source is available (see golang.org/issue/5660) and provides
// enough bytes to perform Content-Type sniffing when required.
if !w.cw.wroteHeader {
- n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
+ n0, err := io.CopyBuffer(writerOnly{w}, io.LimitReader(src, sniffLen), buf)
n += n0
if err != nil || n0 < sniffLen {
return n, err
@@ -598,7 +602,7 @@ func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
return n, err
}
- n0, err := io.Copy(writerOnly{w}, src)
+ n0, err := io.CopyBuffer(writerOnly{w}, src, buf)
n += n0
return n, err
}
@@ -795,6 +799,13 @@ var (
bufioWriter4kPool sync.Pool
)
+var copyBufPool = sync.Pool{
+ New: func() any {
+ b := make([]byte, 32*1024)
+ return &b
+ },
+}
+
func bufioWriterPool(size int) *sync.Pool {
switch size {
case 2 << 10: