Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
x/net/http2: client sometimes sends extra zero-len DATA frame after request DATA #32254
What version of Go are you using (
It's doing whatever the underlying io.Reader does.
If the underlying reader returns (non-zero, io.EOF), then it sends one 1 DATA frame.
(We tried to change the strings.Reader and bytes.Reader implementations several times in the past to do eager EOF returns but it broke too many tests to be worth it.)
But I suppose we could know better in the case where the request body's content-length was predeclared (as it is when you use http.NewRequest on a few known types like strings.Reader). Once we've read enough bytes then we could assume that no bytes will remain on that reader, but that's also where we currently double-check users' Reader implementations and abort the http2 stream if their declared request content-length doesn't match reality. But I suppose we could trust standard library types and only sanity check unknown types.
But that's a lot of special casing for minimal benefit.
The spec (https://http2.github.io/http2-spec/#malformed) says:
So we can do the following:
Another way is that we can wrap io.Reader into a new io.Reader with content-length constraint. This can be done as a separate package outside x/net, which will have minimal side-effects.
@bradfitz Which way looks good to you? I can do the implementation.
@bradfitz A simplified solution would be to drop the extra bytes silently without producing any actual error except a debug log.
A complete solution would be the following:
Does these sounds OK?
What I did is also simpler than discussed before. It fixes the issue, while still allows sending any body without interruption or truncation, even if the actual length does not match specified content-length. This is exactly the behavior before.
I thought it is the receiving peer's responsibility to handle the malformed request body rather than the sending peer.
Check EOF eagerly on the request body when its content-length is specified and it is expected to end. Thus, the data frame containing the last chunk of data of the body will be marked with END_STREAM eagerly. However, if the specified content-length is incorrect, the whole request body will still be sent, regardless of its actual length. This will render the request malformed according to the spec. We believe it is the receiving peer's responsibility to handle the error. Fix golang/go#32254 Change-Id: Id24c043c7cc3a41421dfd099a139f1b1e08056b9
Updates x/net/http2 to git rev d66e71096ffb9f08f36d9aefcae80ce319de6d68 http2: end stream eagerly after sending the request body https://golang.org/cl/181157 (fixes #32254) all: fix typos https://golang.org/cl/193799 http2: fix memory leak in random write scheduler https://golang.org/cl/198462 (fixes #33812) http2: do not sniff body if Content-Encoding is set https://golang.org/cl/199841 (updates #31753) Also unskips tests from CL 199799. Change-Id: I241c0b1cd18cad5041485be92809137a973e33bd Reviewed-on: https://go-review.googlesource.com/c/go/+/200102 Run-TryBot: Emmanuel Odeke <firstname.lastname@example.org> Reviewed-by: Brad Fitzpatrick <email@example.com> TryBot-Result: Gobot Gobot <firstname.lastname@example.org>