def test_decompressor_reset(self, client: bool, no_context_takeover: bool) -> None: if client: args = {"server_no_context_takeover": no_context_takeover} else: args = {"client_no_context_takeover": no_context_takeover} ext = wpext.PerMessageDeflate(**args) ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) result = ext.frame_inbound_header(proto, fp.Opcode.BINARY, fp.RsvBits(True, False, False), 0) assert isinstance(result, fp.RsvBits) assert result.rsv1 assert ext._decompressor is not None result2 = ext.frame_inbound_complete(proto, True) assert not isinstance(result2, fp.CloseReason) if no_context_takeover: assert ext._decompressor is None else: assert ext._decompressor is not None result3 = ext.frame_inbound_header(proto, fp.Opcode.BINARY, fp.RsvBits(True, False, False), 0) assert isinstance(result3, fp.RsvBits) assert result3.rsv1 assert ext._decompressor is not None
def test_client_decompress_after_uncompressible_frame( self, client: bool) -> None: ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) # A PING frame result = ext.frame_inbound_header(proto, fp.Opcode.PING, fp.RsvBits(False, False, False), 0) result2 = ext.frame_inbound_payload_data(proto, b"") assert not isinstance(result2, fp.CloseReason) assert ext.frame_inbound_complete(proto, True) is None # A compressed TEXT frame payload = b"x" * 23 compressed_payload = b"\xaa\xa8\xc0\n\x00\x00" result3 = ext.frame_inbound_header( proto, fp.Opcode.TEXT, fp.RsvBits(True, False, False), len(compressed_payload), ) assert isinstance(result3, fp.RsvBits) assert result3.rsv1 result4 = ext.frame_inbound_payload_data(proto, compressed_payload) assert result4 == payload result5 = ext.frame_inbound_complete(proto, True) assert not isinstance(result5, fp.CloseReason)
def test_client_inbound_compressed_multiple_data_frames(self, client): payload = b'x' * 23 compressed_payload = b'\xaa\xa8\xc0\n\x00\x00' split = 3 data = b'' ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) result = ext.frame_inbound_header(proto, fp.Opcode.BINARY, fp.RsvBits(True, False, False), split) assert result.rsv1 result = ext.frame_inbound_payload_data(proto, compressed_payload[:split]) assert not isinstance(result, fp.CloseReason) data += result assert ext.frame_inbound_complete(proto, False) is None result = ext.frame_inbound_header(proto, fp.Opcode.CONTINUATION, fp.RsvBits(False, False, False), len(compressed_payload) - split) assert result.rsv1 result = ext.frame_inbound_payload_data(proto, compressed_payload[split:]) assert not isinstance(result, fp.CloseReason) data += result result = ext.frame_inbound_complete(proto, True) assert not isinstance(result, fp.CloseReason) data += result assert data == payload
def test_compressor_reset(self, client: bool, no_context_takeover: bool) -> None: if client: args = {"client_no_context_takeover": no_context_takeover} else: args = {"server_no_context_takeover": no_context_takeover} ext = wpext.PerMessageDeflate(**args) ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) rsv = fp.RsvBits(False, False, False) rsv, data = ext.frame_outbound(proto, fp.Opcode.BINARY, rsv, b"", False) assert rsv.rsv1 is True assert ext._compressor is not None rsv = fp.RsvBits(False, False, False) rsv, data = ext.frame_outbound(proto, fp.Opcode.CONTINUATION, rsv, b"", True) assert rsv.rsv1 is False if no_context_takeover: assert ext._compressor is None else: assert ext._compressor is not None rsv = fp.RsvBits(False, False, False) rsv, data = ext.frame_outbound(proto, fp.Opcode.BINARY, rsv, b"", False) assert rsv.rsv1 is True assert ext._compressor is not None
def test_inbound_bad_zlib_decoder_end_state( self, monkeypatch: MonkeyPatch) -> None: 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 class FailDecompressor: def decompress(self, data: bytes) -> bytes: return b"" def flush(self) -> None: raise zlib.error() monkeypatch.setattr(ext, "_decompressor", FailDecompressor()) result2 = ext.frame_inbound_complete(proto, True) assert result2 is fp.CloseReason.INVALID_FRAME_PAYLOAD_DATA
def frame_outbound(self, proto, opcode, rsv, data, fin): if opcode is fp.Opcode.TEXT: rsv = fp.RsvBits(rsv.rsv1, rsv.rsv2, True) self._outbound_rsv_bit_set = True if fin and self._outbound_rsv_bit_set: data += u"®".encode("utf-8") self._outbound_rsv_bit_set = False return rsv, data
def test_frame_outbound(self) -> None: ext = wpext.Extension() rsv = fp.RsvBits(True, True, True) data = b"" assert ext.frame_outbound(None, None, rsv, data, None) == ( # type: ignore rsv, data, )
def test_outbound_compress_multiple_frames(self, client: bool) -> None: ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) rsv = fp.RsvBits(False, False, False) payload = b"x" * 23 split = 12 compressed_payload = b"\xaa\xa8\xc0\n\x00\x00" rsv, data = ext.frame_outbound(proto, fp.Opcode.BINARY, rsv, payload[:split], False) assert rsv.rsv1 is True rsv = fp.RsvBits(False, False, False) rsv, more_data = ext.frame_outbound(proto, fp.Opcode.CONTINUATION, rsv, payload[split:], True) assert rsv.rsv1 is False assert data + more_data == compressed_payload
def test_inbound_compressed_continuation_frame(self) -> None: 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.CONTINUATION, fp.RsvBits(True, False, False), len(payload)) assert result == fp.CloseReason.PROTOCOL_ERROR
def test_outbound_uncompressible_opcode(self) -> None: ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=True, extensions=[ext]) rsv = fp.RsvBits(False, False, False) payload = b"x" * 23 rsv, data = ext.frame_outbound(proto, fp.Opcode.PING, rsv, payload, True) assert rsv.rsv1 is False assert data == payload
def frame_inbound_header( self, proto: Union[fp.FrameDecoder, fp.FrameProtocol], opcode: fp.Opcode, rsv: fp.RsvBits, payload_length: int, ) -> Union[fp.CloseReason, fp.RsvBits]: self._inbound_header_called = True if opcode is fp.Opcode.PONG: return fp.CloseReason.MANDATORY_EXT self._inbound_rsv_bit_set = rsv.rsv3 return fp.RsvBits(False, False, True)
def test_outbound_compress_single_frame(self, client: bool) -> None: ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) rsv = fp.RsvBits(False, False, False) payload = b"x" * 23 compressed_payload = b"\xaa\xa8\xc0\n\x00\x00" rsv, data = ext.frame_outbound(proto, fp.Opcode.BINARY, rsv, payload, True) assert rsv.rsv1 is True assert data == compressed_payload
def test_inbound_bad_zlib_payload(self): 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 result.rsv1 result = ext.frame_inbound_payload_data(proto, compressed_payload) assert result is fp.CloseReason.INVALID_FRAME_PAYLOAD_DATA
def frame_outbound( self, proto: Union[fp.FrameDecoder, fp.FrameProtocol], opcode: fp.Opcode, rsv: fp.RsvBits, data: bytes, fin: bool, ) -> Tuple[fp.RsvBits, bytes]: if opcode is fp.Opcode.TEXT: rsv = fp.RsvBits(rsv.rsv1, rsv.rsv2, True) self._outbound_rsv_bit_set = True if fin and self._outbound_rsv_bit_set: data += "®".encode("utf-8") self._outbound_rsv_bit_set = False return rsv, data
def test_client_inbound_compressed_single_data_frame(self, client): payload = b'x' * 23 compressed_payload = b'\xaa\xa8\xc0\n\x00\x00' ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=client, extensions=[ext]) result = ext.frame_inbound_header(proto, fp.Opcode.BINARY, fp.RsvBits(True, False, False), len(compressed_payload)) assert result.rsv1 data = ext.frame_inbound_payload_data(proto, compressed_payload) data += ext.frame_inbound_complete(proto, True) assert data == payload
def test_inbound_uncompressed_data_frame(self) -> None: 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(False, False, False), len(payload)) assert result.rsv1 # type: ignore data = ext.frame_inbound_payload_data(proto, payload) assert data == payload assert ext.frame_inbound_complete(proto, True) is None
def test_client_inbound_compressed_single_data_frame(self, client: bool) -> None: payload = b"x" * 23 compressed_payload = b"\xaa\xa8\xc0\n\x00\x00" ext = wpext.PerMessageDeflate() ext._enabled = True proto = fp.FrameProtocol(client=client, 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 data = ext.frame_inbound_payload_data(proto, compressed_payload) assert isinstance(data, bytes) data2 = ext.frame_inbound_complete(proto, True) assert isinstance(data2, bytes) assert data + data2 == payload
def test_inbound_bad_zlib_decoder_end_state(self, monkeypatch): 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 result.rsv1 class FailDecompressor(object): def decompress(self, data): return b'' def flush(self): raise zlib.error() monkeypatch.setattr(ext, '_decompressor', FailDecompressor()) result = ext.frame_inbound_complete(proto, True) assert result is fp.CloseReason.INVALID_FRAME_PAYLOAD_DATA
def test_frame_inbound_header(self) -> None: ext = wpext.Extension() result = ext.frame_inbound_header(None, None, None, None) # type: ignore[arg-type] assert result == fp.RsvBits(False, False, False)
def test_frame_outbound(self): ext = wpext.Extension() rsv = fp.RsvBits(True, True, True) data = object() assert ext.frame_outbound(None, None, rsv, data, None) == (rsv, data)
def test_frame_inbound_header(self): ext = wpext.Extension() result = ext.frame_inbound_header(None, None, None, None) assert result == fp.RsvBits(False, False, False)
def frame_inbound_header(self, proto, opcode, rsv, payload_length): self._inbound_header_called = True if opcode is fp.Opcode.PONG: return fp.CloseReason.MANDATORY_EXT self._inbound_rsv_bit_set = rsv.rsv3 return fp.RsvBits(False, False, True)