Commit 668cca6c authored by Andy Balholm's avatar Andy Balholm Committed by Brad Fitzpatrick

net/http: ignore extra space between response version and status code

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/40933Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 533ed967
...@@ -153,23 +153,23 @@ func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) { ...@@ -153,23 +153,23 @@ func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {
} }
return nil, err return nil, err
} }
f := strings.SplitN(line, " ", 3) if i := strings.IndexByte(line, ' '); i == -1 {
if len(f) < 2 {
return nil, &badStringError{"malformed HTTP response", line} return nil, &badStringError{"malformed HTTP response", line}
} else {
resp.Proto = line[:i]
resp.Status = strings.TrimLeft(line[i+1:], " ")
} }
reasonPhrase := "" statusCode := resp.Status
if len(f) > 2 { if i := strings.IndexByte(resp.Status, ' '); i != -1 {
reasonPhrase = f[2] statusCode = resp.Status[:i]
} }
if len(f[1]) != 3 { if len(statusCode) != 3 {
return nil, &badStringError{"malformed HTTP status code", f[1]} 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 { 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 var ok bool
if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok { if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok {
return nil, &badStringError{"malformed HTTP version", resp.Proto} return nil, &badStringError{"malformed HTTP version", resp.Proto}
......
...@@ -318,7 +318,7 @@ var respTests = []respTest{ ...@@ -318,7 +318,7 @@ var respTests = []respTest{
{ {
"HTTP/1.0 303\r\n\r\n", "HTTP/1.0 303\r\n\r\n",
Response{ Response{
Status: "303 ", Status: "303",
StatusCode: 303, StatusCode: 303,
Proto: "HTTP/1.0", Proto: "HTTP/1.0",
ProtoMajor: 1, ProtoMajor: 1,
...@@ -532,6 +532,29 @@ some body`, ...@@ -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", "\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. // tests successful calls to ReadResponse, and inspects the returned Response.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment