From dfee3332e66bd3f3afd76615767d2cd9b1905b26 Mon Sep 17 00:00:00 2001 From: Ross Light Date: Thu, 27 Aug 2020 13:08:29 -0700 Subject: [PATCH] net/http: document concurrency expectations for Request.Body 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 Reviewed-by: Russ Cox Trust: Damien Neil Run-TryBot: Damien Neil TryBot-Result: Go Bot --- src/net/http/request.go | 4 ++++ src/net/http/server.go | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/net/http/request.go b/src/net/http/request.go index 54ec1c5593..183606d0ff 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -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 diff --git a/src/net/http/server.go b/src/net/http/server.go index db3a09b993..fab229c92a 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -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() } -- 2.50.0