Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
async def test_h2_flow_control(nursery: trio._core._run.Nursery) -> None:
connection = MockConnection()
nursery.start_soon(connection.server.handle_connection)
stream_id = await connection.send_request(
BASIC_HEADERS + [(":method", "GET"), (":path", "/")],
{h2.settings.SettingCodes.INITIAL_WINDOW_SIZE: FLOW_WINDOW_SIZE},
)
await connection.end_stream(stream_id)
async for event in connection.get_events():
if isinstance(event, h2.events.DataReceived):
assert len(event.data) <= FLOW_WINDOW_SIZE
elif isinstance(event, h2.events.StreamEnded):
await connection.close()
def test_incrementing_window_after_close(self):
"""
Hyper does not attempt to increment the flow control window once the
stream is closed.
"""
# For this test, we want to send a response that has three frames at
# the default max frame size (16,384 bytes). That will, on the third
# frame, trigger the processing to increment the flow control window,
# which should then not happen.
f = SettingsFrame(0, settings={h2.settings.INITIAL_WINDOW_SIZE: 100})
c = HTTP20Connection('www.google.com')
c._sock = DummySocket()
c._sock.buffer = BytesIO(f.serialize())
# Open stream 1.
c.request('GET', '/')
# Check what data we've sent right now.
originally_sent_data = c._sock.queue[:]
# Swap out the buffer to get a GoAway frame.
length = 16384
total_length = (3 * 16384) + len(b'some more data')
e = Encoder()
h1 = HeadersFrame(1)
_connection_cls=connection_cls,
io_loop=self.io_loop
)
client.process_pending_requests = mock.MagicMock()
import h2.settings
event_setting = mock.MagicMock()
event_setting.original_value = max_active_requests
event_setting.new_value = max_active_requests + 1
event = mock.MagicMock()
event.changed_settings = {
h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: event_setting
}
client.on_settings_changed(event)
# the processed settings contain a bigger max_active_requests value,
client.process_pending_requests.assert_not_called()
event_setting.original_value = max_active_requests + 1
event_setting.original_value = max_active_requests + 1
# See https://github.com/HypothesisWorks/hypothesis-python/issues/377
frame_factory.refresh_encoder()
c = h2.connection.H2Connection()
c.initiate_connection()
# Set up the stream.
c.send_headers(1, self.example_request_headers, end_stream=True)
headers_frame = frame_factory.build_headers_frame(
headers=self.example_response_headers,
)
c.receive_data(headers_frame.serialize())
# Change the max frame size.
c.update_settings(
{h2.settings.SettingCodes.MAX_FRAME_SIZE: frame_size}
)
settings_ack = frame_factory.build_settings_frame({}, ack=True)
c.receive_data(settings_ack.serialize())
# Greatly increase the flow control windows: we're not here to test
# flow control today.
c.increment_flow_control_window(increment=(2 * frame_size) + 1)
c.increment_flow_control_window(
increment=(2 * frame_size) + 1, stream_id=1
)
# Send one DATA frame that is exactly the max frame size: confirm it's
# fine.
data = frame_factory.build_data_frame(
data=(b'\x00' * frame_size),
)
"""
c = h2.connection.H2Connection(config=self.server_config)
c.receive_data(frame_factory.preamble())
c.clear_outbound_data_buffer()
# Receive the first request, which causes no problem.
f = frame_factory.build_headers_frame(
stream_id=1,
headers=self.request_header_block
)
data = f.serialize()
c.receive_data(data)
# Now, send a settings change. It's un-ACKed at this time. A new
# request arrives, also without incident.
c.update_settings({h2.settings.SettingCodes.HEADER_TABLE_SIZE: 128})
c.clear_outbound_data_buffer()
f = frame_factory.build_headers_frame(
stream_id=3,
headers=self.request_header_block
)
data = f.serialize()
c.receive_data(data)
# We get a SETTINGS ACK.
f = frame_factory.build_settings_frame({}, ack=True)
data = f.serialize()
c.receive_data(data)
# Now a third request comes in. This explodes, as it does not contain
# a dynamic table size update.
f = frame_factory.build_headers_frame(
async def test_h2_flow_control(serving_app: Quart, event_loop: asyncio.AbstractEventLoop) -> None:
connection = MockH2Connection(serving_app, event_loop)
connection.send_request(
BASIC_H2_HEADERS, {h2.settings.SettingCodes.INITIAL_WINDOW_SIZE: FLOW_WINDOW_SIZE},
)
response_data = b''
async for event in connection.get_events():
if isinstance(event, h2.events.DataReceived):
assert len(event.data) <= FLOW_WINDOW_SIZE
response_data += event.data
elif isinstance(event, h2.events.StreamEnded):
break
assert response_data.decode() == BASIC_DATA
# This one's here because h2 helpfully populates remote_settings
# with default values even if the peer doesn't send the setting.
SettingCodes.ENABLE_CONNECT_PROTOCOL: 0,
}
assert dict(h2_conn.remote_settings) == expected_settings
# We don't expect the ENABLE_CONNECT_PROTOCOL to be in the handshake
expected_settings.pop(SettingCodes.ENABLE_CONNECT_PROTOCOL)
assert len(backend.server.settings_changed) == 1
settings = backend.server.settings_changed[0]
assert isinstance(settings, h2.events.RemoteSettingsChanged)
assert len(settings.changed_settings) == len(expected_settings)
for setting_code, changed_setting in settings.changed_settings.items():
assert isinstance(changed_setting, h2.settings.ChangedSetting)
assert changed_setting.new_value == expected_settings[setting_code]
def connection_made(self, transport):
self._transport = transport
self._conn.initiate_connection()
self._conn.update_settings({
settings.SettingCodes.MAX_CONCURRENT_STREAMS: self._inbound_requests.maxsize})
self._flush()
self._stream_creatable.sync()
self.resume_writing()
self._last_active = self._loop.time()
self._functional.sync()
send: Callable[[Event], Awaitable[None]],
spawn_app: Callable[[dict, Callable], Awaitable[Callable]],
event_class: Type[IOEvent],
) -> None:
self.client = client
self.closed = False
self.config = config
self.connection = h2.connection.H2Connection(
config=h2.config.H2Configuration(client_side=False, header_encoding=None)
)
self.connection.DEFAULT_MAX_INBOUND_FRAME_SIZE = config.h2_max_inbound_frame_size
self.connection.local_settings = h2.settings.Settings(
client=False,
initial_values={
h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: config.h2_max_concurrent_streams,
h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: config.h2_max_header_list_size,
h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL: 1,
},
)
self.event_class = event_class
self.send = send
self.server = server
self.spawn_app = spawn_app
self.ssl = ssl
self.streams: Dict[int, Union[HTTPStream, WSStream]] = {}
# The below are used by the sending task
self.has_data = event_class()
self.priority = priority.PriorityTree()
self.stream_buffers: Dict[int, StreamBuffer] = {}
upgrade_request: Optional[h11.Request] = None,
received_data: Optional[bytes] = None,
) -> None:
super().__init__(loop, config, transport, "h2")
self.app = app
self.streams: Dict[int, H2SyncStream] = {}
self.flow_control: Dict[int, asyncio.Event] = {}
self.connection = h2.connection.H2Connection(
config=h2.config.H2Configuration(client_side=False, header_encoding=None)
)
self.connection.DEFAULT_MAX_INBOUND_FRAME_SIZE = config.h2_max_inbound_frame_size
self.connection.local_settings = h2.settings.Settings(
client=False,
initial_values={
h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: config.h2_max_concurrent_streams,
h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: config.h2_max_header_list_size,
h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL: 1,
},
)
if upgrade_request is None:
self.connection.initiate_connection()
if received_data:
self.data_received(received_data)
else:
settings = ""
headers = []
for name, value in upgrade_request.headers:
if name.lower() == b"http2-settings":
settings = value.decode()
elif name.lower() == b"host":