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_initial_keep_alive_timeout() -> None:
config = Config()
config.keep_alive_timeout = 0.01
client_stream, server_stream = trio.testing.memory_stream_pair()
server_stream.socket = MockSocket()
server = TCPServer(echo_framework, config, server_stream)
with trio.fail_after(2 * config.keep_alive_timeout):
await server.run()
# Only way to confirm closure is to invoke an error
with pytest.raises(trio.BrokenResourceError):
await client_stream.send_all(b"GET / HTTP/1.1\r\nHost: hypercorn\r\n")
async def test_initial_keep_alive_timeout() -> None:
client_stream, server_stream = trio.testing.memory_stream_pair()
server_stream.socket = MockSocket()
config = Config()
config.keep_alive_timeout = 0.01
server = H2Server(echo_framework, config, server_stream)
with trio.fail_after(2 * config.keep_alive_timeout):
await server.handle_connection()
# Only way to confirm closure is to invoke an error
with pytest.raises(trio.BrokenResourceError):
await client_stream.send_all(b"Rubbish")
'''
Run the resource monitor.
:returns: Runs until cancelled.
'''
next_run = trio.current_time() + self._interval
while True:
measurement = self._measure()
self._measurements.append(measurement)
to_remove = set()
for channel in self._channels:
try:
channel.send_nowait(measurement)
except trio.WouldBlock:
continue
except trio.BrokenResourceError:
to_remove.add(channel)
for channel in to_remove:
logger.debug('Removing closed channel')
self._channels.remove(channel)
sleep_time = next_run - trio.current_time()
while sleep_time < 0:
sleep_time += self._interval
await trio.sleep(sleep_time)
next_run += self._interval
:returns: This function returns when the sync is complete.
'''
logger.info('%r Starting', self)
async with trio.open_nursery() as nursery:
self._cancel_scope = nursery.cancel_scope
await self._set_initial_job_status()
nursery.start_soon(self._job_status_task)
try:
await self._run_sync()
except (trio.BrokenResourceError, trio.ClosedResourceError):
logger.info('%r Aborted', self)
nursery.cancel_scope.cancel()
try:
await self._send_complete()
logger.info('%r Finished', self)
except (trio.BrokenResourceError, trio.ClosedResourceError):
# If we can't send the completion message, then bail out.
pass
try:
task_status.started()
while True:
try:
if self._stream is None:
raise exceptions.AmqpClosedConnection
if self.server_heartbeat:
timeout = self.server_heartbeat * 2
else:
timeout = inf
with trio.fail_after(timeout):
try:
frame = await self.get_frame()
except trio.BrokenResourceError:
# the stream is now *really* closed …
return
try:
await self.dispatch_frame(frame)
except Exception as exc:
# We want to raise this exception so that the
# nursery ends the protocol, but we need keep
# going for now (need to process the close-OK
# message). Thus we start a new task that
# raises the actual error, somewhat later.
async def owch(exc):
await trio.sleep(0)
raise exc
self._nursery.start_soon(owch, exc)
async def feed_input():
async with proc.stdin:
if input:
try:
await proc.stdin.send_all(input)
except trio.BrokenResourceError:
pass
async def handle_connection(self) -> None:
try:
request = await self.read_request()
async with trio.open_nursery() as nursery:
nursery.start_soon(self.read_messages)
await self.handle_websocket(request)
if self.state == ASGIWebsocketState.HTTPCLOSED:
raise MustCloseError()
except (trio.BrokenResourceError, trio.ClosedResourceError):
await self.asgi_put({"type": "websocket.disconnect"})
except MustCloseError:
pass
finally:
await self.aclose()
t3 = trio.current_time()
t = t3 - t0
self.logger.info(f'{ident} - Completed in {t:.3f}s')
except Exception as exc:
self.logger.error(f'Unexpected error: {exc}')
response = str(exc)
self.logger.error(response, exc_info=exc)
try:
await server_stream.send_all(b'ER')
self.logger.warning(f'Forwarding Exception: {response}')
response = to_bytes(response)
await server_stream.send_all(struct.pack('!Q', len(response)))
await server_stream.send_all(response)
except trio.BrokenResourceError:
# Broken Pipe, we cannot forward the error
pass
async def handle_connection(self) -> None:
try:
# Loop over the requests in order of receipt (either
# pipelined or due to keep-alive).
while True:
with trio.fail_after(self.config.keep_alive_timeout):
request = await self.read_request()
self.raise_if_upgrade(request, self.connection.trailing_data[0])
async with trio.open_nursery() as nursery:
nursery.start_soon(self.handle_request, request)
await self.read_body()
await self.recycle_or_close()
except (trio.BrokenResourceError, trio.ClosedResourceError):
await self.asgi_put({"type": "http.disconnect"})
await self.aclose()
except (trio.TooSlowError, MustCloseError):
await self.aclose()
except H2CProtocolRequired as error:
await self.asend(
h11.InformationalResponse(
status_code=101, headers=[(b"upgrade", b"h2c")] + self.response_headers()
)
)
raise error
except WrongProtocolError:
raise # Do not close the connection
try:
data = await self._socket.receive_some(4 - len(buffer))
except (trio.ClosedResourceError, trio.BrokenResourceError) as err:
raise RemoteDisconnected from err
if data == b"":
raise RemoteDisconnected()
buffer.extend(data)
t_size = 4 + int.from_bytes(buffer[:4], "little")
while len(buffer) < t_size:
try:
data = await self._socket.receive_some(t_size - len(buffer))
except (trio.ClosedResourceError, trio.BrokenResourceError) as err:
raise RemoteDisconnected from err
if data == b"":
raise RemoteDisconnected()
buffer.extend(data)
msg = cast(Message, pickle.loads(buffer[4:t_size]))
return msg