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.
This commit is contained in:
Ronak Jain
2022-08-02 01:49:50 +05:30
parent c7608f3a84
commit 1351d3b416
2 changed files with 10 additions and 1 deletions

View File

@@ -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

View File

@@ -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)
})
}