def test_response_huffman_decoder(): decoder = HuffmanDecoder(RESPONSE_CODES,RESPONSE_CODES_LENGTH) assert decoder.decode(b'\x40\x9f') == b"302" assert decoder.decode(b'\xc3\x1b\x39\xbf\x38\x7f') == b"private" assert decoder.decode(b'\xa2\xfb\xa2\x03\x20\xf2\xab\x30\x31\x24\x01\x8b\x49\x0d\x32\x09\xe8\x77') == b"Mon, 21 Oct 2013 20:13:21 GMT" assert decoder.decode(b'\xe3\x9e\x78\x64\xdd\x7a\xfd\x3d\x3d\x24\x87\x47\xdb\x87\x28\x49\x55\xf6\xff') == b"https://www.example.com" assert decoder.decode(b'\xdf\x7d\xfb\x36\xd3\xd9\xe1\xfc\xfc\x3f\xaf\xe7\xab\xfc\xfe\xfc\xbf\xaf\x3e\xdf\x2f\x97\x7f\xd3\x6f\xf7\xfd\x79\xf6\xf9\x77\xfd\x3d\xe1\x6b\xfa\x46\xfe\x10\xd8\x89\x44\x7d\xe1\xce\x18\xe5\x65\xf7\x6c\x2f') == b"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"
def test_response_huffman_decoder(self): decoder = HuffmanDecoder(RESPONSE_CODES,RESPONSE_CODES_LENGTH) assert decoder.decode(b'\x40\x9f') == b"302" assert decoder.decode(b'\xc3\x1b\x39\xbf\x38\x7f') == b"private" assert decoder.decode(b'\xa2\xfb\xa2\x03\x20\xf2\xab\x30\x31\x24\x01\x8b\x49\x0d\x32\x09\xe8\x77') == b"Mon, 21 Oct 2013 20:13:21 GMT" assert decoder.decode(b'\xe3\x9e\x78\x64\xdd\x7a\xfd\x3d\x3d\x24\x87\x47\xdb\x87\x28\x49\x55\xf6\xff') == b"https://www.example.com" assert decoder.decode(b'\xdf\x7d\xfb\x36\xd3\xd9\xe1\xfc\xfc\x3f\xaf\xe7\xab\xfc\xfe\xfc\xbf\xaf\x3e\xdf\x2f\x97\x7f\xd3\x6f\xf7\xfd\x79\xf6\xf9\x77\xfd\x3d\xe1\x6b\xfa\x46\xfe\x10\xd8\x89\x44\x7d\xe1\xce\x18\xe5\x65\xf7\x6c\x2f') == b"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"
def test_request_huffman_decoder(self): decoder = HuffmanDecoder(REQUEST_CODES, REQUEST_CODES_LENGTH) assert decoder.decode(b'\xdb\x6d\x88\x3e\x68\xd1\xcb\x12\x25\xba\x7f' ) == b"www.example.com" assert decoder.decode(b'\x63\x65\x4a\x13\x98\xff') == b"no-cache" assert decoder.decode( b'\x4e\xb0\x8b\x74\x97\x90\xfa\x7f') == b"custom-key" assert decoder.decode( b'\x4e\xb0\x8b\x74\x97\x9a\x17\xa8\xff') == b"custom-value"
def test_can_decode_a_story(self, story): d = Decoder() # We support draft 5 of the HPACK spec. assert story['draft'] == 5 if story['context'] == 'request': d.huffman_coder = HuffmanDecoder(REQUEST_CODES, REQUEST_CODES_LENGTH) for case in story['cases']: d.header_table_size = case['header_table_size'] decoded_headers = d.decode(unhexlify(case['wire'])) # The correct headers are a list of dicts, which is annoying. correct_headers = {(item[0], item[1]) for header in case['headers'] for item in header.items()} assert correct_headers == decoded_headers
def test_can_encode_a_story_with_huffman(self, raw_story): d = Decoder() e = Encoder() if raw_story['context'] == 'request': d.huffman_coder = HuffmanDecoder(REQUEST_CODES, REQUEST_CODES_LENGTH) else: e.huffman_coder = HuffmanEncoder(RESPONSE_CODES, RESPONSE_CODES_LENGTH) for case in raw_story['cases']: # The input headers are a list of dicts, which is annoying. input_headers = {(item[0], item[1]) for header in case['headers'] for item in header.items()} encoded = e.encode(input_headers, huffman=True) decoded_headers = d.decode(encoded) assert input_headers == decoded_headers
def test_request_examples_with_huffman(self): """ This section shows the same examples as the previous section, but using Huffman encoding for the literal values. """ d = Decoder() # Patch the decoder to use the Request Huffman tables, not the Response # ones. d.huffman_coder = HuffmanDecoder(REQUEST_CODES, REQUEST_CODES_LENGTH) first_header_set = [ ( ':method', 'GET', ), ( ':scheme', 'http', ), ( ':path', '/', ), (':authority', 'www.example.com'), ] first_header_table = first_header_set[::-1] first_data = ( b'\x82\x87\x86\x04\x8b\xdb\x6d\x88\x3e\x68\xd1\xcb\x12\x25\xba\x7f' ) assert d.decode(first_data) == set(first_header_set) assert list(d.header_table) == [(n.encode('utf-8'), v.encode('utf-8')) for n, v in first_header_table] # This request takes advantage of the differential encoding of header # sets. second_header_set = [ ( ':method', 'GET', ), ( ':scheme', 'http', ), ( ':path', '/', ), ( ':authority', 'www.example.com', ), ('cache-control', 'no-cache'), ] second_header_table = second_header_set[::-1] second_data = b'\x1b\x86\x63\x65\x4a\x13\x98\xff' assert d.decode(second_data) == set(second_header_set) assert list(d.header_table) == [(n.encode('utf-8'), v.encode('utf-8')) for n, v in second_header_table] # This request has not enough headers in common with the previous # request to take advantage of the differential encoding. Therefore, # the reference set is emptied before encoding the header fields. third_header_set = [ ( ':method', 'GET', ), ( ':scheme', 'https', ), ( ':path', '/index.html', ), ( ':authority', 'www.example.com', ), ('custom-key', 'custom-value'), ] third_data = ( b'\x80\x85\x8c\x8b\x84\x00\x88\x4e\xb0\x8b\x74\x97\x90\xfa\x7f\x89' b'\x4e\xb0\x8b\x74\x97\x9a\x17\xa8\xff') assert d.decode(third_data) == set(third_header_set) # Don't check the header table here, it's just too complex to be # reliable. Check its length though. assert len(d.header_table) == 8
def test_request_huffman_decoder(self): decoder = HuffmanDecoder(REQUEST_CODES,REQUEST_CODES_LENGTH) assert decoder.decode(b'\xdb\x6d\x88\x3e\x68\xd1\xcb\x12\x25\xba\x7f') == b"www.example.com" assert decoder.decode(b'\x63\x65\x4a\x13\x98\xff') == b"no-cache" assert decoder.decode(b'\x4e\xb0\x8b\x74\x97\x90\xfa\x7f') == b"custom-key" assert decoder.decode(b'\x4e\xb0\x8b\x74\x97\x9a\x17\xa8\xff') == b"custom-value"
def test_eos_terminates_decode_request(self): decoder = HuffmanDecoder(REQUEST_CODES,REQUEST_CODES_LENGTH) assert decoder.decode(b'\xff\xff\xf7\x00') == b''
def test_eos_terminates_decode_response(self): decoder = HuffmanDecoder(RESPONSE_CODES,RESPONSE_CODES_LENGTH) assert decoder.decode(b'\xff\xff\xdd\xff\xff\xff') == b''
def test_huffman_decoder_throws_useful_exceptions(self): # Specify a HuffmanDecoder with no values in it, then attempt to decode # using it. d = HuffmanDecoder([], []) with pytest.raises(HPACKDecodingError): d.decode(b'test')
def test_huffman_decoder_throws_useful_exceptions(self): # Specify a HuffmanDecoder with no values in it, then attempt to decode # using it. d = HuffmanDecoder([], []) with pytest.raises(HPACKDecodingError): d.decode(b"test")
def test_request_huffman_decoder(self): decoder = HuffmanDecoder(REQUEST_CODES,REQUEST_CODES_LENGTH) assert decoder.decode(b'\xf1\xe3\xc2\xe5\xf2:k\xa0\xab\x90\xf4\xff') == b"www.example.com" assert decoder.decode(b'\xa8\xeb\x10d\x9c\xbf') == b"no-cache" assert decoder.decode(b'%\xa8I\xe9[\xa9}\x7f') == b"custom-key" assert decoder.decode(b'%\xa8I\xe9[\xb8\xe8\xb4\xbf') == b"custom-value"
def test_eos_terminates_decode_request(self): decoder = HuffmanDecoder(REQUEST_CODES,REQUEST_CODES_LENGTH) assert decoder.decode(b'\xff\xff\xff\xfc') == b''
def test_eos_terminates_decode_response(self): decoder = HuffmanDecoder(RESPONSE_CODES, RESPONSE_CODES_LENGTH) assert decoder.decode(b'\xff\xff\xdd\xff\xff\xff') == b''