diff --git a/src/net/http/server.go b/src/net/http/server.go index 1ca5a227efb9a8..237cd00d419a99 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -1957,7 +1957,7 @@ func (c *conn) serve(ctx context.Context) { } }() - if tlsConn, ok := c.rwc.(*tls.Conn); ok { + if tlsConn, ok := c.rwc.(tlsConn); ok { tlsTO := c.server.tlsHandshakeTimeout() if tlsTO > 0 { dl := time.Now().Add(tlsTO) @@ -1987,13 +1987,20 @@ func (c *conn) serve(ctx context.Context) { c.tlsState = new(tls.ConnectionState) *c.tlsState = tlsConn.ConnectionState() if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) { + // New HTTP/2 Handler at https://go-review.googlesource.com/c/go/+/616097/2/src/net/http/server.go + + tc, ok := tlsConn.(*tls.Conn) + if !ok { + return + } + if fn := c.server.TLSNextProto[proto]; fn != nil { - h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}} + h := initALPNRequest{ctx, tc, serverHandler{c.server}} // Mark freshly created HTTP/2 as active and prevent any server state hooks // from being run on these connections. This prevents closeIdleConns from // closing such connections. See issue https://golang.org/issue/39776. c.setState(c.rwc, StateActive, skipHooks) - fn(c.server, tlsConn, h) + fn(c.server, tc, h) } return } diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 07b3a9e1e72ba6..9a0563e27562cf 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -1727,6 +1727,11 @@ func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptr return nil } +type tlsConn interface { + HandshakeContext(ctx context.Context) error + ConnectionState() tls.ConnectionState +} + type erringRoundTripper interface { RoundTripErr() error } @@ -1757,7 +1762,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers if err != nil { return nil, wrapErr(err) } - if tc, ok := pconn.conn.(*tls.Conn); ok { + if tc, ok := pconn.conn.(tlsConn); ok { // Handshake here, in case DialTLS didn't. TLSNextProto below // depends on it for knowing the connection state. if trace != nil && trace.TLSHandshakeStart != nil { @@ -1928,13 +1933,17 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers } if s := pconn.tlsState; s != nil && s.NegotiatedProtocolIsMutual && s.NegotiatedProtocol != "" { - if next, ok := t.TLSNextProto[s.NegotiatedProtocol]; ok { - alt := next(cm.targetAddr, pconn.conn.(*tls.Conn)) - if e, ok := alt.(erringRoundTripper); ok { - // pconn.conn was closed by next (http2configureTransports.upgradeFn). - return nil, e.RoundTripErr() + // New HTTP/2 Handler at https://go-review.googlesource.com/c/go/+/616097/2/src/net/http/transport.go + + if tc, ok := pconn.conn.(*tls.Conn); ok { + if next, ok := t.TLSNextProto[s.NegotiatedProtocol]; ok { + alt := next(cm.targetAddr, tc) + if e, ok := alt.(erringRoundTripper); ok { + // pconn.conn was closed by next (http2configureTransports.upgradeFn). + return nil, e.RoundTripErr() + } + return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil } - return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil } }