1
0
mirror of https://github.com/golang/go synced 2024-11-17 16:14:42 -07:00

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>
This commit is contained in:
Brad Fitzpatrick 2015-12-01 19:19:55 +00:00
parent 3b3f422afe
commit 9bad99574a
2 changed files with 40 additions and 9 deletions

View File

@ -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")

View File

@ -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