mirror of
https://github.com/golang/go
synced 2024-11-25 03:07:56 -07:00
http: handle unchunked, un-lengthed HTTP/1.1 responses
Fixes #716 This CL simply resumes the previous CL in-flight at https://golang.org/cl/906042/ R=rsc, petar-m, dsymonds CC=golang-dev https://golang.org/cl/4157042
This commit is contained in:
parent
3629d72328
commit
2aaabfc828
@ -44,6 +44,47 @@ var respTests = []respTest{
|
|||||||
"Body here\n",
|
"Body here\n",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Unchunked HTTP/1.1 response without Content-Length or
|
||||||
|
// Connection headers.
|
||||||
|
{
|
||||||
|
"HTTP/1.1 200 OK\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"Body here\n",
|
||||||
|
|
||||||
|
Response{
|
||||||
|
Status: "200 OK",
|
||||||
|
StatusCode: 200,
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
RequestMethod: "GET",
|
||||||
|
Close: true,
|
||||||
|
ContentLength: -1,
|
||||||
|
},
|
||||||
|
|
||||||
|
"Body here\n",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Unchunked HTTP/1.1 204 response without Content-Length.
|
||||||
|
{
|
||||||
|
"HTTP/1.1 204 No Content\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"Body should not be read!\n",
|
||||||
|
|
||||||
|
Response{
|
||||||
|
Status: "204 No Content",
|
||||||
|
StatusCode: 204,
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
RequestMethod: "GET",
|
||||||
|
Close: false,
|
||||||
|
ContentLength: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
|
||||||
// Unchunked response with Content-Length.
|
// Unchunked response with Content-Length.
|
||||||
{
|
{
|
||||||
"HTTP/1.0 200 OK\r\n" +
|
"HTTP/1.0 200 OK\r\n" +
|
||||||
|
@ -172,6 +172,20 @@ type transferReader struct {
|
|||||||
Trailer map[string]string
|
Trailer map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bodyAllowedForStatus returns whether a given response status code
|
||||||
|
// permits a body. See RFC2616, section 4.4.
|
||||||
|
func bodyAllowedForStatus(status int) bool {
|
||||||
|
switch {
|
||||||
|
case status >= 100 && status <= 199:
|
||||||
|
return false
|
||||||
|
case status == 204:
|
||||||
|
return false
|
||||||
|
case status == 304:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// msg is *Request or *Response.
|
// msg is *Request or *Response.
|
||||||
func readTransfer(msg interface{}, r *bufio.Reader) (err os.Error) {
|
func readTransfer(msg interface{}, r *bufio.Reader) (err os.Error) {
|
||||||
t := &transferReader{}
|
t := &transferReader{}
|
||||||
@ -217,6 +231,19 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err os.Error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is no Content-Length or chunked Transfer-Encoding on a *Response
|
||||||
|
// and the status is not 1xx, 204 or 304, then the body is unbounded.
|
||||||
|
// See RFC2616, section 4.4.
|
||||||
|
switch msg.(type) {
|
||||||
|
case *Response:
|
||||||
|
if t.ContentLength == -1 &&
|
||||||
|
!chunked(t.TransferEncoding) &&
|
||||||
|
bodyAllowedForStatus(t.StatusCode) {
|
||||||
|
// Unbounded body.
|
||||||
|
t.Close = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare body reader. ContentLength < 0 means chunked encoding
|
// Prepare body reader. ContentLength < 0 means chunked encoding
|
||||||
// or close connection when finished, since multipart is not supported yet
|
// or close connection when finished, since multipart is not supported yet
|
||||||
switch {
|
switch {
|
||||||
|
Loading…
Reference in New Issue
Block a user