Skip to content

Commit e108c19

Browse files
neildmknyszek
authored andcommitted
[internal-branch.go1.17-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#49561 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/+/368375 Reviewed-by: Michael Knyszek <[email protected]>
1 parent 95aca89 commit e108c19

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
@@ -1122,6 +1122,9 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
11221122
return err
11231123
}
11241124
cc.addStreamLocked(cs) // assigns stream ID
1125+
if isConnectionCloseRequest(req) {
1126+
cc.doNotReuse = true
1127+
}
11251128
cc.mu.Unlock()
11261129

11271130
// 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)