]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: update bundled http2
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 20 May 2016 03:01:27 +0000 (03:01 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 20 May 2016 05:53:06 +0000 (05:53 +0000)
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>

src/net/http/clientserver_test.go
src/net/http/export_test.go
src/net/http/h2_bundle.go

index b1b7d137d93c52618de9ac9ef311d47fe1f512b8..e12ea0c8c45b409f2559cd066c3011a35c98b1da 100644 (file)
@@ -1196,6 +1196,35 @@ func TestH12_AutoGzipWithDumpResponse(t *testing.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 {
        net.Conn
        closeFunc func()
index 3ebc51b19e62e9e2cf2e6d1abc98171dc9c794ac..9c5ba0809ad0ab200193b1dafd83e6f8eb695432 100644 (file)
@@ -15,17 +15,16 @@ import (
 )
 
 var (
-       DefaultUserAgent              = defaultUserAgent
-       NewLoggingConn                = newLoggingConn
-       ExportAppendTime              = appendTime
-       ExportRefererForURL           = refererForURL
-       ExportServerNewConn           = (*Server).newConn
-       ExportCloseWriteAndWait       = (*conn).closeWriteAndWait
-       ExportErrRequestCanceled      = errRequestCanceled
-       ExportErrRequestCanceledConn  = errRequestCanceledConn
-       ExportServeFile               = serveFile
-       ExportHttp2ConfigureTransport = http2ConfigureTransport
-       ExportHttp2ConfigureServer    = http2ConfigureServer
+       DefaultUserAgent             = defaultUserAgent
+       NewLoggingConn               = newLoggingConn
+       ExportAppendTime             = appendTime
+       ExportRefererForURL          = refererForURL
+       ExportServerNewConn          = (*Server).newConn
+       ExportCloseWriteAndWait      = (*conn).closeWriteAndWait
+       ExportErrRequestCanceled     = errRequestCanceled
+       ExportErrRequestCanceledConn = errRequestCanceledConn
+       ExportServeFile              = serveFile
+       ExportHttp2ConfigureServer   = http2ConfigureServer
 )
 
 func init() {
@@ -152,3 +151,12 @@ func hookSetter(dst *func()) func(func()) {
                *dst = fn
        }
 }
+
+func ExportHttp2ConfigureTransport(t *Transport) error {
+       t2, err := http2configureTransport(t)
+       if err != nil {
+               return err
+       }
+       t.h2transport = t2
+       return nil
+}
index 633bdeadb705f0d4ce75153ed35de7e7ec75bf0c..55111523e587f5f57b6a6777c0fdd54273fc61b5 100644 (file)
@@ -50,6 +50,18 @@ type http2ClientConnPool interface {
        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?
 type http2clientConnPool struct {
        t *http2Transport
@@ -250,6 +262,15 @@ func http2filterOutClientConn(in []*http2ClientConn, exclude *http2ClientConn) [
        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) {
        connPool := new(http2clientConnPool)
        t2 := &http2Transport{
@@ -302,15 +323,6 @@ func http2registerHTTPSProtocol(t *Transport, rt RoundTripper) (err error) {
        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
 // if there's already has a cached connection to the host.
 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.
 // It does not interrupt any connections currently in use.
 func (t *http2Transport) CloseIdleConnections() {
-       if cp, ok := t.connPool().(*http2clientConnPool); ok {
+       if cp, ok := t.connPool().(http2clientConnPoolIdleCloser); ok {
                cp.closeIdleConnections()
        }
 }