~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to debian/patches/15-net-http-connection-close.patch

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Description: net/http: non-keepalive connections close successfully
2
 
 Connections did not close if Request.Close or Response.Close was true. This
3
 
 meant that if the user wanted the connection to close, or if the server
4
 
 requested it via "Connection: close", the connection would not be closed.
5
 
Author: James Gray <james@james4k.com>
6
 
Bug-Debian: http://bugs.debian.org/683421
7
 
Origin: upstream, http://code.google.com/p/go/source/detail?r=820ffde8c396
8
 
Forwarded: not-needed
9
 
Last-Update: 2012-08-01
10
 
 
11
 
---
12
 
 
13
 
--- golang-1.0.2.orig/src/pkg/net/http/transport.go
14
 
+++ golang-1.0.2/src/pkg/net/http/transport.go
15
 
@@ -603,6 +603,10 @@ func (pc *persistConn) readLoop() {
16
 
                // before we race and peek on the underlying bufio reader.
17
 
                if waitForBodyRead != nil {
18
 
                        <-waitForBodyRead
19
 
+               } else if !alive {
20
 
+                       // If waitForBodyRead is nil, and we're not alive, we
21
 
+                       // must close the connection before we leave the loop.
22
 
+                       pc.close()
23
 
                }
24
 
        }
25
 
 }
26
 
--- golang-1.0.2.orig/src/pkg/net/http/transport_test.go
27
 
+++ golang-1.0.2/src/pkg/net/http/transport_test.go
28
 
@@ -13,6 +13,7 @@ import (
29
 
        "fmt"
30
 
        "io"
31
 
        "io/ioutil"
32
 
+       "net"
33
 
        . "net/http"
34
 
        "net/http/httptest"
35
 
        "net/url"
36
 
@@ -20,6 +21,7 @@ import (
37
 
        "runtime"
38
 
        "strconv"
39
 
        "strings"
40
 
+       "sync"
41
 
        "testing"
42
 
        "time"
43
 
 )
44
 
@@ -35,6 +37,64 @@ var hostPortHandler = HandlerFunc(func(w
45
 
        w.Write([]byte(r.RemoteAddr))
46
 
 })
47
 
 
48
 
+type testCloseConn struct {
49
 
+       net.Conn
50
 
+       set *testConnSet
51
 
+}
52
 
+
53
 
+func (conn *testCloseConn) Close() error {
54
 
+       conn.set.remove(conn)
55
 
+       return conn.Conn.Close()
56
 
+}
57
 
+
58
 
+type testConnSet struct {
59
 
+       set   map[net.Conn]bool
60
 
+       mutex sync.Mutex
61
 
+}
62
 
+
63
 
+func (tcs *testConnSet) insert(c net.Conn) {
64
 
+       tcs.mutex.Lock()
65
 
+       defer tcs.mutex.Unlock()
66
 
+       tcs.set[c] = true
67
 
+}
68
 
+
69
 
+func (tcs *testConnSet) remove(c net.Conn) {
70
 
+       tcs.mutex.Lock()
71
 
+       defer tcs.mutex.Unlock()
72
 
+       // just change to false, so we have a full set of opened connections
73
 
+       tcs.set[c] = false
74
 
+}
75
 
+
76
 
+// some tests use this to manage raw tcp connections for later inspection
77
 
+func makeTestDial() (*testConnSet, func(n, addr string) (net.Conn, error)) {
78
 
+       connSet := &testConnSet{
79
 
+               set: make(map[net.Conn]bool),
80
 
+       }
81
 
+       dial := func(n, addr string) (net.Conn, error) {
82
 
+               c, err := net.Dial(n, addr)
83
 
+               if err != nil {
84
 
+                       return nil, err
85
 
+               }
86
 
+               tc := &testCloseConn{c, connSet}
87
 
+               connSet.insert(tc)
88
 
+               return tc, nil
89
 
+       }
90
 
+       return connSet, dial
91
 
+}
92
 
+
93
 
+func (tcs *testConnSet) countClosed() (closed, total int) {
94
 
+       tcs.mutex.Lock()
95
 
+       defer tcs.mutex.Unlock()
96
 
+
97
 
+       total = len(tcs.set)
98
 
+       for _, open := range tcs.set {
99
 
+               if !open {
100
 
+                       closed += 1
101
 
+               }
102
 
+       }
103
 
+       return
104
 
+}
105
 
+
106
 
 // Two subsequent requests and verify their response is the same.
107
 
 // The response from the server is our own IP:port
108
 
 func TestTransportKeepAlives(t *testing.T) {
109
 
@@ -72,8 +132,12 @@ func TestTransportConnectionCloseOnRespo
110
 
        ts := httptest.NewServer(hostPortHandler)
111
 
        defer ts.Close()
112
 
 
113
 
+       connSet, testDial := makeTestDial()
114
 
+
115
 
        for _, connectionClose := range []bool{false, true} {
116
 
-               tr := &Transport{}
117
 
+               tr := &Transport{
118
 
+                       Dial: testDial,
119
 
+               }
120
 
                c := &Client{Transport: tr}
121
 
 
122
 
                fetch := func(n int) string {
123
 
@@ -107,6 +171,13 @@ func TestTransportConnectionCloseOnRespo
124
 
                        t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
125
 
                                connectionClose, bodiesDiffer, body1, body2)
126
 
                }
127
 
+
128
 
+               tr.CloseIdleConnections()
129
 
+       }
130
 
+
131
 
+       closed, total := connSet.countClosed()
132
 
+       if closed < total {
133
 
+               t.Errorf("%d out of %d tcp connections were not closed", total-closed, total)
134
 
        }
135
 
 }
136
 
 
137
 
@@ -114,8 +185,12 @@ func TestTransportConnectionCloseOnReque
138
 
        ts := httptest.NewServer(hostPortHandler)
139
 
        defer ts.Close()
140
 
 
141
 
+       connSet, testDial := makeTestDial()
142
 
+
143
 
        for _, connectionClose := range []bool{false, true} {
144
 
-               tr := &Transport{}
145
 
+               tr := &Transport{
146
 
+                       Dial: testDial,
147
 
+               }
148
 
                c := &Client{Transport: tr}
149
 
 
150
 
                fetch := func(n int) string {
151
 
@@ -149,6 +224,13 @@ func TestTransportConnectionCloseOnReque
152
 
                        t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
153
 
                                connectionClose, bodiesDiffer, body1, body2)
154
 
                }
155
 
+
156
 
+               tr.CloseIdleConnections()
157
 
+       }
158
 
+
159
 
+       closed, total := connSet.countClosed()
160
 
+       if closed < total {
161
 
+               t.Errorf("%d out of %d tcp connections were not closed", total-closed, total)
162
 
        }
163
 
 }
164