mirror of
https://github.com/golang/go
synced 2024-11-23 22:00:11 -07:00
net/http: update bundled http2
Updates x/net/http2 to git rev 8a52c78 for golang.org/cl/23258 (http2: fix Transport.CloseIdleConnections when http1+http2 are wired together) Fixes #14607 Change-Id: I038badc69e230715b8ce4e398eb5e6ede73af918 Reviewed-on: https://go-review.googlesource.com/23280 Reviewed-by: Andrew Gerrand <adg@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
1ded9fdcff
commit
b3bf2e7803
@ -1196,6 +1196,35 @@ func TestH12_AutoGzipWithDumpResponse(t *testing.T) {
|
|||||||
}.run(t)
|
}.run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 14607
|
||||||
|
func TestCloseIdleConnections_h1(t *testing.T) { testCloseIdleConnections(t, h1Mode) }
|
||||||
|
func TestCloseIdleConnections_h2(t *testing.T) { testCloseIdleConnections(t, h2Mode) }
|
||||||
|
func testCloseIdleConnections(t *testing.T, h2 bool) {
|
||||||
|
defer afterTest(t)
|
||||||
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
w.Header().Set("X-Addr", r.RemoteAddr)
|
||||||
|
}))
|
||||||
|
defer cst.close()
|
||||||
|
get := func() string {
|
||||||
|
res, err := cst.c.Get(cst.ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
res.Body.Close()
|
||||||
|
v := res.Header.Get("X-Addr")
|
||||||
|
if v == "" {
|
||||||
|
t.Fatal("didn't get X-Addr")
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
a1 := get()
|
||||||
|
cst.tr.CloseIdleConnections()
|
||||||
|
a2 := get()
|
||||||
|
if a1 == a2 {
|
||||||
|
t.Errorf("didn't close connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type noteCloseConn struct {
|
type noteCloseConn struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
closeFunc func()
|
closeFunc func()
|
||||||
|
@ -24,7 +24,6 @@ var (
|
|||||||
ExportErrRequestCanceled = errRequestCanceled
|
ExportErrRequestCanceled = errRequestCanceled
|
||||||
ExportErrRequestCanceledConn = errRequestCanceledConn
|
ExportErrRequestCanceledConn = errRequestCanceledConn
|
||||||
ExportServeFile = serveFile
|
ExportServeFile = serveFile
|
||||||
ExportHttp2ConfigureTransport = http2ConfigureTransport
|
|
||||||
ExportHttp2ConfigureServer = http2ConfigureServer
|
ExportHttp2ConfigureServer = http2ConfigureServer
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -152,3 +151,12 @@ func hookSetter(dst *func()) func(func()) {
|
|||||||
*dst = fn
|
*dst = fn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExportHttp2ConfigureTransport(t *Transport) error {
|
||||||
|
t2, err := http2configureTransport(t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.h2transport = t2
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -50,6 +50,18 @@ type http2ClientConnPool interface {
|
|||||||
MarkDead(*http2ClientConn)
|
MarkDead(*http2ClientConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clientConnPoolIdleCloser is the interface implemented by ClientConnPool
|
||||||
|
// implementations which can close their idle connections.
|
||||||
|
type http2clientConnPoolIdleCloser interface {
|
||||||
|
http2ClientConnPool
|
||||||
|
closeIdleConnections()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ http2clientConnPoolIdleCloser = (*http2clientConnPool)(nil)
|
||||||
|
_ http2clientConnPoolIdleCloser = http2noDialClientConnPool{}
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: use singleflight for dialing and addConnCalls?
|
// TODO: use singleflight for dialing and addConnCalls?
|
||||||
type http2clientConnPool struct {
|
type http2clientConnPool struct {
|
||||||
t *http2Transport
|
t *http2Transport
|
||||||
@ -250,6 +262,15 @@ func http2filterOutClientConn(in []*http2ClientConn, exclude *http2ClientConn) [
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// noDialClientConnPool is an implementation of http2.ClientConnPool
|
||||||
|
// which never dials. We let the HTTP/1.1 client dial and use its TLS
|
||||||
|
// connection instead.
|
||||||
|
type http2noDialClientConnPool struct{ *http2clientConnPool }
|
||||||
|
|
||||||
|
func (p http2noDialClientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
|
||||||
|
return p.getClientConn(req, addr, http2noDialOnMiss)
|
||||||
|
}
|
||||||
|
|
||||||
func http2configureTransport(t1 *Transport) (*http2Transport, error) {
|
func http2configureTransport(t1 *Transport) (*http2Transport, error) {
|
||||||
connPool := new(http2clientConnPool)
|
connPool := new(http2clientConnPool)
|
||||||
t2 := &http2Transport{
|
t2 := &http2Transport{
|
||||||
@ -302,15 +323,6 @@ func http2registerHTTPSProtocol(t *Transport, rt RoundTripper) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// noDialClientConnPool is an implementation of http2.ClientConnPool
|
|
||||||
// which never dials. We let the HTTP/1.1 client dial and use its TLS
|
|
||||||
// connection instead.
|
|
||||||
type http2noDialClientConnPool struct{ *http2clientConnPool }
|
|
||||||
|
|
||||||
func (p http2noDialClientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
|
|
||||||
return p.getClientConn(req, addr, http2noDialOnMiss)
|
|
||||||
}
|
|
||||||
|
|
||||||
// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
|
// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
|
||||||
// if there's already has a cached connection to the host.
|
// if there's already has a cached connection to the host.
|
||||||
type http2noDialH2RoundTripper struct{ t *http2Transport }
|
type http2noDialH2RoundTripper struct{ t *http2Transport }
|
||||||
@ -5054,7 +5066,7 @@ func (t *http2Transport) RoundTripOpt(req *Request, opt http2RoundTripOpt) (*Res
|
|||||||
// connected from previous requests but are now sitting idle.
|
// connected from previous requests but are now sitting idle.
|
||||||
// It does not interrupt any connections currently in use.
|
// It does not interrupt any connections currently in use.
|
||||||
func (t *http2Transport) CloseIdleConnections() {
|
func (t *http2Transport) CloseIdleConnections() {
|
||||||
if cp, ok := t.connPool().(*http2clientConnPool); ok {
|
if cp, ok := t.connPool().(http2clientConnPoolIdleCloser); ok {
|
||||||
cp.closeIdleConnections()
|
cp.closeIdleConnections()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user