aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/h2_bundle.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2021-12-02 03:55:25 +0000
committerMichael Knyszek <mknyszek@google.com>2021-12-02 04:43:33 +0000
commitb29e772caf5089638777d84bf9f136926415f1f2 (patch)
tree7d6f9129aee0a3cf57a252607e2736515fefdd7c /src/net/http/h2_bundle.go
parent0f9838eeb119ef9c49e70a8388c25f02567a5a14 (diff)
downloadgo-b29e772caf5089638777d84bf9f136926415f1f2.tar.gz
go-b29e772caf5089638777d84bf9f136926415f1f2.zip
[release-branch.go1.16] net/http: update bundled golang.org/x/net/http2
Pull in approved backports to golang.org/x/net/http2: 64539c1 http2: don't count aborted streams as active in tests e677a40 ipv6: OpenBSD does not appear to support multicast loopback d8ae719 net/http2: Fix handling of expect continue cc2f99c http2: avoid busy loop when ResponseHeaderTimeout is set 5533dda http2: avoid spurious RoundTrip error when server closes and resets stream 26ec667 http2: close conns after use when req.Close is set By doing: $ go get -d golang.org/x/net@internal-branch.go1.16-vendor go: downloading golang.org/x/net v0.0.0-20211201233224-64539c132272 go get: upgraded golang.org/x/net v0.0.0-20211101194150-d8c3cde3c676 => v0.0.0-20211201233224-64539c132272 $ go mod tidy $ go mod vendor $ go generate -run=bundle std Fixes #49904. Fixes #49623. Fixes #49661. Fixes #49560. Fixes #49908. Fixes #49910. Change-Id: I73261b189f84cf1919a79129ec36a1c187723133 Reviewed-on: https://go-review.googlesource.com/c/go/+/368594 Trust: Michael Knyszek <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Diffstat (limited to 'src/net/http/h2_bundle.go')
-rw-r--r--src/net/http/h2_bundle.go81
1 files changed, 49 insertions, 32 deletions
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 0fd8da1d15..735f1b5eac 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -7653,36 +7653,49 @@ func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
}
}
+ handleResponseHeaders := func() (*Response, error) {
+ res := cs.res
+ if res.StatusCode > 299 {
+ // On error or status code 3xx, 4xx, 5xx, etc abort any
+ // ongoing write, assuming that the server doesn't care
+ // about our request body. If the server replied with 1xx or
+ // 2xx, however, then assume the server DOES potentially
+ // want our body (e.g. full-duplex streaming:
+ // golang.org/issue/13444). If it turns out the server
+ // doesn't, they'll RST_STREAM us soon enough. This is a
+ // heuristic to avoid adding knobs to Transport. Hopefully
+ // we can keep it.
+ cs.abortRequestBodyWrite()
+ }
+ res.Request = req
+ res.TLS = cc.tlsState
+ if res.Body == http2noBody && http2actualContentLength(req) == 0 {
+ // If there isn't a request or response body still being
+ // written, then wait for the stream to be closed before
+ // RoundTrip returns.
+ if err := waitDone(); err != nil {
+ return nil, err
+ }
+ }
+ return res, nil
+ }
+
for {
select {
case <-cs.respHeaderRecv:
- res := cs.res
- if res.StatusCode > 299 {
- // On error or status code 3xx, 4xx, 5xx, etc abort any
- // ongoing write, assuming that the server doesn't care
- // about our request body. If the server replied with 1xx or
- // 2xx, however, then assume the server DOES potentially
- // want our body (e.g. full-duplex streaming:
- // golang.org/issue/13444). If it turns out the server
- // doesn't, they'll RST_STREAM us soon enough. This is a
- // heuristic to avoid adding knobs to Transport. Hopefully
- // we can keep it.
- cs.abortRequestBodyWrite()
- }
- res.Request = req
- res.TLS = cc.tlsState
- if res.Body == http2noBody && http2actualContentLength(req) == 0 {
- // If there isn't a request or response body still being
- // written, then wait for the stream to be closed before
- // RoundTrip returns.
- if err := waitDone(); err != nil {
- return nil, err
- }
- }
- return res, nil
+ return handleResponseHeaders()
case <-cs.abort:
- waitDone()
- return nil, cs.abortErr
+ select {
+ case <-cs.respHeaderRecv:
+ // If both cs.respHeaderRecv and cs.abort are signaling,
+ // pick respHeaderRecv. The server probably wrote the
+ // response and immediately reset the stream.
+ // golang.org/issue/49645
+ return handleResponseHeaders()
+ default:
+ waitDone()
+ return nil, cs.abortErr
+ }
case <-ctx.Done():
err := ctx.Err()
cs.abortStream(err)
@@ -7742,6 +7755,9 @@ func (cs *http2clientStream) writeRequest(req *Request) (err error) {
return err
}
cc.addStreamLocked(cs) // assigns stream ID
+ if http2isConnectionCloseRequest(req) {
+ cc.doNotReuse = true
+ }
cc.mu.Unlock()
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
@@ -7765,12 +7781,12 @@ func (cs *http2clientStream) writeRequest(req *Request) (err error) {
}
continueTimeout := cc.t.expectContinueTimeout()
- if continueTimeout != 0 &&
- !httpguts.HeaderValuesContainsToken(
- req.Header["Expect"],
- "100-continue") {
- continueTimeout = 0
- cs.on100 = make(chan struct{}, 1)
+ if continueTimeout != 0 {
+ if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") {
+ continueTimeout = 0
+ } else {
+ cs.on100 = make(chan struct{}, 1)
+ }
}
// Past this point (where we send request headers), it is possible for
@@ -7839,6 +7855,7 @@ func (cs *http2clientStream) writeRequest(req *Request) (err error) {
case <-respHeaderTimer:
return http2errTimeout
case <-respHeaderRecv:
+ respHeaderRecv = nil
respHeaderTimer = nil // keep waiting for END_STREAM
case <-cs.abort:
return cs.abortErr