Browse Source

http2: add internal function isNoCachedConnError to test for ErrNoCachedConn

In a given program there may be two separate copies of
ErrNoCachedConn: the h2_bundle.go version in net/http, and the user's
golang.org/x/net/http2 version. We need to be able to detect either
in net/http.

This CL adds a function to report whether an error value represents
that type of error, and then a subsequent CL to net/http will use it
instead of ==.

Updates golang/go#22091

Change-Id: I86f1e20704eee29b8980707b700d7a290107dfd4
Reviewed-on: https://go-review.googlesource.com/87297
Reviewed-by: Tom Bergan <tombergan@google.com>
Brad Fitzpatrick 8 years ago
parent
commit
ab555f366c
2 changed files with 21 additions and 2 deletions
  1. 1 1
      http2/configure_transport.go
  2. 20 1
      http2/transport.go

+ 1 - 1
http2/configure_transport.go

@@ -73,7 +73,7 @@ type noDialH2RoundTripper struct{ t *Transport }
 
 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 	res, err := rt.t.RoundTrip(req)
-	if err == ErrNoCachedConn {
+	if isNoCachedConnError(err) {
 		return nil, http.ErrSkipAltProtocol
 	}
 	return res, err

+ 20 - 1
http2/transport.go

@@ -306,7 +306,26 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
 	return
 }
 
-var ErrNoCachedConn = errors.New("http2: no cached connection was available")
+// noCachedConnError is the concrete type of ErrNoCachedConn, which
+// 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 noCachedConnError struct{}
+
+func (noCachedConnError) IsHTTP2NoCachedConnError() {}
+func (noCachedConnError) 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 isNoCachedConnError(err error) bool {
+	_, ok := err.(interface{ IsHTTP2NoCachedConnError() })
+	return ok
+}
+
+var ErrNoCachedConn error = noCachedConnError{}
 
 // RoundTripOpt are options for the Transport.RoundTripOpt method.
 type RoundTripOpt struct {