-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
net/http: data race in tip after CL 461675 #60041
Comments
@neild do you have an opinion on whether this is a release blocker? Getting very close to the freeze and RC now. |
Change https://go.dev/cl/496016 mentions this issue: |
Don't know if it's a release blocker, but I believe I have a fix. |
Change https://go.dev/cl/496335 mentions this issue: |
When returning an error from RoundTrip, wait for the close of the request body to complete before returning. This avoids a race between the HTTP/2 transport closing the request body and the net/http retry loop examining the readTrackingBody to see if it has been closed. For golang/go#60041 Change-Id: I8be69ff5056806406716e01e02d1f631deeca088 Reviewed-on: https://go-review.googlesource.com/c/net/+/496335 Run-TryBot: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Bryan Mills <[email protected]>
We decided in the release meeting that this is a release blocker (and an RC1 release blocker). What's left to do here? Does this get resolved by vendoring x/net/http, or does https://go.dev/cl/496016 also need to land? Thanks. |
@dneil can you please confirm the status here? This is currently marked as an RC1 release blocker https://go-review.googlesource.com/c/go/+/496016 hasn't made progress in 3 weeks. |
https://go.dev/cl/496335 supersedes https://go.dev/cl/496016, should fix this issue, and has made it from |
I believe it wasn't fixed properly. I have managed to reproduce this with somewhat different test case on both Go 1.20.6 and Go 1.21rc3. Here multiple requests are created with package tmpgbudljeu3i_test
import (
"bufio"
"bytes"
"fmt"
"io"
"net/http"
"net/http/httptest"
"testing"
)
func writeChunk(w io.Writer, b []byte) {
fmt.Fprintf(w, "%x\r\n", len(b))
w.Write(b)
fmt.Fprint(w, "\r\n")
}
func startRequestGenerator(url string) io.ReadCloser {
r, w := io.Pipe()
chunk := bytes.Repeat([]byte("A"), 64)
go func() {
for {
_, err := fmt.Fprintf(w, "POST %s HTTP/1.1\r\n", url)
if err != nil {
return
}
fmt.Fprint(w, "Host: localhost\r\n")
fmt.Fprint(w, "Transfer-Encoding: chunked\r\n")
fmt.Fprint(w, "\r\n")
writeChunk(w, chunk)
writeChunk(w, nil)
}
}()
return r
}
func TestHTTPRace(t *testing.T) {
svr := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// cause cs.abortRequestBodyWrite()
// https://github.com/golang/go/blob/go1.20.6/src/net/http/h2_bundle.go#L8205-L8216
w.WriteHeader(http.StatusBadRequest)
}))
svr.EnableHTTP2 = true
svr.StartTLS()
r := startRequestGenerator("https://" + svr.Listener.Addr().String() + "/")
defer r.Close()
b := bufio.NewReader(r)
for i := 0; i < 3; i++ {
req, err := http.ReadRequest(b)
if err != nil {
t.Fatal(err)
}
req.RequestURI = ""
_, err = svr.Client().Transport.RoundTrip(req)
if err != nil {
t.Log(err)
}
}
}
|
Since we're closing in on the final release, reopening and conservatively marking a release blocker. |
@neild any updates here? |
@WGH-, if you are able to reproduce that failure mode with Go 1.20.6, then I don't see how it can possibly be the same regression as the one originally reported for this issue, and it should not be a release-blocker. I suggest filing a new issue with the new reproducer, and we can consider backports for that once it is fixed. |
Strictly speaking, yeah, it does appear in slightly different conditions. It's just underlying problem is the same: HTTP/2 round-tripper discards the request body asynchronously in some cases. One of the cases has been duct-tape-fixed, then duct tape fell apart, and we've got this regression. Some other case has been there for a while. Anyway, I can't close the issue for I'm not the original author. Once you do, I'll create a new issue, no problem. |
I can reproduce the race reported in #60041 (comment) with Go 1.20, so this is not a regression (although it is a bug). I've filed #61596 to track the new report, re-closing this issue as still fixed. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Go 1.20.x: no
Tip: yes
What operating system and processor architecture are you using (
go env
)?darwin
What did you do?
What did you expect to see?
Test pass
What did you see instead?
I believe I have bisected it to this change, #49621, which introduce the type assertion to
req.Body.(*readTrackingBody)
which elides the read body lock./cc @bradfitz @neild
The text was updated successfully, but these errors were encountered: