return copyBuffer(dst, src, buf)
}
-var bufPool = sync.Pool{
- New: func() any {
- b := make([]byte, 32*1024)
- return &b
- },
-}
-
// copyBuffer is the actual implementation of Copy and CopyBuffer.
// if buf is nil, one is allocated.
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
return rt.ReadFrom(src)
}
if buf == nil {
- bufp := bufPool.Get().(*[]byte)
- defer bufPool.Put(bufp)
- buf = *bufp
+ size := 32 * 1024
+ if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
+ if l.N < 1 {
+ size = 1
+ } else {
+ size = int(l.N)
+ }
+ }
+ buf = make([]byte, size)
}
for {
nr, er := src.Read(buf)
return len(s), nil
}
+var blackHolePool = sync.Pool{
+ New: func() any {
+ b := make([]byte, 8192)
+ return &b
+ },
+}
+
func (discard) ReadFrom(r Reader) (n int64, err error) {
- bufp := bufPool.Get().(*[]byte)
+ bufp := blackHolePool.Get().(*[]byte)
readSize := 0
for {
readSize, err = r.Read(*bufp)
n += int64(readSize)
if err != nil {
- bufPool.Put(bufp)
+ blackHolePool.Put(bufp)
if err == EOF {
return n, nil
}
// 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.
// 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
return n, err
}
- n0, err := io.Copy(writerOnly{w}, src)
+ n0, err := io.CopyBuffer(writerOnly{w}, src, buf)
n += n0
return n, err
}
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: