Skip to content

Commit 355b984

Browse files
committed
Preserve flow-control windows when rejecting local increments
Signed-off-by: Xucheng Zhou <aden1350@outlook.com>
1 parent bc239af commit 355b984

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

‎src/h2/windows.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,13 @@ def window_opened(self, size: int) -> None:
6464
:returns: Nothing
6565
:rtype: ``None``
6666
"""
67-
self.current_window_size += size
67+
new_window_size = self.current_window_size + size
6868

69-
if self.current_window_size > LARGEST_FLOW_CONTROL_WINDOW:
69+
if new_window_size > LARGEST_FLOW_CONTROL_WINDOW:
7070
msg = f"Flow control window mustn't exceed {LARGEST_FLOW_CONTROL_WINDOW}"
7171
raise FlowControlError(msg)
7272

73+
self.current_window_size = new_window_size
7374
self.max_window_size = max(self.current_window_size, self.max_window_size)
7475

7576
def process_bytes(self, size: int) -> int | None:

‎tests/test_flow_control_window.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,29 @@ def test_reject_local_overlarge_increase_stream_window(self) -> None:
650650
with pytest.raises(h2.exceptions.FlowControlError):
651651
c.increment_flow_control_window(increment=increment, stream_id=1)
652652

653+
@pytest.mark.parametrize("stream_id", [None, 1])
654+
def test_rejected_local_window_increase_preserves_window(self, frame_factory, stream_id: int | None) -> None:
655+
"""
656+
Rejecting a local increase must not change the advertised window or
657+
prevent a subsequent valid increase.
658+
"""
659+
c = h2.connection.H2Connection()
660+
c.initiate_connection()
661+
c.send_headers(1, self.example_request_headers)
662+
c.clear_outbound_data_buffer()
663+
before = c.inbound_flow_control_window
664+
665+
with pytest.raises(h2.exceptions.FlowControlError):
666+
c.increment_flow_control_window(2**31 - before, stream_id=stream_id)
667+
668+
assert c.inbound_flow_control_window == before
669+
assert c.data_to_send() == b""
670+
c.increment_flow_control_window(1, stream_id=stream_id)
671+
expected = frame_factory.build_window_update_frame(
672+
stream_id=stream_id or 0, increment=1,
673+
)
674+
assert c.data_to_send() == expected.serialize()
675+
653676
def test_send_update_on_closed_streams(self, frame_factory) -> None:
654677
c = h2.connection.H2Connection()
655678
c.initiate_connection()

0 commit comments

Comments
 (0)