diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2017-06-19 22:59:56 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2017-06-19 23:26:32 +0000 |
| commit | be855e3f28507dd3e34eb4699c84493eeaae68db (patch) | |
| tree | dead2febec862e78803e337cdad162c86bbb01bd /src | |
| parent | 26b07c43a3b160d06ed48657aeea40c84f21078d (diff) | |
| download | go-be855e3f28507dd3e34eb4699c84493eeaae68db.tar.xz | |
net/http: update bundled http2
Updates http2 to x/net/http2 git rev 3d7ac2a5d for:
http2: fix Server race
https://golang.org/cl/20704
Fixes #20704
Change-Id: I803288f94a8a462ad0960b0c29c2dfee27b9f1ae
Reviewed-on: https://go-review.googlesource.com/46093
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Tom Bergan <tombergan@google.com>
Reviewed-by: Tom Bergan <tombergan@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/net/http/h2_bundle.go | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 0533f56f0e..9ef24ab6cc 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -5946,6 +5946,7 @@ type http2responseWriterState struct { wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet. sentHeader bool // have we sent the header frame? handlerDone bool // handler has finished + dirty bool // a Write failed; don't reuse this responseWriterState sentContentLen int64 // non-zero if handler set a Content-Length header wroteBytes int64 @@ -6027,6 +6028,7 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { date: date, }) if err != nil { + rws.dirty = true return 0, err } if endStream { @@ -6048,6 +6050,7 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { if len(p) > 0 || endStream { // only send a 0 byte DATA frame if we're ending the stream. if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { + rws.dirty = true return 0, err } } @@ -6059,6 +6062,9 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { trailers: rws.trailers, endStream: true, }) + if err != nil { + rws.dirty = true + } return len(p), err } return len(p), nil @@ -6198,7 +6204,7 @@ func http2cloneHeader(h Header) Header { // // * Handler calls w.Write or w.WriteString -> // * -> rws.bw (*bufio.Writer) -> -// * (Handler migth call Flush) +// * (Handler might call Flush) // * -> chunkWriter{rws} // * -> responseWriterState.writeChunk(p []byte) // * -> responseWriterState.writeChunk (most of the magic; see comment there) @@ -6237,10 +6243,19 @@ func (w *http2responseWriter) write(lenData int, dataB []byte, dataS string) (n func (w *http2responseWriter) handlerDone() { rws := w.rws + dirty := rws.dirty rws.handlerDone = true w.Flush() w.rws = nil - http2responseWriterStatePool.Put(rws) + if !dirty { + // Only recycle the pool if all prior Write calls to + // the serverConn goroutine completed successfully. If + // they returned earlier due to resets from the peer + // there might still be write goroutines outstanding + // from the serverConn referencing the rws memory. See + // issue 20704. + http2responseWriterStatePool.Put(rws) + } } // Push errors. |
