aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/http/server.go')
-rw-r--r--src/net/http/server.go40
1 files changed, 10 insertions, 30 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go
index ad99741177d..198102ffd21 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -577,37 +577,17 @@ func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
return io.CopyBuffer(writerOnly{w}, src, buf)
}
- // sendfile path:
-
- // Do not start actually writing response until src is readable.
- // If body length is <= sniffLen, sendfile/splice path will do
- // little anyway. This small read also satisfies sniffing the
- // body in case Content-Type is missing.
- nr, er := src.Read(buf[:sniffLen])
- atEOF := errors.Is(er, io.EOF)
- n += int64(nr)
-
- if nr > 0 {
- // Write the small amount read normally.
- nw, ew := w.Write(buf[:nr])
- if ew != nil {
- err = ew
- } else if nr != nw {
- err = io.ErrShortWrite
+ // Copy the first sniffLen bytes before switching to ReadFrom.
+ // This ensures we don't start writing the response before the
+ // 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.CopyBuffer(writerOnly{w}, io.LimitReader(src, sniffLen), buf)
+ n += n0
+ if err != nil || n0 < sniffLen {
+ return n, err
}
}
- if err == nil && er != nil && !atEOF {
- err = er
- }
-
- // Do not send StatusOK in the error case where nothing has been written.
- if err == nil && !w.wroteHeader {
- w.WriteHeader(StatusOK) // nr == 0, no error (or EOF)
- }
-
- if err != nil || atEOF {
- return n, err
- }
w.w.Flush() // get rid of any previous writes
w.cw.flush() // make sure Header is written; flush data to rwc
@@ -620,7 +600,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
}