This is primarily aimed at client requests where the user can supply
their own io.ReadCloser, but also clarifies server request behavior.
A server request body can be one of:
- *body
- *http2RequestBody
- *expectContinueReader
- *maxBytesReader
Of those, *expectContinueReader did not meet these expectations, so this
change also removes the data race.
Change-Id: Id4f1ae573d938347b1123a7b612b271aabb045a4
Reviewed-on: https://go-review.googlesource.com/c/go/+/251087
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
// but will return EOF immediately when no body is present.
// The Server will close the request body. The ServeHTTP
// Handler does not need to.
+ //
+ // Body must allow Read to be called concurrently with Close.
+ // In particular, calling Close should unblock a Read waiting
+ // for input.
Body io.ReadCloser
// GetBody defines an optional func to return a new copy of
type expectContinueReader struct {
resp *response
readCloser io.ReadCloser
- closed bool
+ closed atomicBool
sawEOF atomicBool
}
func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
- if ecr.closed {
+ if ecr.closed.isSet() {
return 0, ErrBodyReadAfterClose
}
w := ecr.resp
}
func (ecr *expectContinueReader) Close() error {
- ecr.closed = true
+ ecr.closed.setTrue()
return ecr.readCloser.Close()
}