Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_very_insufficiently_very_long_message_frame(self) -> None:
payload = b"x" * 64
payload_len = struct.pack("!Q", len(payload))
frame_bytes = b"\x81\x7f" + payload_len + payload
self._parse_failure_test(
client=True,
frame_bytes=frame_bytes,
close_reason=fp.CloseReason.PROTOCOL_ERROR,
)
def test_close_bad_utf8_payload(self) -> None:
payload = unhexlify("cebae1bdb9cf83cebcceb5eda080656469746564")
with pytest.raises(fp.ParseFailed) as exc:
self._close_test(fp.CloseReason.NORMAL_CLOSURE, reason_bytes=payload)
assert exc.value.code == fp.CloseReason.INVALID_FRAME_PAYLOAD_DATA
sock.connect((uri.hostname, uri.port or 80))
sock.sendall(
connection.send(
Request(host=uri.netloc, target="%s?%s" % (uri.path, uri.query))
)
)
closed = False
while not closed:
data = sock.recv(65535)
connection.receive_data(data)
for event in connection.events():
if isinstance(event, AcceptConnection):
sock.sendall(
connection.send(CloseConnection(code=CloseReason.NORMAL_CLOSURE))
)
try:
sock.close()
except CONNECTION_EXCEPTIONS:
pass
finally:
closed = True
def test_close_whilst_closing() -> None:
client = Connection(CLIENT)
client.send(CloseConnection(code=CloseReason.NORMAL_CLOSURE))
with pytest.raises(LocalProtocolError):
client.send(CloseConnection(code=CloseReason.NORMAL_CLOSURE))
async def test_websocket_closure_from_within(app, client):
@app.websocket('/failure')
async def failme(request, ws, **params):
await ws.close()
await ws.recv()
async with client:
async with client.websocket('/failure') as ws:
await ws.send(b'This shall never be received.')
assert ws.closure.code == CloseReason(1000)
assert ws.closure.reason == 'Closed.'
compressed_payload = b"x" * 23
ext = wpext.PerMessageDeflate()
ext._enabled = True
proto = fp.FrameProtocol(client=True, extensions=[ext])
result = ext.frame_inbound_header(
proto,
fp.Opcode.BINARY,
fp.RsvBits(True, False, False),
len(compressed_payload),
)
assert isinstance(result, fp.RsvBits)
assert result.rsv1
result2 = ext.frame_inbound_payload_data(proto, compressed_payload)
assert result2 is fp.CloseReason.INVALID_FRAME_PAYLOAD_DATA
async def app_send(self, message: Optional[dict]) -> None:
if self.closed:
# Allow app to finish after close
return
if message is None: # ASGI App has finished sending messages
# Cleanup if required
if self.state == ASGIWebsocketState.HANDSHAKE:
await self._send_error_response(500)
await self.config.log.access(
self.scope, {"status": 500, "headers": []}, time() - self.start_time
)
elif self.state == ASGIWebsocketState.CONNECTED:
await self._send_wsproto_event(CloseConnection(code=CloseReason.ABNORMAL_CLOSURE))
await self.send(StreamClosed(stream_id=self.stream_id))
else:
if message["type"] == "websocket.accept" and self.state == ASGIWebsocketState.HANDSHAKE:
self.state = ASGIWebsocketState.CONNECTED
status_code, headers, self.connection = self.handshake.accept(
message.get("subprotocol")
)
await self.send(
Response(stream_id=self.stream_id, status_code=status_code, headers=headers)
)
await self.config.log.access(
self.scope, {"status": status_code, "headers": []}, time() - self.start_time
)
elif (
message["type"] == "websocket.http.response.start"
and self.state == ASGIWebsocketState.HANDSHAKE
async def _close_websocket(self, code: Union[CloseReason, int], reason: str = ''):
if isinstance(code, int):
code = CloseReason(code)
await self._event_queue.put(_CLOSE_MESSAGE)
self._close_code = code
self._close_reason = reason
logger.debug('%s closed by %r', self, ConnectionClosed(code, reason))
"extensions": {"websocket.http.response": {}},
}
self.start_time = time()
if not self.handshake.is_valid():
await self._send_error_response(400)
else:
self.app_put = await self.spawn_app(self.scope, self.app_send)
await self.app_put({"type": "websocket.connect"})
elif isinstance(event, (Body, Data)):
self.connection.receive_data(event.data)
await self._handle_events()
elif isinstance(event, StreamClosed) and not self.closed:
self.closed = True
if self.app_put is not None:
if self.state in {ASGIWebsocketState.HTTPCLOSED, ASGIWebsocketState.CLOSED}:
code = CloseReason.NORMAL_CLOSURE.value
else:
code = CloseReason.ABNORMAL_CLOSURE.value
await self.app_put({"type": "websocket.disconnect", "code": code})
def __init__(self, client_conn, server_conn, handshake_flow, live=None):
super().__init__("websocket", client_conn, server_conn, live)
self.messages: List[WebSocketMessage] = []
"""A list containing all WebSocketMessage's."""
self.close_sender = 'client'
"""'client' if the client initiated connection closing."""
self.close_code = CloseReason.NORMAL_CLOSURE
"""WebSocket close code."""
self.close_message = '(message missing)'
"""WebSocket close message."""
self.close_reason = 'unknown status code'
"""WebSocket close reason."""
self.stream = False
"""True of this connection is streaming directly to the other endpoint."""
self.handshake_flow = handshake_flow
"""The HTTP flow containing the initial WebSocket handshake."""
self.ended = False
"""True when the WebSocket connection has been closed."""
self._inject_messages_client = queue.Queue(maxsize=1)
self._inject_messages_server = queue.Queue(maxsize=1)
if handshake_flow: