diff --git a/src/net/http/internal/http2/server.go b/src/net/http/internal/http2/server.go index 1a7a09ab9e..37808dd0d2 100644 --- a/src/net/http/internal/http2/server.go +++ b/src/net/http/internal/http2/server.go @@ -2174,14 +2174,18 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res return nil, nil, err } bodyOpen := !f.StreamEnded() - if bodyOpen { - if vv, ok := rp.Header["Content-Length"]; ok { - if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil { - req.ContentLength = int64(cl) - } else { - req.ContentLength = 0 - } + if vv, ok := rp.Header["Content-Length"]; ok { + if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil { + req.ContentLength = int64(cl) } else { + req.ContentLength = 0 + } + if !bodyOpen && req.ContentLength != 0 { + return nil, nil, sc.countError("bodyless_content_length", streamError(f.StreamID, ErrCodeProtocol)) + } + } + if bodyOpen { + if _, ok := rp.Header["Content-Length"]; !ok { req.ContentLength = -1 } req.Body.(*requestBody).pipe = &pipe{ diff --git a/src/net/http/internal/http2/server_test.go b/src/net/http/internal/http2/server_test.go index f2964f4d15..6c316766a9 100644 --- a/src/net/http/internal/http2/server_test.go +++ b/src/net/http/internal/http2/server_test.go @@ -779,6 +779,20 @@ func testServer_Request_Post_Body_ContentLength_TooLarge(t testing.TB) { }) } +func TestServer_Request_Post_Body_ContentLength_EndStream(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader( + ":method", "POST", + "content-length", "3", + ), + EndStream: true, + EndHeaders: true, + }) + }) +} + func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) { synctestTest(t, testServer_Request_Post_Body_ContentLength_TooSmall) }