]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: Make ReadResponse work with a nil Request parameter
authorTaru Karttunen <taruti@taruti.net>
Fri, 9 Aug 2013 22:11:03 +0000 (15:11 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 9 Aug 2013 22:11:03 +0000 (15:11 -0700)
Fixes #5583

R=golang-dev, dave, bradfitz
CC=golang-dev
https://golang.org/cl/9821043

src/pkg/net/http/response.go
src/pkg/net/http/response_test.go
src/pkg/net/http/transfer.go

index 30d785f541356163dc78830dd5a0d6b91ee3eccd..35d0ba3bb151343bab52f5f00bfb8995c269b910 100644 (file)
@@ -98,18 +98,17 @@ func (r *Response) Location() (*url.URL, error) {
        return url.Parse(lv)
 }
 
-// ReadResponse reads and returns an HTTP response from r.  The
-// req parameter specifies the Request that corresponds to
-// this Response.  Clients must call resp.Body.Close when finished
-// reading resp.Body.  After that call, clients can inspect
-// resp.Trailer to find key/value pairs included in the response
-// trailer.
-func ReadResponse(r *bufio.Reader, req *Request) (resp *Response, err error) {
-
+// ReadResponse reads and returns an HTTP response from r.
+// The req parameter optionally specifies the Request that corresponds
+// to this Response. If nil, a GET request is assumed.
+// Clients must call resp.Body.Close when finished reading resp.Body.
+// After that call, clients can inspect resp.Trailer to find key/value
+// pairs included in the response trailer.
+func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {
        tp := textproto.NewReader(r)
-       resp = new(Response)
-
-       resp.Request = req
+       resp := &Response{
+               Request: req,
+       }
 
        // Parse the first line of the response.
        line, err := tp.ReadLine()
index 1f4475088054296f2cb4500639486069ae33e49e..181937a7826e2f7feb1150f56b22f8aa20d8cb9b 100644 (file)
@@ -348,6 +348,29 @@ some body`,
 
                "some body",
        },
+
+       // Unchunked response without Content-Length, Request is nil
+       {
+               "HTTP/1.0 200 OK\r\n" +
+                       "Connection: close\r\n" +
+                       "\r\n" +
+                       "Body here\n",
+
+               Response{
+                       Status:     "200 OK",
+                       StatusCode: 200,
+                       Proto:      "HTTP/1.0",
+                       ProtoMajor: 1,
+                       ProtoMinor: 0,
+                       Header: Header{
+                               "Connection": {"close"}, // TODO(rsc): Delete?
+                       },
+                       Close:         true,
+                       ContentLength: -1,
+               },
+
+               "Body here\n",
+       },
 }
 
 func TestReadResponse(t *testing.T) {
index ce56a563e5eab6da024e8a5ba55f09a9b95c58bf..bacd83732de57ff1fac89c7b664d934eb6db2a36 100644 (file)
@@ -254,7 +254,7 @@ func bodyAllowedForStatus(status int) bool {
 
 // msg is *Request or *Response.
 func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
-       t := &transferReader{}
+       t := &transferReader{RequestMethod: "GET"}
 
        // Unify input
        isResponse := false
@@ -262,11 +262,13 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
        case *Response:
                t.Header = rr.Header
                t.StatusCode = rr.StatusCode
-               t.RequestMethod = rr.Request.Method
                t.ProtoMajor = rr.ProtoMajor
                t.ProtoMinor = rr.ProtoMinor
                t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header)
                isResponse = true
+               if rr.Request != nil {
+                       t.RequestMethod = rr.Request.Method
+               }
        case *Request:
                t.Header = rr.Header
                t.ProtoMajor = rr.ProtoMajor
@@ -274,7 +276,6 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
                // Transfer semantics for Requests are exactly like those for
                // Responses with status code 200, responding to a GET method
                t.StatusCode = 200
-               t.RequestMethod = "GET"
        default:
                panic("unexpected type")
        }