diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2016-09-30 10:40:58 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2016-09-30 19:45:34 +0000 |
| commit | 9491e7d65e09644eb7db4e2ed5ff0139571cedf3 (patch) | |
| tree | a6ac35613bf1a51dfba3ce03d40ecc5d141e178c /src/net/http/request.go | |
| parent | ab6ba99484b637bad0c5a5fa2c590834c14746c7 (diff) | |
| download | go-9491e7d65e09644eb7db4e2ed5ff0139571cedf3.tar.xz | |
net/http: refactor testing of Request.Body on 0 ContentLength
Code movement only, to look more like the equivalent http2 code, and
to make an upcoming fix look more obvious.
Updates #16002 (to be fixed once this code is in)
Change-Id: Iaa4f965be14e98f9996e7c4624afe6e19bed1a80
Reviewed-on: https://go-review.googlesource.com/30087
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Diffstat (limited to 'src/net/http/request.go')
| -rw-r--r-- | src/net/http/request.go | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/net/http/request.go b/src/net/http/request.go index b191d519f2..21e25b08ef 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -1215,3 +1215,42 @@ func (r *Request) isReplayable() bool { } return false } + +// bodyAndLength reports the request's body and content length, with +// the difference from r.ContentLength being that 0 means actually +// zero, and -1 means unknown. +func (r *Request) bodyAndLength() (body io.Reader, contentLen int64) { + body = r.Body + if body == nil { + return nil, 0 + } + if r.ContentLength != 0 { + return body, r.ContentLength + } + // Don't try to sniff the bytes if they're using a custom + // transfer encoding (or specified chunked themselves), and + // don't sniff if they're not using HTTP/1.1 and can't chunk + // anyway. + if len(r.TransferEncoding) != 0 || !r.ProtoAtLeast(1, 1) { + return body, -1 + } + + // Test to see if it's actually zero or just unset. + var buf [1]byte + n, err := io.ReadFull(body, buf[:]) + if err != nil && err != io.EOF { + return errorReader{err}, -1 + } + + if n == 1 { + // Oh, guess there is data in this Body Reader after all. + // The ContentLength field just wasn't set. + // Stich the Body back together again, re-attaching our + // consumed byte. + // TODO(bradfitz): switch to stitchByteAndReader + return io.MultiReader(bytes.NewReader(buf[:]), body), -1 + } + + // Body is actually empty. + return nil, 0 +} |
