]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: fix and lock-in Client.Do docs on request cancelation
authorEmmanuel T Odeke <emmanuel@orijtech.com>
Sat, 12 Oct 2019 00:27:33 +0000 (20:27 -0400)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 14 Oct 2019 20:50:54 +0000 (20:50 +0000)
Fixes the docs to correctly match the implementation
and also adds a test locking-in the behavior to prevent
any accidental future regressions on the docs.

Fixes #33545

Change-Id: I6fdac6048cce8ac99beaa2db0dfc81d0dccc10f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/200798
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/http/client.go
src/net/http/client_test.go

index 9566b8940e67defb56bbb4a060141e53c25c54a5..6a8c59a6702f343ae4f391babb6d0a5432299202 100644 (file)
@@ -434,8 +434,8 @@ func Get(url string) (resp *Response, err error) {
 // An error is returned if the Client's CheckRedirect function fails
 // or if there was an HTTP protocol error. A non-2xx response doesn't
 // cause an error. Any returned error will be of type *url.Error. The
-// url.Error value's Timeout method will report true if request timed
-// out or was canceled.
+// url.Error value's Timeout method will report true if the request
+// timed out.
 //
 // When err is nil, resp always contains a non-nil resp.Body.
 // Caller should close resp.Body when done reading from it.
index 37c0390a739d5c1e50068796385a9dc4a89870d6..2b4f53f802ba4a047418b20ed1de5b685b0aadad 100644 (file)
@@ -1936,3 +1936,58 @@ func TestClientPropagatesTimeoutToContext(t *testing.T) {
        }
        c.Get("https://example.tld/")
 }
+
+func TestClientDoCanceledVsTimeout_h1(t *testing.T) {
+       testClientDoCanceledVsTimeout(t, h1Mode)
+}
+
+func TestClientDoCanceledVsTimeout_h2(t *testing.T) {
+       testClientDoCanceledVsTimeout(t, h2Mode)
+}
+
+// Issue 33545: lock-in the behavior promised by Client.Do's
+// docs about request cancelation vs timing out.
+func testClientDoCanceledVsTimeout(t *testing.T, h2 bool) {
+       defer afterTest(t)
+       cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+               w.Write([]byte("Hello, World!"))
+       }))
+       defer cst.close()
+
+       cases := []string{"timeout", "canceled"}
+
+       for _, name := range cases {
+               t.Run(name, func(t *testing.T) {
+                       var ctx context.Context
+                       var cancel func()
+                       if name == "timeout" {
+                               ctx, cancel = context.WithTimeout(context.Background(), -time.Nanosecond)
+                       } else {
+                               ctx, cancel = context.WithCancel(context.Background())
+                               cancel()
+                       }
+                       defer cancel()
+
+                       req, _ := NewRequestWithContext(ctx, "GET", cst.ts.URL, nil)
+                       _, err := cst.c.Do(req)
+                       if err == nil {
+                               t.Fatal("Unexpectedly got a nil error")
+                       }
+
+                       ue := err.(*url.Error)
+
+                       var wantIsTimeout bool
+                       var wantErr error = context.Canceled
+                       if name == "timeout" {
+                               wantErr = context.DeadlineExceeded
+                               wantIsTimeout = true
+                       }
+                       if g, w := ue.Timeout(), wantIsTimeout; g != w {
+                               t.Fatalf("url.Timeout() = %t, want %t", g, w)
+                       }
+                       if g, w := ue.Err, wantErr; g != w {
+                               t.Errorf("url.Error.Err = %v; want %v", g, w)
+                       }
+               })
+       }
+}