]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: use cancelKey to cancel request
authorAlexander Yastrebov <yastrebov.alex@gmail.com>
Wed, 2 Aug 2023 22:15:59 +0000 (22:15 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 21 Aug 2023 18:00:29 +0000 (18:00 +0000)
Follows up on CL 245357 and adds missing returns in waitCondition (CL 477196)

Fixes #51354

Change-Id: I7950ff889ad72c4927a969c35fedc0186e863bd6
GitHub-Last-Rev: 52ce05bc83ef88c7104df9254bc1add0dda83ae0
GitHub-Pull-Request: golang/go#61724
Reviewed-on: https://go-review.googlesource.com/c/go/+/515435
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Damien Neil <dneil@google.com>

src/net/http/transport.go
src/net/http/transport_test.go

index c07352b018e1ef00fab3025e9dd488bf7e1542f5..d30eb79508a0cba8927276b96eb3f2afb69db870 100644 (file)
@@ -2248,7 +2248,7 @@ func (pc *persistConn) readLoop() {
                        }
                case <-rc.req.Cancel:
                        alive = false
-                       pc.t.CancelRequest(rc.req)
+                       pc.t.cancelRequest(rc.cancelKey, errRequestCanceled)
                case <-rc.req.Context().Done():
                        alive = false
                        pc.t.cancelRequest(rc.cancelKey, rc.req.Context().Err())
index 028fecc9611ea0010b48d5e1179ee02f2d04ad81..bcc26aa58e03fa491cb0c15b9c8c09ddcac56848 100644 (file)
@@ -2440,6 +2440,7 @@ func testTransportCancelRequest(t *testing.T, mode testMode) {
                        if d > 0 {
                                t.Logf("pending requests = %d after %v (want 0)", n, d)
                        }
+                       return false
                }
                return true
        })
@@ -2599,6 +2600,65 @@ func testCancelRequestWithChannel(t *testing.T, mode testMode) {
                        if d > 0 {
                                t.Logf("pending requests = %d after %v (want 0)", n, d)
                        }
+                       return false
+               }
+               return true
+       })
+}
+
+// Issue 51354
+func TestCancelRequestWithBodyWithChannel(t *testing.T) {
+       run(t, testCancelRequestWithBodyWithChannel, []testMode{http1Mode})
+}
+func testCancelRequestWithBodyWithChannel(t *testing.T, mode testMode) {
+       if testing.Short() {
+               t.Skip("skipping test in -short mode")
+       }
+
+       const msg = "Hello"
+       unblockc := make(chan struct{})
+       ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+               io.WriteString(w, msg)
+               w.(Flusher).Flush() // send headers and some body
+               <-unblockc
+       })).ts
+       defer close(unblockc)
+
+       c := ts.Client()
+       tr := c.Transport.(*Transport)
+
+       req, _ := NewRequest("POST", ts.URL, strings.NewReader("withbody"))
+       cancel := make(chan struct{})
+       req.Cancel = cancel
+
+       res, err := c.Do(req)
+       if err != nil {
+               t.Fatal(err)
+       }
+       body := make([]byte, len(msg))
+       n, _ := io.ReadFull(res.Body, body)
+       if n != len(body) || !bytes.Equal(body, []byte(msg)) {
+               t.Errorf("Body = %q; want %q", body[:n], msg)
+       }
+       close(cancel)
+
+       tail, err := io.ReadAll(res.Body)
+       res.Body.Close()
+       if err != ExportErrRequestCanceled {
+               t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
+       } else if len(tail) > 0 {
+               t.Errorf("Spurious bytes from Body.Read: %q", tail)
+       }
+
+       // Verify no outstanding requests after readLoop/writeLoop
+       // goroutines shut down.
+       waitCondition(t, 10*time.Millisecond, func(d time.Duration) bool {
+               n := tr.NumPendingRequestsForTesting()
+               if n > 0 {
+                       if d > 0 {
+                               t.Logf("pending requests = %d after %v (want 0)", n, d)
+                       }
+                       return false
                }
                return true
        })