-
Notifications
You must be signed in to change notification settings - Fork 18k
x/net/http2: closing a requestBody in the ServerHTTP method drops conn-level flow control #28634
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
Possibly related to #28441. |
I'm happy to explain the logs in more detail. Note that a quick work around for me is to do:
But I think this is a hack since I don't think the http2.Server should break if a http handler closed the body. |
I think @wujieliulan actually describes this problem in #16481. |
Got a self-contained repro? You link to #16481 but that looks like it was fixed. Do you think it wasn't fixed? |
Yeah, I think this patch handles an unhandled edge case from #16481:
Applying that to my fork I see my issues go away. I'll work on a contained reproduction sometime next week, although maybe the patch gives you some insight on the issue? |
(found this via #28204) We ran into the same issue a few times, and it seems to be exactly as @jared2501 points out -- closing a request body on the server doesn't update the connection flow-control, leading to the connection stalling as the client side thinks it has exhausted the connection flow-control. I have a repro up: (Edit: The repro almost always fails on Linux within 100 iterations, but requires a higher number of iterations on other platforms). The repro does the following in a loop:
It typically breaks in < 50 iterations, but sometimes (probably 5% of the time) makes it through 100 iterations. When it fails, we see a timeout on the echo call. If I remove the Digging into the code for
The last call nils out the pipe buffer field Logs from the repro running with I tried the patch above on a branch, and it seemed to improve the success rate of getting through 100 iterations (probably to 10-20% instead of 5%) but it didn't seem to fix the issue. |
I have a slightly easier fix, but I am trying to come up with a testcase that makes sense. |
Change https://golang.org/cl/187377 mentions this issue: |
Is there anything we can do to help make progress on this issue? We still see the issue periodically. |
Reviewed. |
Once the pipe is broken, any remaining data needs to be reported as well as any data that is written but dropped. The client side flow control can eventually run out of available bytes to be sent since no WINDOW_UPDATE is sent to reflect the data that is never read in the pipe. Updates golang/go#28634 Change-Id: I83f3c9d3614cd92517af2687489d2ccbf3a65456 Reviewed-on: https://go-review.googlesource.com/c/net/+/187377 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Change https://golang.org/cl/209077 mentions this issue: |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go1.11 darwin/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?What did you do? / What did you expect to see? / What did you see instead?
I'm using an
httputil.ReverseProxy
to proxy a client-streaming RPC (using go grpc). If the upstream connection that the ReverseProxy is copying to breaks then the http2 transport attempts to close the request's body. This causes thehttp2.pipe
that back's thehttp2.requestBody
to have it'spipeBuffer
set to nil see here. When the http2 goes to retrieve the length of the requestBody so that it can return the remaining data to the connection-level flow control it discovers the length is 0 and does not return the data in the pipe to the conn-leel flow control. Therefore, the client get's stuck.Here's some logs I added:
Here's the diff to apply the logs:
The text was updated successfully, but these errors were encountered: