components/golang-17/patches/0012-release-branch.go1.7-net-http-fix-unwanted-HTTP-2-co.patch
author Shawn Walker-Salas <shawn.walker@oracle.com>
Tue, 20 Dec 2016 11:59:29 -0800
changeset 7518 c388d4e1d3ad
permissions -rw-r--r--
PSARC/2016/250 Google Go version 1.7 23170486 update to Google Go version 1.7 and add sparc64 support
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7518
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     1
From dc3612e0d1a569e2ad1a3deea9ef6eab72616dc4 Mon Sep 17 00:00:00 2001
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     2
From: Brad Fitzpatrick <[email protected]>
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     3
Date: Fri, 19 Aug 2016 23:13:29 +0000
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     4
Subject: [PATCH 12/38] [release-branch.go1.7] net/http: fix unwanted HTTP/2
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     5
 conn Transport crash after IdleConnTimeout
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     6
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     7
Go 1.7 crashed after Transport.IdleConnTimeout if an HTTP/2 connection
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     8
was established but but its caller no longer wanted it. (Assuming the
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
     9
connection cache was enabled, which it is by default)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    10
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    11
Fixes #16208
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    12
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    13
Change-Id: I9628757f7669e344f416927c77f00ed3864839e3
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    14
Reviewed-on: https://go-review.googlesource.com/27450
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    15
Reviewed-by: Andrew Gerrand <[email protected]>
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    16
Run-TryBot: Brad Fitzpatrick <[email protected]>
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    17
TryBot-Result: Gobot Gobot <[email protected]>
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    18
Reviewed-on: https://go-review.googlesource.com/28637
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    19
Reviewed-by: Brad Fitzpatrick <[email protected]>
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    20
---
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    21
 src/net/http/transport.go      |  4 +++
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    22
 src/net/http/transport_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    23
 2 files changed, 59 insertions(+)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    24
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    25
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    26
index 6672119..1f07634 100644
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    27
--- a/src/net/http/transport.go
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    28
+++ b/src/net/http/transport.go
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    29
@@ -590,6 +590,7 @@ var (
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    30
 	errReadLoopExiting    = errors.New("http: persistConn.readLoop exiting")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    31
 	errServerClosedIdle   = errors.New("http: server closed idle connection")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    32
 	errIdleConnTimeout    = errors.New("http: idle connection timeout")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    33
+	errNotCachingH2Conn   = errors.New("http: not caching alternate protocol's connections")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    34
 )
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    35
 
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    36
 // transportReadFromServerError is used by Transport.readLoop when the
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    37
@@ -633,6 +634,9 @@ func (t *Transport) tryPutIdleConn(pconn *persistConn) error {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    38
 	if pconn.isBroken() {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    39
 		return errConnBroken
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    40
 	}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    41
+	if pconn.alt != nil {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    42
+		return errNotCachingH2Conn
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    43
+	}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    44
 	pconn.markReused()
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    45
 	key := pconn.cacheKey
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    46
 
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    47
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    48
index 749d453..298682d 100644
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    49
--- a/src/net/http/transport_test.go
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    50
+++ b/src/net/http/transport_test.go
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    51
@@ -3511,6 +3511,61 @@ func TestTransportIdleConnTimeout(t *testing.T) {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    52
 	}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    53
 }
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    54
 
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    55
+// Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    56
+// HTTP/2 connection was established but but its caller no longer
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    57
+// wanted it. (Assuming the connection cache was enabled, which it is
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    58
+// by default)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    59
+//
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    60
+// This test reproduced the crash by setting the IdleConnTimeout low
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    61
+// (to make the test reasonable) and then making a request which is
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    62
+// canceled by the DialTLS hook, which then also waits to return the
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    63
+// real connection until after the RoundTrip saw the error.  Then we
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    64
+// know the successful tls.Dial from DialTLS will need to go into the
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    65
+// idle pool. Then we give it a of time to explode.
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    66
+func TestIdleConnH2Crash(t *testing.T) {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    67
+	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    68
+		// nothing
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    69
+	}))
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    70
+	defer cst.close()
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    71
+
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    72
+	ctx, cancel := context.WithCancel(context.Background())
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    73
+	defer cancel()
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    74
+
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    75
+	gotErr := make(chan bool, 1)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    76
+
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    77
+	cst.tr.IdleConnTimeout = 5 * time.Millisecond
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    78
+	cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    79
+		cancel()
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    80
+		<-gotErr
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    81
+		c, err := tls.Dial(network, addr, &tls.Config{
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    82
+			InsecureSkipVerify: true,
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    83
+			NextProtos:         []string{"h2"},
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    84
+		})
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    85
+		if err != nil {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    86
+			t.Error(err)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    87
+			return nil, err
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    88
+		}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    89
+		if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    90
+			t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    91
+			c.Close()
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    92
+			return nil, errors.New("bogus")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    93
+		}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    94
+		return c, nil
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    95
+	}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    96
+
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    97
+	req, _ := NewRequest("GET", cst.ts.URL, nil)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    98
+	req = req.WithContext(ctx)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
    99
+	res, err := cst.c.Do(req)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   100
+	if err == nil {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   101
+		res.Body.Close()
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   102
+		t.Fatal("unexpected success")
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   103
+	}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   104
+	gotErr <- true
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   105
+
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   106
+	// Wait for the explosion.
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   107
+	time.Sleep(cst.tr.IdleConnTimeout * 10)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   108
+}
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   109
+
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   110
 type funcConn struct {
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   111
 	net.Conn
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   112
 	read  func([]byte) (int, error)
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   113
-- 
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   114
2.7.4
c388d4e1d3ad PSARC/2016/250 Google Go version 1.7
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff changeset
   115