From: Andy Balholm Date: Mon, 17 Apr 2017 18:58:30 +0000 (-0700) Subject: net/http: ignore extra space between response version and status code X-Git-Tag: go1.9beta1~656 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=668cca6cb4fbf217b9e00f306d5e8a6f80134288;p=gostls13.git 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/40933 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- diff --git a/src/net/http/response.go b/src/net/http/response.go index 1b19088a72..1ebea6c45c 100644 --- a/src/net/http/response.go +++ b/src/net/http/response.go @@ -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} diff --git a/src/net/http/response_test.go b/src/net/http/response_test.go index 660d51791b..8b8c90ef50 100644 --- a/src/net/http/response_test.go +++ b/src/net/http/response_test.go @@ -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.