Skip to content

Commit 2da8a16

Browse files
benburkerttombergan
authored andcommitted
net/http: ignore response body when forbidden by status code
A 1XX, 204, or 304 response may not include a response body according to RFC 7230, section 3.3.3. If a buggy server returns a 204 or 304 response with a body that is chunked encoded, the invalid body is currently made readable in the Response. This can lead to data races due to the transport connection's read loop which does not wait for the body EOF when the response status is 204 or 304. The correct behavior is to ignore the body on a 204 or 304 response, and treat the body data as the beginning of the next request on the connection. Updates #22330. Change-Id: I89a457ceb783b6f66136d5bf9be0a9b0a04fa955 Reviewed-on: https://go-review.googlesource.com/71910 Reviewed-by: Tom Bergan <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Tom Bergan <[email protected]>
1 parent b0680b4 commit 2da8a16

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/net/http/transfer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
497497
// or close connection when finished, since multipart is not supported yet
498498
switch {
499499
case chunked(t.TransferEncoding):
500-
if noResponseBodyExpected(t.RequestMethod) {
500+
if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) {
501501
t.Body = NoBody
502502
} else {
503503
t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}

src/net/http/transport_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -4337,3 +4337,25 @@ func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, p
43374337
res, err = tr.RoundTrip(req)
43384338
return
43394339
}
4340+
4341+
// Issue 22330: do not allow the response body to be read when the status code
4342+
// forbids a response body.
4343+
func TestNoBodyOnChunked304Response(t *testing.T) {
4344+
defer afterTest(t)
4345+
cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
4346+
conn, buf, _ := w.(Hijacker).Hijack()
4347+
buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
4348+
buf.Flush()
4349+
conn.Close()
4350+
}))
4351+
defer cst.close()
4352+
4353+
res, err := cst.c.Get(cst.ts.URL)
4354+
if err != nil {
4355+
t.Fatal(err)
4356+
}
4357+
4358+
if res.Body != NoBody {
4359+
t.Errorf("Unexpected body on 304 response")
4360+
}
4361+
}

0 commit comments

Comments
 (0)