From bb4356dbfd03343bef39746f9937e57c93453e97 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 10 Jan 2018 21:50:13 +0000 Subject: net/http: fix "http2: no cached connection..." error with x/net/http2 The net/http Transport was testing for a sentinel x/net/http2 error value with ==, which meant it was only testing the bundled version. If a user enabled http2 via golang.org/x/net/http2, the error value had a different name. This also updates the bundled x/net/http2 to git rev ab555f36 for: http2: add internal function isNoCachedConnError to test for ErrNoCachedConn https://golang.org/cl/87297 Fixes #22091 Change-Id: I3fb85e2b7ba7d145dd66767e1795a56de633958c Reviewed-on: https://go-review.googlesource.com/87298 Reviewed-by: Tom Bergan --- src/net/http/h2_bundle.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/net/http/h2_bundle.go') diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 161a1ed137..7a1564f755 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -989,7 +989,7 @@ type http2noDialH2RoundTripper struct{ t *http2Transport } func (rt http2noDialH2RoundTripper) RoundTrip(req *Request) (*Response, error) { res, err := rt.t.RoundTrip(req) - if err == http2ErrNoCachedConn { + if http2isNoCachedConnError(err) { return nil, ErrSkipAltProtocol } return res, err @@ -6856,7 +6856,27 @@ func (sew http2stickyErrWriter) Write(p []byte) (n int, err error) { return } -var http2ErrNoCachedConn = errors.New("http2: no cached connection was available") +// noCachedConnError is the concrete type of ErrNoCachedConn, needs to be detected +// by net/http regardless of whether it's its bundled version (in h2_bundle.go with a rewritten type name) +// or from a user's x/net/http2. As such, as it has a unique method name (IsHTTP2NoCachedConnError) that +// net/http sniffs for via func isNoCachedConnError. +type http2noCachedConnError struct{} + +func (http2noCachedConnError) IsHTTP2NoCachedConnError() {} + +func (http2noCachedConnError) Error() string { return "http2: no cached connection was available" } + +// isNoCachedConnError reports whether err is of type noCachedConnError +// or its equivalent renamed type in net/http2's h2_bundle.go. Both types +// may coexist in the same running program. +func http2isNoCachedConnError(err error) bool { + _, ok := err.(interface { + IsHTTP2NoCachedConnError() + }) + return ok +} + +var http2ErrNoCachedConn error = http2noCachedConnError{} // RoundTripOpt are options for the Transport.RoundTripOpt method. type http2RoundTripOpt struct { -- cgit v1.3-6-g1900