Skip to content

Commit 7a62274

Browse files
committed
net/http: make Transport use new connection if over HTTP/2 concurrency limit
The Go HTTP/1 client will make as many new TCP connections as the user requests. The HTTP/2 client tried to have that behavior, but the policy of whether a connection is re-usable didn't take into account the extra 1 stream counting against SETTINGS_MAX_CONCURRENT_STREAMS so in practice users were getting errors. For example, if the server's advertised max concurrent streams is 100 and 200 concurrrent Go HTTP requests ask for a connection at once, all 200 will think they can reuse that TCP connection, but then 100 will fail later when the number of concurrent streams exceeds 100. Instead, recognize the "no cached connections" error value in the shouldRetryRequest method, so those 100 will retry a new connection. This is the conservative fix for Go 1.7 so users don't get errors, and to match the HTTP/1 behavior. Issues #13957 and #13774 are the more involved bugs for Go 1.8. Updates #16582 Updates #13957 Change-Id: I1f15a7ce60c07a4baebca87675836d6fe03993e8 Reviewed-on: https://go-review.googlesource.com/25580 TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Chris Broadfoot <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]>
1 parent 219ca60 commit 7a62274

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

src/net/http/transport.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,15 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) {
398398
// HTTP request on a new connection. The non-nil input error is the
399399
// error from roundTrip.
400400
func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool {
401+
if err == http2ErrNoCachedConn {
402+
// Issue 16582: if the user started a bunch of
403+
// requests at once, they can all pick the same conn
404+
// and violate the server's max concurrent streams.
405+
// Instead, match the HTTP/1 behavior for now and dial
406+
// again to get a new TCP connection, rather than failing
407+
// this request.
408+
return true
409+
}
401410
if err == errMissingHost {
402411
// User error.
403412
return false

0 commit comments

Comments
 (0)