A server handler can close an inbound Request.Body to indicate that it
is not interested in the remainder of the request body.
Equivalently, a client can close a Response.Body indicate that it is
not interesed in the remainder of the response body.
In both cases, if we receive DATA frames from the peer for the stream,
we should return connection-level flow control credit for the discarded data.
We do not return stream-level flow control, since we don't want to unblock
further sends of data that we're just going to discard.
Closing either a Response.Body or an inbound Request.Body results in a
pipe.BreakWithError. Reads from a broken pipe fail immediately.
Previously, writes to a broken pipe would succeed, discarding the written
data and incrementing the pipe's unread count. Silently discarding
data written to a broken pipe results in both the Transport and Server
failing to detect the condition where data has been discarded.
Change pipes to return an error when writing to a broken pipe.
Change transportResponseBody.Close to break the response body before
returning flow control credit for unread data in the pipe, avoiding
a race condition where data is added to the pipe in between the
return of flow control credit and the pipe breaking.
Change the Server to treat an error writing to the inbound request
body as an expected condition (since this only happens when a
handler closes the request body), returning connection-level
flow control credit for the discarded data.
Fixesgolang/go#57578
Change-Id: I1ed4ea9865818f9c7d7eb4500edfd7556e3cbcbf
Reviewed-on: https://go-review.googlesource.com/c/net/+/475135
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Move the entire request write into a new writeRequest function,
which runs as its own goroutine.
The writeRequest function handles all indefintely-blocking
operations (in particular, network writes), as well as all
post-request cleanup: Closing the request body, sending a
RST_STREAM when necessary, releasing the concurrency slot
held by the stream, etc.
Consolidates several goroutines used to wait for stream
slots, write the body, and close response bodies.
Ensures that RoundTrip does not block past request cancelation.
Change-Id: Iaf8bb3e17de89384b031ec4f324918b5720f5877
Reviewed-on: https://go-review.googlesource.com/c/net/+/353390
Trust: Damien Neil <dneil@google.com>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
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>
Case happens if Read is called after it has already returned an error
previously. Verified that the new TestPipeCloseWithError test fails
before this change but passes after.
Updates golang/go#20501
Change-Id: I636fbb194f2d0019b0722556cc25a88da2d18e13
Reviewed-on: https://go-review.googlesource.com/44330
Run-TryBot: Tom Bergan <tombergan@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
After a response body is closed, we keep writing to the bufPipe. This
accumulates bytes that will never be read, wasting memory. The fix is to
discard the buffer on pipe.BreakWithError.
Updates golang/go#20448
Change-Id: Ia2cf46cb8c401fd8091ef3785eb48fe7b188bb57
Reviewed-on: https://go-review.googlesource.com/43810
Run-TryBot: Tom Bergan <tombergan@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The tree's pretty inconsistent about single space vs double space
after a period in documentation. Make it consistently a single space,
per earlier decisions, and changes in go repository. This means
contributors won't be confused by misleading precedence.
This CL was generated with:
perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])')
on top of copyright headers change in https://golang.org/cl/32878.
Follows https://golang.org/cl/20022.
Change-Id: I821e4a300122b4668aa31e12eaa914db615e5369
Reviewed-on: https://go-review.googlesource.com/32879
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The Transport's Response.Body.Close call was closing the
Response.Body, but the Reader implementation was yielding its buffered
data before returning the error. Add a new method to force an
immediate close. An audit of the other CloseWithError callers found
that the after-buffered-data behavior was correct for them.
New tests in the main go repo in net/http/clientserver_test.go:
TestResponseBodyReadAfterClose_h1 and TestResponseBodyReadAfterClose_h2
Updates golang/go#13648
Change-Id: If3a13a20c106b5a7bbe668ccb4e3c704a0e0682b
Reviewed-on: https://go-review.googlesource.com/17937
Reviewed-by: Russ Cox <rsc@golang.org>
Make the pipe code take an interface as the backing store. Now a pipe
is something that's goroutine-safe and does the Cond waits but its underlying data
is now an interface: anything that's a ReaderWriter with a Len method (such as a
*bytes.Buffer), or a fixedBuffer (renamed in this CL from 'buffer').
This opens the ground to having a non-fixed buffer used with pipe.
This also moves the CloseWithError code up into the pipe code, out of
fixedBuffer.
Change-Id: Ia3b853e8aa8920807b705ff4e41bed934a8c67b7
Reviewed-on: https://go-review.googlesource.com/16312
Reviewed-by: Blake Mizerany <blake.mizerany@gmail.com>