}
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}
{
"HTTP/1.0 303\r\n\r\n",
Response{
- Status: "303 ",
+ Status: "303",
StatusCode: 303,
Proto: "HTTP/1.0",
ProtoMajor: 1,
},
"\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.