Skip to content

Commit 13a9a73

Browse files
jronakneild
authored andcommitted
http2: fix conn flow control when stream closes on bad content-length
HTTP2 server does not send WINDOW_UPDATE when the client sends more data than declared in the content-length header. Client flow control can eventually run out of available bytes which hangs the client connection as it cannot write DATA frames for any stream any longer. Fixes: golang/go#54185 Change-Id: I48ae3212fb31ce302715abe129adf5c9625faf12 GitHub-Last-Rev: 1351d3b GitHub-Pull-Request: #143 Reviewed-on: https://go-review.googlesource.com/c/net/+/421974 Reviewed-by: Than McIntosh <thanm@google.com> Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
1 parent 07c6da5 commit 13a9a73

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

‎http2/server.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,12 @@ func (sc *serverConn) processData(f *DataFrame) error {
17471747

17481748
// Sender sending more than they'd declared?
17491749
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
1750+
if sc.inflow.available() < int32(f.Length) {
1751+
return sc.countError("data_flow", streamError(id, ErrCodeFlowControl))
1752+
}
1753+
sc.inflow.take(int32(f.Length))
1754+
sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1755+
17501756
st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
17511757
// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
17521758
// value of a content-length header field does not equal the sum of the

‎http2/server_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,9 @@ func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) {
809809
EndHeaders: true,
810810
})
811811
st.writeData(1, true, []byte("12345"))
812+
// Return flow control bytes back, since the data handler closed
813+
// the stream.
814+
st.wantWindowUpdate(0, 5)
812815
})
813816
}
814817

@@ -3918,7 +3921,7 @@ func TestServer_Rejects_TooSmall(t *testing.T) {
39183921
EndHeaders: true,
39193922
})
39203923
st.writeData(1, true, []byte("12345"))
3921-
3924+
st.wantWindowUpdate(0, 5)
39223925
st.wantRSTStream(1, ErrCodeProtocol)
39233926
})
39243927
}

0 commit comments

Comments
 (0)