author | Brad Fitzpatrick
<bradfitz@golang.org> 2016-09-01 04:28:38 UTC |
committer | Brad Fitzpatrick
<bradfitz@golang.org> 2016-09-01 05:44:53 UTC |
parent | 9bc2a3340c92c17a20edcd0080e93851ed58f5d5 |
http2/go17_not18.go | +36 | -0 |
http2/go18.go | +11 | -0 |
http2/not_go17.go | +26 | -0 |
http2/server_test.go | +14 | -22 |
http2/transport.go | +1 | -1 |
http2/transport_test.go | +2 | -2 |
diff --git a/http2/go17_not18.go b/http2/go17_not18.go new file mode 100644 index 0000000..b4c52ec --- /dev/null +++ b/http2/go17_not18.go @@ -0,0 +1,36 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7,!go1.8 + +package http2 + +import "crypto/tls" + +// temporary copy of Go 1.7's private tls.Config.clone: +func cloneTLSConfig(c *tls.Config) *tls.Config { + return &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, + Renegotiation: c.Renegotiation, + } +} diff --git a/http2/go18.go b/http2/go18.go new file mode 100644 index 0000000..c2ae167 --- /dev/null +++ b/http2/go18.go @@ -0,0 +1,11 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package http2 + +import "crypto/tls" + +func cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() } diff --git a/http2/not_go17.go b/http2/not_go17.go index 28df0c1..667867f 100644 --- a/http2/not_go17.go +++ b/http2/not_go17.go @@ -7,6 +7,7 @@ package http2 import ( + "crypto/tls" "net" "net/http" ) @@ -49,3 +50,28 @@ func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { func requestWithContext(req *http.Request, ctx contextContext) *http.Request { return req } + +// temporary copy of Go 1.6's private tls.Config.clone: +func cloneTLSConfig(c *tls.Config) *tls.Config { + return &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + } +} diff --git a/http2/server_test.go b/http2/server_test.go index ecacf84..ee5cafa 100644 --- a/http2/server_test.go +++ b/http2/server_test.go @@ -2931,51 +2931,43 @@ func (c *issue53Conn) SetWriteDeadline(t time.Time) error { return nil } // golang.org/issue/12895 func TestConfigureServer(t *testing.T) { tests := []struct { - name string - in http.Server - wantErr string + name string + tlsConfig *tls.Config + wantErr string }{ { name: "empty server", - in: http.Server{}, }, { name: "just the required cipher suite", - in: http.Server{ - TLSConfig: &tls.Config{ - CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, - }, + tlsConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, }, { name: "missing required cipher suite", - in: http.Server{ - TLSConfig: &tls.Config{ - CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, - }, + tlsConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, }, wantErr: "is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", }, { name: "required after bad", - in: http.Server{ - TLSConfig: &tls.Config{ - CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, - }, + tlsConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, wantErr: "contains an HTTP/2-approved cipher suite (0xc02f), but it comes after", }, { name: "bad after required", - in: http.Server{ - TLSConfig: &tls.Config{ - CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA}, - }, + tlsConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA}, }, }, } for _, tt := range tests { - err := ConfigureServer(&tt.in, nil) + srv := &http.Server{TLSConfig: tt.tlsConfig} + err := ConfigureServer(srv, nil) if (err != nil) != (tt.wantErr != "") { if tt.wantErr != "" { t.Errorf("%s: success, but want error", tt.name) @@ -2986,7 +2978,7 @@ func TestConfigureServer(t *testing.T) { if err != nil && tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr) { t.Errorf("%s: err = %v; want substring %q", tt.name, err, tt.wantErr) } - if err == nil && !tt.in.TLSConfig.PreferServerCipherSuites { + if err == nil && !srv.TLSConfig.PreferServerCipherSuites { t.Errorf("%s: PreferServerCipherSuite is false; want true", tt.name) } } diff --git a/http2/transport.go b/http2/transport.go index bcd27ae..47c66d9 100644 --- a/http2/transport.go +++ b/http2/transport.go @@ -356,7 +356,7 @@ func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, er func (t *Transport) newTLSConfig(host string) *tls.Config { cfg := new(tls.Config) if t.TLSClientConfig != nil { - *cfg = *t.TLSClientConfig + *cfg = *cloneTLSConfig(t.TLSClientConfig) } if !strSliceContains(cfg.NextProtos, NextProtoTLS) { cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...) diff --git a/http2/transport_test.go b/http2/transport_test.go index a7cce94..e220c91 100644 --- a/http2/transport_test.go +++ b/http2/transport_test.go @@ -510,7 +510,7 @@ func TestConfigureTransport(t *testing.T) { if err != nil { t.Fatal(err) } - if got := fmt.Sprintf("%#v", *t1); !strings.Contains(got, `"h2"`) { + if got := fmt.Sprintf("%#v", t1); !strings.Contains(got, `"h2"`) { // Laziness, to avoid buildtags. t.Errorf("stringification of HTTP/1 transport didn't contain \"h2\": %v", got) } @@ -2105,7 +2105,7 @@ func testTransportUsesGoAwayDebugError(t *testing.T, failMidBody bool) { DebugData: goAwayDebugData, } if !reflect.DeepEqual(err, want) { - t.Errorf("RoundTrip error = %T: %#v, want %T (%#T)", err, err, want, want) + t.Errorf("RoundTrip error = %T: %#v, want %T (%#v)", err, err, want, want) } return nil }