mirror of
https://github.com/golang/go
synced 2024-11-26 14:46:47 -07:00
net/http: simplify transfer body; reduces allocations too
benchmark old ns/op new ns/op delta BenchmarkServerFakeConnNoKeepAlive 14431 14247 -1.28% BenchmarkServerFakeConnWithKeepAlive 11618 11357 -2.25% BenchmarkServerFakeConnWithKeepAliveLite 6735 6427 -4.57% BenchmarkServerHandlerTypeLen 8842 8740 -1.15% BenchmarkServerHandlerNoLen 8001 7828 -2.16% BenchmarkServerHandlerNoType 8270 8227 -0.52% BenchmarkServerHandlerNoHeader 6148 5920 -3.71% benchmark old allocs new allocs delta BenchmarkServerFakeConnNoKeepAlive 30 29 -3.33% BenchmarkServerFakeConnWithKeepAlive 25 24 -4.00% BenchmarkServerFakeConnWithKeepAliveLite 10 9 -10.00% BenchmarkServerHandlerTypeLen 18 17 -5.56% BenchmarkServerHandlerNoLen 15 14 -6.67% BenchmarkServerHandlerNoType 16 15 -6.25% BenchmarkServerHandlerNoHeader 10 9 -10.00% benchmark old bytes new bytes delta BenchmarkServerFakeConnNoKeepAlive 2557 2492 -2.54% BenchmarkServerFakeConnWithKeepAlive 2260 2194 -2.92% BenchmarkServerFakeConnWithKeepAliveLite 1092 1026 -6.04% BenchmarkServerHandlerTypeLen 1941 1875 -3.40% BenchmarkServerHandlerNoLen 1898 1832 -3.48% BenchmarkServerHandlerNoType 1906 1840 -3.46% BenchmarkServerHandlerNoHeader 1092 1026 -6.04% Update #5195 R=golang-dev, daniel.morsing CC=golang-dev https://golang.org/cl/9492044
This commit is contained in:
parent
b98a4d1a10
commit
27f7427995
@ -1814,7 +1814,15 @@ func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eofReader is a non-nil io.ReadCloser that always returns EOF.
|
// eofReader is a non-nil io.ReadCloser that always returns EOF.
|
||||||
var eofReader = ioutil.NopCloser(strings.NewReader(""))
|
// It embeds a *strings.Reader so it still has a WriteTo method
|
||||||
|
// and io.Copy won't need a buffer.
|
||||||
|
var eofReader = &struct {
|
||||||
|
*strings.Reader
|
||||||
|
io.Closer
|
||||||
|
}{
|
||||||
|
strings.NewReader(""),
|
||||||
|
ioutil.NopCloser(nil),
|
||||||
|
}
|
||||||
|
|
||||||
// initNPNRequest is an HTTP handler that initializes certain
|
// initNPNRequest is an HTTP handler that initializes certain
|
||||||
// uninitialized fields in its *Request. Such partially-initialized
|
// uninitialized fields in its *Request. Such partially-initialized
|
||||||
|
@ -328,12 +328,12 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
|
|||||||
switch {
|
switch {
|
||||||
case chunked(t.TransferEncoding):
|
case chunked(t.TransferEncoding):
|
||||||
if noBodyExpected(t.RequestMethod) {
|
if noBodyExpected(t.RequestMethod) {
|
||||||
t.Body = &body{Reader: eofReader, closing: t.Close}
|
t.Body = eofReader
|
||||||
} else {
|
} else {
|
||||||
t.Body = &body{Reader: newChunkedReader(r), hdr: msg, r: r, closing: t.Close}
|
t.Body = &body{Reader: newChunkedReader(r), hdr: msg, r: r, closing: t.Close}
|
||||||
}
|
}
|
||||||
case realLength == 0:
|
case realLength == 0:
|
||||||
t.Body = &body{Reader: eofReader, closing: t.Close}
|
t.Body = eofReader
|
||||||
case realLength > 0:
|
case realLength > 0:
|
||||||
t.Body = &body{Reader: io.LimitReader(r, realLength), closing: t.Close}
|
t.Body = &body{Reader: io.LimitReader(r, realLength), closing: t.Close}
|
||||||
default:
|
default:
|
||||||
@ -343,7 +343,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
|
|||||||
t.Body = &body{Reader: r, closing: t.Close}
|
t.Body = &body{Reader: r, closing: t.Close}
|
||||||
} else {
|
} else {
|
||||||
// Persistent connection (i.e. HTTP/1.1)
|
// Persistent connection (i.e. HTTP/1.1)
|
||||||
t.Body = &body{Reader: eofReader, closing: t.Close}
|
t.Body = eofReader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,8 +518,6 @@ type body struct {
|
|||||||
r *bufio.Reader // underlying wire-format reader for the trailer
|
r *bufio.Reader // underlying wire-format reader for the trailer
|
||||||
closing bool // is the connection to be closed after reading body?
|
closing bool // is the connection to be closed after reading body?
|
||||||
closed bool
|
closed bool
|
||||||
|
|
||||||
res *response // response writer for server requests, else nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrBodyReadAfterClose is returned when reading a Request or Response
|
// ErrBodyReadAfterClose is returned when reading a Request or Response
|
||||||
@ -618,14 +616,6 @@ func (b *body) Close() error {
|
|||||||
case b.hdr == nil && b.closing:
|
case b.hdr == nil && b.closing:
|
||||||
// no trailer and closing the connection next.
|
// no trailer and closing the connection next.
|
||||||
// no point in reading to EOF.
|
// no point in reading to EOF.
|
||||||
case b.res != nil && b.res.requestBodyLimitHit:
|
|
||||||
// In a server request, don't continue reading from the client
|
|
||||||
// if we've already hit the maximum body size set by the
|
|
||||||
// handler. If this is set, that also means the TCP connection
|
|
||||||
// is about to be closed, so getting to the next HTTP request
|
|
||||||
// in the stream is not necessary.
|
|
||||||
case b.Reader == eofReader:
|
|
||||||
// Nothing to read. No need to io.Copy from it.
|
|
||||||
default:
|
default:
|
||||||
// Fully consume the body, which will also lead to us reading
|
// Fully consume the body, which will also lead to us reading
|
||||||
// the trailer headers after the body, if present.
|
// the trailer headers after the body, if present.
|
||||||
|
Loading…
Reference in New Issue
Block a user