]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: document concurrency expectations for Request.Body
authorRoss Light <ross@zombiezen.com>
Thu, 27 Aug 2020 20:08:29 +0000 (13:08 -0700)
committerRuss Cox <rsc@golang.org>
Fri, 16 Oct 2020 16:52:13 +0000 (16:52 +0000)
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>

src/net/http/request.go
src/net/http/server.go

index 54ec1c5593cca96b7dcf3334583c511d8bc7f264..183606d0fffe194861b4443af4fa314d73817cf1 100644 (file)
@@ -175,6 +175,10 @@ type Request struct {
        // 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
index db3a09b9937d5dd4613a5f54d582970614e64298..fab229c92af83fbaee8a54d35ce4ed003d92cd20 100644 (file)
@@ -890,12 +890,12 @@ func (srv *Server) initialReadLimitSize() int64 {
 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
@@ -917,7 +917,7 @@ func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
 }
 
 func (ecr *expectContinueReader) Close() error {
-       ecr.closed = true
+       ecr.closed.setTrue()
        return ecr.readCloser.Close()
 }