Skip to content

Commit 26ec667

Browse files
neildmknyszek
authored andcommitted
[internal-branch.go1.16-vendor] http2: close conns after use when req.Close is set
Avoid reusing connections after receiving a response to a request for which cc.Close is set or a "Connection: close" header is present. Adjust the tests for connection reuse to test both the case where new conns are created by the http2 package and when they are created by the net/http package. For golang/go#49375 Fixes golang/go#49560 Change-Id: I58594972c832a20b66a3910c17acb51a98a9f7a5 Reviewed-on: https://go-review.googlesource.com/c/net/+/361498 Trust: Damien Neil <[email protected]> Run-TryBot: Damien Neil <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> (cherry picked from commit 69e39ba) Reviewed-on: https://go-review.googlesource.com/c/net/+/368374 Reviewed-by: Michael Knyszek <[email protected]>
1 parent d8c3cde commit 26ec667

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

http2/transport.go

+3
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,9 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
11261126
return err
11271127
}
11281128
cc.addStreamLocked(cs) // assigns stream ID
1129+
if isConnectionCloseRequest(req) {
1130+
cc.doNotReuse = true
1131+
}
11291132
cc.mu.Unlock()
11301133

11311134
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?

http2/transport_test.go

+42-17
Original file line numberDiff line numberDiff line change
@@ -190,22 +190,32 @@ func TestTransport(t *testing.T) {
190190
}
191191
}
192192

193-
func onSameConn(t *testing.T, modReq func(*http.Request)) bool {
193+
func testTransportReusesConns(t *testing.T, useClient, wantSame bool, modReq func(*http.Request)) {
194194
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
195195
io.WriteString(w, r.RemoteAddr)
196196
}, optOnlyServer, func(c net.Conn, st http.ConnState) {
197197
t.Logf("conn %v is now state %v", c.RemoteAddr(), st)
198198
})
199199
defer st.Close()
200200
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
201+
if useClient {
202+
tr.ConnPool = noDialClientConnPool{new(clientConnPool)}
203+
}
201204
defer tr.CloseIdleConnections()
202205
get := func() string {
203206
req, err := http.NewRequest("GET", st.ts.URL, nil)
204207
if err != nil {
205208
t.Fatal(err)
206209
}
207210
modReq(req)
208-
res, err := tr.RoundTrip(req)
211+
var res *http.Response
212+
if useClient {
213+
c := st.ts.Client()
214+
ConfigureTransports(c.Transport.(*http.Transport))
215+
res, err = c.Do(req)
216+
} else {
217+
res, err = tr.RoundTrip(req)
218+
}
209219
if err != nil {
210220
t.Fatal(err)
211221
}
@@ -222,24 +232,39 @@ func onSameConn(t *testing.T, modReq func(*http.Request)) bool {
222232
}
223233
first := get()
224234
second := get()
225-
return first == second
226-
}
227-
228-
func TestTransportReusesConns(t *testing.T) {
229-
if !onSameConn(t, func(*http.Request) {}) {
230-
t.Errorf("first and second responses were on different connections")
235+
if got := first == second; got != wantSame {
236+
t.Errorf("first and second responses on same connection: %v; want %v", got, wantSame)
231237
}
232238
}
233239

234-
func TestTransportReusesConn_RequestClose(t *testing.T) {
235-
if onSameConn(t, func(r *http.Request) { r.Close = true }) {
236-
t.Errorf("first and second responses were not on different connections")
237-
}
238-
}
239-
240-
func TestTransportReusesConn_ConnClose(t *testing.T) {
241-
if onSameConn(t, func(r *http.Request) { r.Header.Set("Connection", "close") }) {
242-
t.Errorf("first and second responses were not on different connections")
240+
func TestTransportReusesConns(t *testing.T) {
241+
for _, test := range []struct {
242+
name string
243+
modReq func(*http.Request)
244+
wantSame bool
245+
}{{
246+
name: "ReuseConn",
247+
modReq: func(*http.Request) {},
248+
wantSame: true,
249+
}, {
250+
name: "RequestClose",
251+
modReq: func(r *http.Request) { r.Close = true },
252+
wantSame: false,
253+
}, {
254+
name: "ConnClose",
255+
modReq: func(r *http.Request) { r.Header.Set("Connection", "close") },
256+
wantSame: false,
257+
}} {
258+
t.Run(test.name, func(t *testing.T) {
259+
t.Run("Transport", func(t *testing.T) {
260+
const useClient = false
261+
testTransportReusesConns(t, useClient, test.wantSame, test.modReq)
262+
})
263+
t.Run("Client", func(t *testing.T) {
264+
const useClient = true
265+
testTransportReusesConns(t, useClient, test.wantSame, test.modReq)
266+
})
267+
})
243268
}
244269
}
245270

0 commit comments

Comments
 (0)