mirror of
https://github.com/golang/go
synced 2024-11-20 09:24:50 -07:00
net/http: allow reuse of http.Request objects
Calling response.Body.Close() early would generarate a race before this. Since closing would return early before the main code path had a chance to reset the request canceler. Having a non-nil request canceler at the start of the next request would cause a "request canceled" error. Here we simply wait for the eofc channel to be closed before returning from earlyCloseFn, ensuring that the caller won't be re-using that Request object before we have a chance to reset the request canceler to nil. Fixes #21838 Change-Id: I641815526c6ac63d1816c9b6ad49d73715f7a5cb Reviewed-on: https://go-review.googlesource.com/62891 Run-TryBot: Tom Bergan <tombergan@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Tom Bergan <tombergan@google.com>
This commit is contained in:
parent
cf872fae78
commit
78c4dc3709
@ -1616,6 +1616,7 @@ func (pc *persistConn) readLoop() {
|
||||
body: resp.Body,
|
||||
earlyCloseFn: func() error {
|
||||
waitForBodyRead <- false
|
||||
<-eofc // will be closed by deferred call at the end of the function
|
||||
return nil
|
||||
|
||||
},
|
||||
|
@ -124,6 +124,34 @@ func (tcs *testConnSet) check(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReuseRequest(t *testing.T) {
|
||||
defer afterTest(t)
|
||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||
w.Write([]byte("{}"))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
c := ts.Client()
|
||||
req, _ := NewRequest("GET", ts.URL, nil)
|
||||
res, err := c.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
res, err = c.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Two subsequent requests and verify their response is the same.
|
||||
// The response from the server is our own IP:port
|
||||
func TestTransportKeepAlives(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user