http2: export a field of an internal type for use by net/http
Updates golang/go#22891
Change-Id: Ibde5ce0867a78703a5a4f04fafc3d709ea4cbda3
Reviewed-on: https://go-review.googlesource.com/123656
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/http2/configure_transport.go b/http2/configure_transport.go
index 088d6e2..6356b32 100644
--- a/http2/configure_transport.go
+++ b/http2/configure_transport.go
@@ -57,7 +57,7 @@
// registerHTTPSProtocol calls Transport.RegisterProtocol but
// converting panics into errors.
-func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
+func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
@@ -69,10 +69,12 @@
// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
// if there's already has a cached connection to the host.
-type noDialH2RoundTripper struct{ t *Transport }
+// (The field is exported so it can be accessed via reflect from net/http; tested
+// by TestNoDialH2RoundTripperType)
+type noDialH2RoundTripper struct{ *Transport }
func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
- res, err := rt.t.RoundTrip(req)
+ res, err := rt.Transport.RoundTrip(req)
if isNoCachedConnError(err) {
return nil, http.ErrSkipAltProtocol
}
diff --git a/http2/transport_test.go b/http2/transport_test.go
index 23cb820..5b5c076 100644
--- a/http2/transport_test.go
+++ b/http2/transport_test.go
@@ -4161,3 +4161,25 @@
t.Error("req2.Body unchanged")
}
}
+
+// Issue 22891: verify that the "https" altproto we register with net/http
+// is a certain type: a struct with one field with our *http2.Transport in it.
+func TestNoDialH2RoundTripperType(t *testing.T) {
+ t1 := new(http.Transport)
+ t2 := new(Transport)
+ rt := noDialH2RoundTripper{t2}
+ if err := registerHTTPSProtocol(t1, rt); err != nil {
+ t.Fatal(err)
+ }
+ rv := reflect.ValueOf(rt)
+ if rv.Type().Kind() != reflect.Struct {
+ t.Fatalf("kind = %v; net/http expects struct", rv.Type().Kind())
+ }
+ if n := rv.Type().NumField(); n != 1 {
+ t.Fatalf("fields = %d; net/http expects 1", n)
+ }
+ v := rv.Field(0)
+ if _, ok := v.Interface().(*Transport); !ok {
+ t.Fatalf("wrong kind %T; want *Transport", v.Interface())
+ }
+}