mirror of
https://github.com/golang/net.git
synced 2026-03-31 10:27:08 +09:00
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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user