diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2015-12-01 19:19:55 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2015-12-02 02:03:19 +0000 |
| commit | 9bad99574ad90f877ee4d8aa36ca503f4167fab6 (patch) | |
| tree | 8115a74b01b766fa5a0809aa038ca579e910da9d /src | |
| parent | 3b3f422afed632a7d332e03444a908abc170d402 (diff) | |
| download | go-9bad99574ad90f877ee4d8aa36ca503f4167fab6.tar.xz | |
net/http: enable HTTP/2 on all Transports, not just the DefaultTransport
This mirrors the same behavior and API from the server code to the
client side: if TLSNextProto is nil, HTTP/2 is on by default for
both. If it's non-nil, the user was trying to do something fancy and
step out of their way.
Updates #6891
Change-Id: Ia31808b71f336a8d5b44b985591d72113429e1d4
Reviewed-on: https://go-review.googlesource.com/17300
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/net/http/transport.go | 28 | ||||
| -rw-r--r-- | src/net/http/transport_test.go | 21 |
2 files changed, 40 insertions, 9 deletions
diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 5ba072007f..1cd5d84574 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -40,15 +40,6 @@ var DefaultTransport RoundTripper = &Transport{ ExpectContinueTimeout: 1 * time.Second, } -func init() { - if !strings.Contains(os.Getenv("GODEBUG"), "h2client=0") { - err := http2ConfigureTransport(DefaultTransport.(*Transport)) - if err != nil { - panic(err) - } - } -} - // DefaultMaxIdleConnsPerHost is the default value of Transport's // MaxIdleConnsPerHost. const DefaultMaxIdleConnsPerHost = 2 @@ -138,12 +129,30 @@ type Transport struct { // called with the request's authority (such as "example.com" // or "example.com:1234") and the TLS connection. The function // must return a RoundTripper that then handles the request. + // If TLSNextProto is nil, HTTP/2 support is enabled automatically. TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper + nextProtoOnce sync.Once // guards initialization of TLSNextProto (onceSetNextProtoDefaults) + // TODO: tunable on global max cached connections // TODO: tunable on timeout on cached connections } +// onceSetNextProtoDefaults initializes TLSNextProto. +// It must be called via t.nextProtoOnce.Do. +func (t *Transport) onceSetNextProtoDefaults() { + if strings.Contains(os.Getenv("GODEBUG"), "h2client=0") { + return + } + if t.TLSNextProto != nil { + return + } + err := http2ConfigureTransport(t) + if err != nil { + log.Printf("Error enabling Transport HTTP/2 support: %v", err) + } +} + // ProxyFromEnvironment returns the URL of the proxy to use for a // given request, as indicated by the environment variables // HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions @@ -216,6 +225,7 @@ func (tr *transportRequest) extraHeaders() Header { // For higher-level HTTP client support (such as handling of cookies // and redirects), see Get, Post, and the Client type. func (t *Transport) RoundTrip(req *Request) (*Response, error) { + t.nextProtoOnce.Do(t.onceSetNextProtoDefaults) if req.URL == nil { req.closeBody() return nil, errors.New("http: nil Request.URL") diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index eaed3a484d..e5c8501e19 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -2921,6 +2921,27 @@ func TestTransportPrefersResponseOverWriteError(t *testing.T) { } } +func TestTransportAutomaticHTTP2(t *testing.T) { + tr := &Transport{} + _, err := tr.RoundTrip(new(Request)) + if err == nil { + t.Error("expected error from RoundTrip") + } + if tr.TLSNextProto["h2"] == nil { + t.Errorf("HTTP/2 not registered.") + } + + // Now with TLSNextProto set: + tr = &Transport{TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper)} + _, err = tr.RoundTrip(new(Request)) + if err == nil { + t.Error("expected error from RoundTrip") + } + if tr.TLSNextProto["h2"] != nil { + t.Errorf("HTTP/2 registered, despite non-nil TLSNextProto field") + } +} + func wantBody(res *Response, err error, want string) error { if err != nil { return err |
