mirror of
https://github.com/golang/go
synced 2024-11-18 10:34:51 -07:00
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>
This commit is contained in:
parent
b649bdc7f3
commit
19e0799ba0
@ -434,8 +434,8 @@ func Get(url string) (resp *Response, err error) {
|
|||||||
// An error is returned if the Client's CheckRedirect function fails
|
// 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
|
// 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
|
// 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
|
// url.Error value's Timeout method will report true if the request
|
||||||
// out or was canceled.
|
// timed out.
|
||||||
//
|
//
|
||||||
// When err is nil, resp always contains a non-nil resp.Body.
|
// When err is nil, resp always contains a non-nil resp.Body.
|
||||||
// Caller should close resp.Body when done reading from it.
|
// Caller should close resp.Body when done reading from it.
|
||||||
|
@ -1936,3 +1936,58 @@ func TestClientPropagatesTimeoutToContext(t *testing.T) {
|
|||||||
}
|
}
|
||||||
c.Get("https://example.tld/")
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user