]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: ignore extra space between response version and status code
authorAndy Balholm <andybalholm@gmail.com>
Mon, 17 Apr 2017 18:58:30 +0000 (11:58 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 17 Apr 2017 22:32:05 +0000 (22:32 +0000)
Reading a response with a status line like "HTTP/1.0  401 Unauthorized"
(with two spaces after the version) has been returning an error. Now the
extra space will be ignored.

Fixes #19989

Change-Id: I0c88a6ef7562ba80e2e2635be2070dd1b5b671a7
Reviewed-on: https://go-review.googlesource.com/40933
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

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

index 1b19088a728147596a8e363dea1ebe408e3a9f74..1ebea6c45cbe12c411d69ab6dfc7e4f4357e7410 100644 (file)
@@ -153,23 +153,23 @@ func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {
                }
                return nil, err
        }
-       f := strings.SplitN(line, " ", 3)
-       if len(f) < 2 {
+       if i := strings.IndexByte(line, ' '); i == -1 {
                return nil, &badStringError{"malformed HTTP response", line}
+       } else {
+               resp.Proto = line[:i]
+               resp.Status = strings.TrimLeft(line[i+1:], " ")
        }
-       reasonPhrase := ""
-       if len(f) > 2 {
-               reasonPhrase = f[2]
+       statusCode := resp.Status
+       if i := strings.IndexByte(resp.Status, ' '); i != -1 {
+               statusCode = resp.Status[:i]
        }
-       if len(f[1]) != 3 {
-               return nil, &badStringError{"malformed HTTP status code", f[1]}
+       if len(statusCode) != 3 {
+               return nil, &badStringError{"malformed HTTP status code", statusCode}
        }
-       resp.StatusCode, err = strconv.Atoi(f[1])
+       resp.StatusCode, err = strconv.Atoi(statusCode)
        if err != nil || resp.StatusCode < 0 {
-               return nil, &badStringError{"malformed HTTP status code", f[1]}
+               return nil, &badStringError{"malformed HTTP status code", statusCode}
        }
-       resp.Status = f[1] + " " + reasonPhrase
-       resp.Proto = f[0]
        var ok bool
        if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok {
                return nil, &badStringError{"malformed HTTP version", resp.Proto}
index 660d51791b7ebbcf09f621388a6bd187c7c1790d..8b8c90ef509cfe11dc4f15baef9beec65399b34f 100644 (file)
@@ -318,7 +318,7 @@ var respTests = []respTest{
        {
                "HTTP/1.0 303\r\n\r\n",
                Response{
-                       Status:        "303 ",
+                       Status:        "303",
                        StatusCode:    303,
                        Proto:         "HTTP/1.0",
                        ProtoMajor:    1,
@@ -532,6 +532,29 @@ some body`,
                },
                "\x1f\x8b\b\x00\x00\x00\x00\x00\x00\x00s\xf3\xf7\a\x00\xab'\xd4\x1a\x03\x00\x00\x00",
        },
+
+       // Issue 19989: two spaces between HTTP version and status.
+       {
+               "HTTP/1.0  401 Unauthorized\r\n" +
+                       "Content-type: text/html\r\n" +
+                       "WWW-Authenticate: Basic realm=\"\"\r\n\r\n" +
+                       "Your Authentication failed.\r\n",
+               Response{
+                       Status:     "401 Unauthorized",
+                       StatusCode: 401,
+                       Proto:      "HTTP/1.0",
+                       ProtoMajor: 1,
+                       ProtoMinor: 0,
+                       Request:    dummyReq("GET"),
+                       Header: Header{
+                               "Content-Type":     {"text/html"},
+                               "Www-Authenticate": {`Basic realm=""`},
+                       },
+                       Close:         true,
+                       ContentLength: -1,
+               },
+               "Your Authentication failed.\r\n",
+       },
 }
 
 // tests successful calls to ReadResponse, and inspects the returned Response.