From 1351d3b416b6ecbfc396b7a7d43dba5115b4aaf7 Mon Sep 17 00:00:00 2001 From: Ronak Jain Date: Tue, 2 Aug 2022 01:49:50 +0530 Subject: [PATCH] http2: update conn flow control when stream closes due to invalid content-length header HTTP2 server does not send WINDOW_UPDATE when client sends more data than declared in content-length header. Client outbound flow control can eventually run out of available bytes and this hangs the client connection as it cannot write DATA frames any longer. --- http2/server.go | 6 ++++++ http2/server_test.go | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/http2/server.go b/http2/server.go index 47524a61..2368499f 100644 --- a/http2/server.go +++ b/http2/server.go @@ -1747,6 +1747,12 @@ func (sc *serverConn) processData(f *DataFrame) error { // Sender sending more than they'd declared? if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { + if sc.inflow.available() < int32(f.Length) { + return sc.countError("data_flow", streamError(id, ErrCodeFlowControl)) + } + sc.inflow.take(int32(f.Length)) + sc.sendWindowUpdate(nil, int(f.Length)) // conn-level + st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the // value of a content-length header field does not equal the sum of the diff --git a/http2/server_test.go b/http2/server_test.go index 2a677b99..ddd3dafb 100644 --- a/http2/server_test.go +++ b/http2/server_test.go @@ -809,6 +809,9 @@ func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) { EndHeaders: true, }) st.writeData(1, true, []byte("12345")) + // Return flow control bytes back, since the data handler closed + // the stream. + st.wantWindowUpdate(0, 5) }) } @@ -3918,7 +3921,7 @@ func TestServer_Rejects_TooSmall(t *testing.T) { EndHeaders: true, }) st.writeData(1, true, []byte("12345")) - + st.wantWindowUpdate(0, 5) st.wantRSTStream(1, ErrCodeProtocol) }) }