You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
funcTestCancelAfterRequest(t*testing.T) {
ctx, cancel:=context.WithCancel(context.Background())
resp, err:=doRequest(ctx)
// Cancel before reading the body.// Request.Body should still be readable after the context is canceled.cancel()
b, err:=ioutil.ReadAll(resp.Body)
iferr!=nil||string(b) !=requestBody {
t.Fatalf("could not read body: %q %v", b, err)
}
}
Unfortunately, I think the test could be problematic for many useful cases for cancelling http requests.
It's fairly obvious from reading the implementation that the canceler has no effect called once .Do() returns, however it is not obvious from the documentation.
I'm taking a look at this now. I double checked that closing the request's Cancel channel after Do return does behave like you'd expect, so I'm just trying to work out the best way to plumb that into the ctxhttp package.
FWIW, there is a slight bug in the test above: since the headers are never being flushed the call to Do is never even returning. You can fix that by writing sufficient data to the body, or by calling Flush:
If a HTTP request is cancelled via a context once .Do() has returned, the cancellation request is ignored.
Consider this test in x/net/context/ctxhttp:
Unfortunately, I think the test could be problematic for many useful cases for cancelling http requests.
The immediate use case I have is to attach to the stdout of a docker container over docker's http endpoint, and disconnect when a client's interest in the output goes away. Otherwise resources are leaked, since the stdout might not otherwise go away. See fsouza/go-dockerclient#161. Secondly, cancelling a build once it is in progress, where the build output is being streamed to you: fsouza/go-dockerclient#182.
Here's an alternative "test" which simulates what I described above, exercising cancellation once Do() has returned. Currently, it hangs forever:
It's fairly obvious from reading the implementation that the canceler has no effect called once
.Do()
returns, however it is not obvious from the documentation.See also #13293, and golang-dev discussion.
The text was updated successfully, but these errors were encountered: