aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/http/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/http/client.go')
-rw-r--r--libgo/go/net/http/client.go21
1 files changed, 20 insertions, 1 deletions
diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go
index a496f1c..3860d97 100644
--- a/libgo/go/net/http/client.go
+++ b/libgo/go/net/http/client.go
@@ -216,7 +216,7 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d
if req.RequestURI != "" {
req.closeBody()
- return nil, alwaysFalse, errors.New("http: Request.RequestURI can't be set in client requests.")
+ return nil, alwaysFalse, errors.New("http: Request.RequestURI can't be set in client requests")
}
// forkReq forks req into a shallow clone of ireq the first
@@ -265,6 +265,25 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d
}
return nil, didTimeout, err
}
+ if resp == nil {
+ return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a nil *Response with a nil error", rt)
+ }
+ if resp.Body == nil {
+ // The documentation on the Body field says “The http Client and Transport
+ // guarantee that Body is always non-nil, even on responses without a body
+ // or responses with a zero-length body.” Unfortunately, we didn't document
+ // that same constraint for arbitrary RoundTripper implementations, and
+ // RoundTripper implementations in the wild (mostly in tests) assume that
+ // they can use a nil Body to mean an empty one (similar to Request.Body).
+ // (See https://golang.org/issue/38095.)
+ //
+ // If the ContentLength allows the Body to be empty, fill in an empty one
+ // here to ensure that it is non-nil.
+ if resp.ContentLength > 0 && req.Method != "HEAD" {
+ return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a *Response with content length %d but a nil Body", rt, resp.ContentLength)
+ }
+ resp.Body = ioutil.NopCloser(strings.NewReader(""))
+ }
if !deadline.IsZero() {
resp.Body = &cancelTimerBody{
stop: stopTimer,