Commit 7aa4e29d authored by Brad Fitzpatrick's avatar Brad Fitzpatrick Committed by Ian Lance Taylor

net/http: fix server/transport data race when sharing the request body

Introduced in https://go-review.googlesource.com/12865 (git rev c2db5f4c).

This fix doesn't add any new lock acquistions: it just moves the
existing one taken by the unreadDataSize method and moves it out
wider.

It became flaky at rev c2db5f4c, but now reliably passes again:
$ go test -v -race -run=TestTransportAndServerSharedBodyRace -count=100 net/http

Fixes #11985

Change-Id: I6956d62839fd7c37e2f7441b1d425793f4a0db30
Reviewed-on: https://go-review.googlesource.com/12909
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 5e15e28e
...@@ -880,17 +880,19 @@ func (cw *chunkWriter) writeHeader(p []byte) { ...@@ -880,17 +880,19 @@ func (cw *chunkWriter) writeHeader(p []byte) {
discard = true discard = true
} }
case *body: case *body:
bdy.mu.Lock()
switch { switch {
case bdy.closed: case bdy.closed:
if !bdy.sawEOF { if !bdy.sawEOF {
// Body was closed in handler with non-EOF error. // Body was closed in handler with non-EOF error.
w.closeAfterReply = true w.closeAfterReply = true
} }
case bdy.unreadDataSize() >= maxPostHandlerReadBytes: case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
tooBig = true tooBig = true
default: default:
discard = true discard = true
} }
bdy.mu.Unlock()
default: default:
discard = true discard = true
} }
......
...@@ -737,11 +737,10 @@ func mergeSetHeader(dst *Header, src Header) { ...@@ -737,11 +737,10 @@ func mergeSetHeader(dst *Header, src Header) {
} }
} }
// unreadDataSize returns the number of bytes of unread input. // unreadDataSizeLocked returns the number of bytes of unread input.
// It returns -1 if unknown. // It returns -1 if unknown.
func (b *body) unreadDataSize() int64 { // b.mu must be held.
b.mu.Lock() func (b *body) unreadDataSizeLocked() int64 {
defer b.mu.Unlock()
if lr, ok := b.src.(*io.LimitedReader); ok { if lr, ok := b.src.(*io.LimitedReader); ok {
return lr.N return lr.N
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment