Increase HTTP/2 default flow control window. (#7317)

* increase default flow control window

* fix tests

* fix test

* update changelog

* [autofix.ci] apply automated fixes

* simpler way to override default settings

* acknowledge settings

* document hyper-h2 workaround

* quote RFC

* [autofix.ci] apply automated fixes

* increase MAX_FRAME_SIZE

* update comment

* max out initial window size

* [autofix.ci] apply automated fixes

* increment connection control window

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Hils <github@maximilianhils.com>
This commit is contained in:
Sujal Singh 2024-11-18 14:56:07 +05:30 committed by GitHub
parent 0d069552e7
commit fd346055b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 9 deletions

View File

@ -22,6 +22,8 @@
This may break users of `modify_headers` that rely on filters referencing the message body.
We expect this to be uncommon, but please make yourself heard if that's not the case.
([#7286](https://github.com/mitmproxy/mitmproxy/pull/7286), @lukant)
- Increase HTTP/2 default flow control window size.
([#7317](https://github.com/mitmproxy/mitmproxy/pull/7317), @sujaldev)
- Fix a crash when handling corrupted compressed body in savehar addon and its tests.
([#7320](https://github.com/mitmproxy/mitmproxy/pull/7320), @8192bytes)
- Remove dependency on `protobuf` library as it was no longer being used.

View File

@ -49,9 +49,20 @@ class BufferedH2Connection(h2.connection.H2Connection):
def __init__(self, config: h2.config.H2Configuration):
super().__init__(config)
self.local_settings.initial_window_size = 2**31 - 1
self.local_settings.max_frame_size = 2**17
self.max_inbound_frame_size = 2**17
# hyper-h2 pitfall: we need to acknowledge here, otherwise its sends out the old settings.
self.local_settings.acknowledge()
self.stream_buffers = collections.defaultdict(collections.deque)
self.stream_trailers = {}
def initiate_connection(self):
super().initiate_connection()
# We increase the flow-control window for new streams with a setting,
# but we need to increase the overall connection flow-control window as well.
self.increment_flow_control_window(2**31 - 1 - 65535) # maximum - default
def send_data(
self,
stream_id: int,

View File

@ -116,6 +116,7 @@ def test_simple(tctx):
frames = decode_frames(initial())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
]
sff = FrameFactory()
@ -258,6 +259,7 @@ def test_request_trailers(tctx: Context, open_h2_server_conn: Server, stream):
frames = decode_frames(server_data1.setdefault(b"") + server_data2())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
hyperframe.frame.DataFrame,
hyperframe.frame.HeadersFrame,
@ -323,6 +325,7 @@ def test_long_response(tctx: Context, trailers):
frames = decode_frames(initial())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
]
sff = FrameFactory()
@ -349,11 +352,6 @@ def test_long_response(tctx: Context, trailers):
server,
sff.build_data_frame(b"a" * 10000, flags=[]).serialize(),
)
<< SendData(
server,
sff.build_window_update_frame(0, 40000).serialize()
+ sff.build_window_update_frame(1, 40000).serialize(),
)
>> DataReceived(
server,
sff.build_data_frame(b"a" * 10000, flags=[]).serialize(),
@ -590,10 +588,11 @@ def test_no_normalization(tctx, normalize):
frames = decode_frames(initial())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
]
assert (
hpack.hpack.Decoder().decode(frames[1].data, True) == request_headers_lower
hpack.hpack.Decoder().decode(frames[2].data, True) == request_headers_lower
if normalize
else request_headers
)
@ -666,9 +665,10 @@ def test_end_stream_via_headers(tctx, stream):
frames = decode_frames(forwarded_request_frames())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
]
assert "END_STREAM" in frames[1].flags
assert "END_STREAM" in frames[2].flags
frames = decode_frames(forwarded_response_frames())
assert [type(x) for x in frames] == [
@ -861,6 +861,7 @@ def test_stream_concurrency(tctx):
frames = decode_frames(data_req2())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
]
frames = decode_frames(data_req1())
@ -920,7 +921,7 @@ def test_max_concurrency(tctx):
)
<< SendData(tctx.client, Placeholder(bytes))
)
settings, req1 = decode_frames(req1_bytes())
settings, _, req1 = decode_frames(req1_bytes())
(settings_ack,) = decode_frames(settings_ack_bytes())
(req2,) = decode_frames(req2_bytes())
@ -961,6 +962,7 @@ def test_stream_concurrent_get_connection(tctx):
frames = decode_frames(data())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
hyperframe.frame.HeadersFrame,
]
@ -1013,6 +1015,7 @@ def test_kill_stream(tctx):
frames = decode_frames(data_req1())
assert [type(x) for x in frames] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.HeadersFrame,
]
@ -1120,6 +1123,7 @@ def test_early_server_data(tctx):
)
assert [type(x) for x in decode_frames(server1())] == [
hyperframe.frame.SettingsFrame,
hyperframe.frame.WindowUpdateFrame,
hyperframe.frame.SettingsFrame,
]
assert [type(x) for x in decode_frames(server2())] == [

View File

@ -45,7 +45,8 @@ def h2_client(tctx: Context) -> tuple[h2.connection.H2Connection, Playbook]:
server_preamble = Placeholder(bytes)
assert playbook << SendData(tctx.client, server_preamble)
assert event_types(conn.receive_data(server_preamble())) == [
h2.events.RemoteSettingsChanged
h2.events.RemoteSettingsChanged,
h2.events.WindowUpdated,
]
settings_ack = Placeholder(bytes)
@ -134,6 +135,7 @@ def test_h1_to_h2(tctx):
events = conn.receive_data(request())
assert event_types(events) == [
h2.events.RemoteSettingsChanged,
h2.events.WindowUpdated,
h2.events.RequestReceived,
h2.events.StreamEnded,
]