aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/request.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-09-30 10:40:58 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2016-09-30 19:45:34 +0000
commit9491e7d65e09644eb7db4e2ed5ff0139571cedf3 (patch)
treea6ac35613bf1a51dfba3ce03d40ecc5d141e178c /src/net/http/request.go
parentab6ba99484b637bad0c5a5fa2c590834c14746c7 (diff)
downloadgo-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.go39
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
+}