From 10b214a85303b73ecc5d0d9e4219edb52cd5b7db Mon Sep 17 00:00:00 2001 From: pgjones Date: Mon, 8 Jul 2019 12:44:25 +0100 Subject: [PATCH] Bugfix HTTP/2 flow control handling There are two bugs fixed here, firslty negative flow control values are truthy (only 0 is False), and whilst negative flow control values are possible only positive ones should allow data to be sent. Secondly if the INITIAL_WINDOW_SIZE setting is changed (after the headers have been sent) h2 does not emit a WindowUpdated event (see https://github.com/python-hyper/hyper-h2/issues/1193) yet the window should be updated. This should fix the intermittent (race-condition) errors with h2spec and the Trio worker. --- hypercorn/protocol/h2.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hypercorn/protocol/h2.py b/hypercorn/protocol/h2.py index 48b8af61..fcfd6ecf 100755 --- a/hypercorn/protocol/h2.py +++ b/hypercorn/protocol/h2.py @@ -137,7 +137,9 @@ async def _handle_events(self, events: List[h2.events.Event]) -> None: del self.streams[event.stream_id] elif isinstance(event, h2.events.WindowUpdated): await self._window_updated(event.stream_id) - pass + elif isinstance(event, h2.events.RemoteSettingsChanged): + if h2.settings.SettingCodes.INITIAL_WINDOW_SIZE in event.changed_settings: + await self._window_updated(None) elif isinstance(event, h2.events.ConnectionTerminated): await self.send(Closed()) await self._flush() @@ -149,7 +151,7 @@ async def _flush(self) -> None: async def _send_data(self, stream_id: int, data: bytes) -> None: while True: - while not self.connection.local_flow_control_window(stream_id): + while self.connection.local_flow_control_window(stream_id) < 1: await self._wait_for_flow_control(stream_id) chunk_size = min(len(data), self.connection.local_flow_control_window(stream_id))