aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/request.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/http/request.go')
-rw-r--r--src/net/http/request.go53
1 files changed, 48 insertions, 5 deletions
diff --git a/src/net/http/request.go b/src/net/http/request.go
index fd9ea5494e..fb6bb0aab5 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -171,7 +171,7 @@ type Request struct {
Body io.ReadCloser
// GetBody defines an optional func to return a new copy of
- // Body. It used for client requests when a redirect requires
+ // Body. It is used for client requests when a redirect requires
// reading the body more than once. Use of GetBody still
// requires setting Body.
//
@@ -313,8 +313,8 @@ type Request struct {
// For outgoing client requests, the context controls cancelation.
//
// For incoming server requests, the context is canceled when the
-// ServeHTTP method returns. For its associated values, see
-// ServerContextKey and LocalAddrContextKey.
+// client's connection closes, the request is canceled (with HTTP/2),
+// or when the ServeHTTP method returns.
func (r *Request) Context() context.Context {
if r.ctx != nil {
return r.ctx
@@ -341,6 +341,18 @@ func (r *Request) ProtoAtLeast(major, minor int) bool {
r.ProtoMajor == major && r.ProtoMinor >= minor
}
+// protoAtLeastOutgoing is like ProtoAtLeast, but is for outgoing
+// requests (see issue 18407) where these fields aren't supposed to
+// matter. As a minor fix for Go 1.8, at least treat (0, 0) as
+// matching HTTP/1.1 or HTTP/1.0. Only HTTP/1.1 is used.
+// TODO(bradfitz): ideally remove this whole method. It shouldn't be used.
+func (r *Request) protoAtLeastOutgoing(major, minor int) bool {
+ if r.ProtoMajor == 0 && r.ProtoMinor == 0 && major == 1 && minor <= 1 {
+ return true
+ }
+ return r.ProtoAtLeast(major, minor)
+}
+
// UserAgent returns the client's User-Agent, if sent in the request.
func (r *Request) UserAgent() string {
return r.Header.Get("User-Agent")
@@ -600,6 +612,12 @@ func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, wai
}
}
+ if bw, ok := w.(*bufio.Writer); ok && tw.FlushHeaders {
+ if err := bw.Flush(); err != nil {
+ return err
+ }
+ }
+
// Write body and trailer
err = tw.WriteBody(w)
if err != nil {
@@ -731,6 +749,12 @@ func validMethod(method string) bool {
// net/http/httptest package, use ReadRequest, or manually update the
// Request fields. See the Request type's documentation for the
// difference between inbound and outbound request fields.
+//
+// If body is of type *bytes.Buffer, *bytes.Reader, or
+// *strings.Reader, the returned request's ContentLength is set to its
+// exact value (instead of -1), GetBody is populated (so 307 and 308
+// redirects can replay the body), and Body is set to NoBody if the
+// ContentLength is 0.
func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
if method == "" {
// We document that "" means "GET" for Request.Method, and people have
@@ -785,7 +809,11 @@ func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
return ioutil.NopCloser(&r), nil
}
default:
- req.ContentLength = -1 // unknown
+ // This is where we'd set it to -1 (at least
+ // if body != NoBody) to mean unknown, but
+ // that broke people during the Go 1.8 testing
+ // period. People depend on it being 0 I
+ // guess. Maybe retry later. See Issue 18117.
}
// For client requests, Request.ContentLength of 0
// means either actually 0, or unknown. The only way
@@ -795,7 +823,7 @@ func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
// so we use a well-known ReadCloser variable instead
// and have the http package also treat that sentinel
// variable to mean explicitly zero.
- if req.ContentLength == 0 {
+ if req.GetBody != nil && req.ContentLength == 0 {
req.Body = NoBody
req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
}
@@ -1289,3 +1317,18 @@ func (r *Request) outgoingLength() int64 {
}
return -1
}
+
+// requestMethodUsuallyLacksBody reports whether the given request
+// method is one that typically does not involve a request body.
+// This is used by the Transport (via
+// transferWriter.shouldSendChunkedRequestBody) to determine whether
+// we try to test-read a byte from a non-nil Request.Body when
+// Request.outgoingLength() returns -1. See the comments in
+// shouldSendChunkedRequestBody.
+func requestMethodUsuallyLacksBody(method string) bool {
+ switch method {
+ case "GET", "HEAD", "DELETE", "OPTIONS", "PROPFIND", "SEARCH":
+ return true
+ }
+ return false
+}