-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: requests sometimes sent even when context is already canceled #25852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I wasn't able to reproduce this on go1.10.3 darwin/amd64. @hiranya911 can you please help me with my understanding here: My guess is that the firebase library linked to this issue has the requirement to support go1.6. firebase/firebase-admin-go#144 links to this:
The code pasted by the OP above has: These are different libraries: net/http, golang.org/x/net/context/ctxhttp Your comment:
I thought context was added to net/http in 1.7 so how could that test be running in go1.6? |
You're right about us not being able to use ctx+http APIs at the moment, due to us having to support golang 1.6. |
The issue occurs very occasionally. I haven't observed it in the local development environments. But it happens every now and then on our Travis builds. Here's some env details from the golang 1.9 build environment where this happened today:
|
Very strange. For Go 1.9, ctxhttp is a very light shim:
so, this might be a bug in net/http. Renaming bug given how unlikely this is a bug in ctxhttp. |
I can reproduce it in Go 1.10.3 on linux/amd64 using this modified code without the package main
import (
"context"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
if client == nil {
client = http.DefaultClient
}
resp, err := client.Do(req.WithContext(ctx))
// If we got an error, and the context has been canceled,
// the context's error is probably more useful.
if err != nil {
select {
case <-ctx.Done():
err = ctx.Err()
default:
}
}
return resp, err
}
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("{}"))
})
server := httptest.NewServer(handler)
defer server.Close()
hc := http.DefaultClient
doSend := func(ctx context.Context, req *http.Request) error {
resp, err := Do(ctx, hc, req)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return nil
}
for i := 0; i < 10; i++ {
go func() {
for {
ctx, cancel := context.WithCancel(context.Background())
req, err := http.NewRequest("GET", server.URL, nil)
if err != nil {
log.Fatal(err)
}
if err := doSend(ctx, req); err != nil { // Request 1
log.Fatal(err)
}
cancel()
req, err = http.NewRequest("GET", server.URL, nil)
if err != nil {
log.Fatal(err)
}
if err := doSend(ctx, req); err == nil { // Request 2
log.Fatal("no err raised")
}
}
}()
}
select {}
} It takes only 1-10 seconds before there's |
Some my thoughts.
|
Change https://golang.org/cl/118560 mentions this issue: |
Thanks gophers. Do you usually backport this sort of thing to older versions of Go, or is it just going to be included in the next milestone release? |
Fixes golang#25852 Change-Id: I35c630367c8f1934dcffc0b0e08891d55a903518 Reviewed-on: https://go-review.googlesource.com/118560 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Andrew Bonventre <[email protected]>
We are observing a intermittent error with the
ctxhttp
package when calling it with already cancelled contexts.What version of Go are you using (
go version
)?Error has been observed on multiple Go versions (1.6, 1.7, 1.9)
Here's some more details from the golang 1.9 build environment (Travis CI based) where this happened today:
What did you do?
I have the following test case:
What did you expect to see?
I expect
Request 2
to fail with an error since the context is explicitly cancelled.What did you see instead?
Every now and then
Request 2
completes successfully (i.e. gets a response from the server), and doesn't return an error.The text was updated successfully, but these errors were encountered: