def test_encode_decode_fragmented_text_frame(self): frame1 = Frame(OP_TEXT, "café".encode("utf-8"), fin=False) frame2 = Frame(OP_CONT, " & ".encode("utf-8"), fin=False) frame3 = Frame(OP_CONT, "croissants".encode("utf-8")) enc_frame1 = self.extension.encode(frame1) enc_frame2 = self.extension.encode(frame2) enc_frame3 = self.extension.encode(frame3) self.assertEqual( enc_frame1, dataclasses.replace(frame1, rsv1=True, data=b"JNL;\xbc\x12\x00\x00\x00\xff\xff"), ) self.assertEqual( enc_frame2, dataclasses.replace(frame2, data=b"RPS\x00\x00\x00\x00\xff\xff")) self.assertEqual( enc_frame3, dataclasses.replace(frame3, data=b"J.\xca\xcf,.N\xcc+)\x06\x00")) dec_frame1 = self.extension.decode(enc_frame1) dec_frame2 = self.extension.decode(enc_frame2) dec_frame3 = self.extension.decode(enc_frame3) self.assertEqual(dec_frame1, frame1) self.assertEqual(dec_frame2, frame2) self.assertEqual(dec_frame3, frame3)
def test_no_decode_fragmented_binary_frame(self): frame1 = Frame(False, OP_TEXT, b"tea ") frame2 = Frame(True, OP_CONT, b"time") dec_frame1 = self.extension.decode(frame1) dec_frame2 = self.extension.decode(frame2) self.assertEqual(dec_frame1, frame1) self.assertEqual(dec_frame2, frame2)
def test_encode_decode_binary_frame(self): frame = Frame(True, OP_BINARY, b"tea") enc_frame = self.extension.encode(frame) self.assertEqual(enc_frame, frame._replace(rsv1=True, data=b"*IM\x04\x00")) dec_frame = self.extension.decode(enc_frame) self.assertEqual(dec_frame, frame)
def test_encode_decode_text_frame(self): frame = Frame(True, OP_TEXT, "café".encode("utf-8")) enc_frame = self.extension.encode(frame) self.assertEqual(enc_frame, frame._replace(rsv1=True, data=b"JNL;\xbc\x12\x00")) dec_frame = self.extension.decode(enc_frame) self.assertEqual(dec_frame, frame)
def test_no_decode_fragmented_text_frame(self): frame1 = Frame(False, OP_TEXT, "café".encode("utf-8")) frame2 = Frame(False, OP_CONT, " & ".encode("utf-8")) frame3 = Frame(True, OP_CONT, "croissants".encode("utf-8")) dec_frame1 = self.extension.decode(frame1) dec_frame2 = self.extension.decode(frame2) dec_frame3 = self.extension.decode(frame3) self.assertEqual(dec_frame1, frame1) self.assertEqual(dec_frame2, frame2) self.assertEqual(dec_frame3, frame3)
def test_compress_settings(self): # Configure an extension so that no compression actually occurs. extension = PerMessageDeflate(False, False, 15, 15, {"level": 0}) frame = Frame(True, OP_TEXT, "café".encode("utf-8")) enc_frame = extension.encode(frame) self.assertEqual( enc_frame, frame._replace( rsv1=True, data=b"\x00\x05\x00\xfa\xffcaf\xc3\xa9\x00" # not compressed ), )
def test_context_takeover(self): frame = Frame(True, OP_TEXT, "café".encode("utf-8")) enc_frame1 = self.extension.encode(frame) enc_frame2 = self.extension.encode(frame) self.assertEqual(enc_frame1.data, b"JNL;\xbc\x12\x00") self.assertEqual(enc_frame2.data, b"J\x06\x11\x00\x00")
async def test_ws_frame_put_fetched(opcode): assembler = WebsocketFrameAssembler(Mock()) assembler.message_fetched = AsyncMock() assembler.message_fetched.is_set = Mock(return_value=False) await assembler.put(Frame(opcode, b"")) assembler.message_fetched.wait.assert_awaited_once() assembler.message_fetched.clear.assert_called_once()
def test_decompress_max_size(self): frame = Frame(True, OP_TEXT, ("a" * 20).encode("utf-8")) enc_frame = self.extension.encode(frame) self.assertEqual(enc_frame.data, b"JL\xc4\x04\x00\x00") with self.assertRaises(PayloadTooBig): self.extension.decode(enc_frame, max_size=10)
async def test_ws_frame_put_not_fetched(opcode): assembler = WebsocketFrameAssembler(Mock()) assembler.message_fetched.set() message = re.escape( "Websocket put() got a new message when the previous message was " "not yet fetched." ) with pytest.raises(ServerError, match=message): await assembler.put(Frame(opcode, b""))
async def test_ws_frame_put_message_complete(opcode): assembler = WebsocketFrameAssembler(Mock()) assembler.message_complete.set() message = re.escape( "Websocket put() got a new message when a message was " "already in its chamber." ) with pytest.raises(ServerError, match=message): await assembler.put(Frame(opcode, b""))
async def test_ws_frame_put_message_into_queue(opcode): assembler = WebsocketFrameAssembler(Mock()) assembler.chunks_queue = AsyncMock(spec=Queue) assembler.message_fetched = AsyncMock() assembler.message_fetched.is_set = Mock(return_value=False) await assembler.put(Frame(opcode, b"foo")) assembler.chunks_queue.put.has_calls( call(b"foo"), call(None), )
def test_encode_decode_fragmented_binary_frame(self): frame1 = Frame(OP_TEXT, b"tea ", fin=False) frame2 = Frame(OP_CONT, b"time") enc_frame1 = self.extension.encode(frame1) enc_frame2 = self.extension.encode(frame2) self.assertEqual( enc_frame1, dataclasses.replace(frame1, rsv1=True, data=b"*IMT\x00\x00\x00\x00\xff\xff"), ) self.assertEqual( enc_frame2, dataclasses.replace(frame2, data=b"*\xc9\xccM\x05\x00"), ) dec_frame1 = self.extension.decode(enc_frame1) dec_frame2 = self.extension.decode(enc_frame2) self.assertEqual(dec_frame1, frame1) self.assertEqual(dec_frame2, frame2)
def test_local_no_context_takeover(self): # No context takeover when encoding and decoding messages. self.extension = PerMessageDeflate(True, True, 15, 15) frame = Frame(True, OP_TEXT, "café".encode("utf-8")) enc_frame1 = self.extension.encode(frame) enc_frame2 = self.extension.encode(frame) self.assertEqual(enc_frame1.data, b"JNL;\xbc\x12\x00") self.assertEqual(enc_frame2.data, b"JNL;\xbc\x12\x00") dec_frame1 = self.extension.decode(enc_frame1) dec_frame2 = self.extension.decode(enc_frame2) self.assertEqual(dec_frame1, frame) self.assertEqual(dec_frame2, frame)
def test_remote_no_context_takeover(self): # No context takeover when decoding messages. self.extension = PerMessageDeflate(True, False, 15, 15) frame = Frame(True, OP_TEXT, "café".encode("utf-8")) enc_frame1 = self.extension.encode(frame) enc_frame2 = self.extension.encode(frame) self.assertEqual(enc_frame1.data, b"JNL;\xbc\x12\x00") self.assertEqual(enc_frame2.data, b"J\x06\x11\x00\x00") dec_frame1 = self.extension.decode(enc_frame1) self.assertEqual(dec_frame1, frame) with self.assertRaises(zlib.error) as exc: self.extension.decode(enc_frame2) self.assertIn("invalid distance too far back", str(exc.exception))
def test_encode_decode_fragmented_binary_frame(self): frame1 = Frame(False, OP_TEXT, b"tea ") frame2 = Frame(True, OP_CONT, b"time") enc_frame1 = self.extension.encode(frame1) enc_frame2 = self.extension.encode(frame2) self.assertEqual( enc_frame1, frame1._replace(rsv1=True, data=b"*IMT\x00\x00\x00\x00\xff\xff")) self.assertEqual(enc_frame2, frame2._replace(data=b"*\xc9\xccM\x05\x00")) dec_frame1 = self.extension.decode(enc_frame1) dec_frame2 = self.extension.decode(enc_frame2) self.assertEqual(dec_frame1, frame1) self.assertEqual(dec_frame2, frame2)
def test_no_encode_decode_close_frame(self): frame = Frame(True, OP_CLOSE, serialize_close(1000, "")) self.assertEqual(self.extension.encode(frame), frame) self.assertEqual(self.extension.decode(frame), frame)
def test_no_encode_decode_pong_frame(self): frame = Frame(True, OP_PONG, b"") self.assertEqual(self.extension.encode(frame), frame) self.assertEqual(self.extension.decode(frame), frame)
async def test_ws_frame_put_not_fin(opcode): assembler = WebsocketFrameAssembler(Mock()) retval = await assembler.put(Frame(opcode, b"foo", fin=False)) assert retval is None
async def test_ws_frame_put_skip_ctrl(opcode): assembler = WebsocketFrameAssembler(Mock()) retval = await assembler.put(Frame(opcode, b"")) assert retval is None
def test_bypass_handshake(self): server = ServerConnection(state=OPEN) server.receive_data(b"\x81\x86\x00\x00\x00\x00Hello!") [frame] = server.events_received() self.assertEqual(frame, Frame(OP_TEXT, b"Hello!"))
def test_no_decode_text_frame(self): frame = Frame(True, OP_TEXT, "café".encode("utf-8")) # Try decoding a frame that wasn't encoded. self.assertEqual(self.extension.decode(frame), frame)
def test_no_decode_binary_frame(self): frame = Frame(True, OP_TEXT, b"tea") # Try decoding a frame that wasn't encoded. self.assertEqual(self.extension.decode(frame), frame)
def test_bypass_handshake(self): client = ClientConnection("ws://example.com/test", state=OPEN) client.receive_data(b"\x81\x06Hello!") [frame] = client.events_received() self.assertEqual(frame, Frame(OP_TEXT, b"Hello!"))