diff options
| author | Emmanuel T Odeke <emmanuel@orijtech.com> | 2019-10-11 20:27:33 -0400 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2019-10-14 20:50:54 +0000 |
| commit | 19e0799ba049bf26e770d150d4c296f247e1de5c (patch) | |
| tree | bdb5b31b4e69497c42d029c0c3040fd8913f994d | |
| parent | b649bdc7f3c99c5288c91a1ce148efadd86e19a4 (diff) | |
| download | go-git-19e0799ba049bf26e770d150d4c296f247e1de5c.tar.gz | |
net/http: fix and lock-in Client.Do docs on request cancelation
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>
| -rw-r--r-- | src/net/http/client.go | 4 | ||||
| -rw-r--r-- | src/net/http/client_test.go | 55 |
2 files changed, 57 insertions, 2 deletions
diff --git a/src/net/http/client.go b/src/net/http/client.go index 9566b8940e..6a8c59a670 100644 --- a/src/net/http/client.go +++ b/src/net/http/client.go @@ -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. diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go index 37c0390a73..2b4f53f802 100644 --- a/src/net/http/client_test.go +++ b/src/net/http/client_test.go @@ -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) + } + }) + } +} |
