diff options
author | Damien Neil <dneil@google.com> | 2020-07-28 12:49:52 -0700 |
---|---|---|
committer | Damien Neil <dneil@google.com> | 2020-08-04 19:27:13 +0000 |
commit | f235275097eb68b36d171908cea6a0be23351a94 (patch) | |
tree | 537aa71c84c473878557a8b22d95b79195c99d2e /src/net/http/transport_test.go | |
parent | f92337422ef2ca27464c198bb3426d2dc4661653 (diff) | |
download | go-f235275097eb68b36d171908cea6a0be23351a94.tar.gz go-f235275097eb68b36d171908cea6a0be23351a94.zip |
net/http: fix cancelation of requests with a readTrackingBody wrapper
Use the original *Request in the reqCanceler map, not the transient
wrapper created to handle body rewinding.
Change the key of reqCanceler to a struct{*Request}, to make it more
difficult to accidentally use the wrong request as the key.
Fixes #40453.
Change-Id: I4e61ee9ff2c794fb4c920a3a66c9a0458693d757
Reviewed-on: https://go-review.googlesource.com/c/go/+/245357
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/net/http/transport_test.go')
-rw-r--r-- | src/net/http/transport_test.go | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index 31a41f5351..0a47687d9a 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -2364,6 +2364,50 @@ func TestTransportCancelRequest(t *testing.T) { } } +func testTransportCancelRequestInDo(t *testing.T, body io.Reader) { + setParallel(t) + defer afterTest(t) + if testing.Short() { + t.Skip("skipping test in -short mode") + } + unblockc := make(chan bool) + ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + <-unblockc + })) + defer ts.Close() + defer close(unblockc) + + c := ts.Client() + tr := c.Transport.(*Transport) + + donec := make(chan bool) + req, _ := NewRequest("GET", ts.URL, body) + go func() { + defer close(donec) + c.Do(req) + }() + start := time.Now() + timeout := 10 * time.Second + for time.Since(start) < timeout { + time.Sleep(100 * time.Millisecond) + tr.CancelRequest(req) + select { + case <-donec: + return + default: + } + } + t.Errorf("Do of canceled request has not returned after %v", timeout) +} + +func TestTransportCancelRequestInDo(t *testing.T) { + testTransportCancelRequestInDo(t, nil) +} + +func TestTransportCancelRequestWithBodyInDo(t *testing.T) { + testTransportCancelRequestInDo(t, bytes.NewBuffer([]byte{0})) +} + func TestTransportCancelRequestInDial(t *testing.T) { defer afterTest(t) if testing.Short() { |