def get_encoder(self): """ Returns a HPACK encoder set up for responses. """ e = Encoder() e.huffman_coder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) return e
def socket_handler(listener): sock = listener.accept()[0] e = Encoder() e.huffman_coder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) # We get two messages for the connection open and then a HEADERS # frame. receive_preamble(sock) # Now, send the headers for the response. This response has no body. f = build_headers_frame([(':status', '200'), ('content-length', '0')], e) f.stream_id = 1 sock.send(f.serialize()) # Also send a data frame. f = DataFrame(1) f.data = b'have some data' sock.send(f.serialize()) # Now, send a headers frame again, containing trailing headers. f = build_headers_frame([('trailing', 'sure'), (':res', 'no')], e) f.flags.add('END_STREAM') f.stream_id = 1 sock.send(f.serialize()) # Wait for the message from the main thread. recv_event.wait() sock.close()
def build_headers_frame(headers): f = HeadersFrame(1) e = Encoder() e.huffman_coder = HuffmanEncoder(RESPONSE_CODES, RESPONSE_CODES_LENGTH) f.data = e.encode(headers) f.flags.add('END_HEADERS') return f
def test_response_huffman_encode(): encoder = HuffmanEncoder(RESPONSE_CODES, RESPONSE_CODES_LENGTH) assert encoder.encode(b"302") == (b'\x40\x9f') assert encoder.encode(b"private") == (b'\xc3\x1b\x39\xbf\x38\x7f') assert encoder.encode(b"Mon, 21 Oct 2013 20:13:21 GMT") == (b'\xa2\xfb\xa2\x03\x20\xf2\xab\x30\x31\x24\x01\x8b\x49\x0d\x32\x09\xe8\x77') assert encoder.encode(b"https://www.example.com") == (b'\xe3\x9e\x78\x64\xdd\x7a\xfd\x3d\x3d\x24\x87\x47\xdb\x87\x28\x49\x55\xf6\xff') assert encoder.encode(b"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1") == (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')
def build_headers_frame(headers, encoder=None): f = HeadersFrame(1) e = encoder if e is None: e = Encoder() e.huffman_coder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) f.data = e.encode(headers) f.flags.add('END_HEADERS') return f
def test_response_huffman_encode(self): encoder = HuffmanEncoder(RESPONSE_CODES, RESPONSE_CODES_LENGTH) assert encoder.encode(b"302") == (b'\x40\x9f') assert encoder.encode(b"private") == (b'\xc3\x1b\x39\xbf\x38\x7f') assert encoder.encode(b"Mon, 21 Oct 2013 20:13:21 GMT") == (b'\xa2\xfb\xa2\x03\x20\xf2\xab\x30\x31\x24\x01\x8b\x49\x0d\x32\x09\xe8\x77') assert encoder.encode(b"https://www.example.com") == (b'\xe3\x9e\x78\x64\xdd\x7a\xfd\x3d\x3d\x24\x87\x47\xdb\x87\x28\x49\x55\xf6\xff') assert encoder.encode(b"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1") == (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')
def test_request_huffman_encode(self): encoder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) assert encoder.encode(b"www.example.com") == ( b'\xdb\x6d\x88\x3e\x68\xd1\xcb\x12\x25\xba\x7f') assert encoder.encode(b"no-cache") == (b'\x63\x65\x4a\x13\x98\xff') assert encoder.encode(b"custom-key") == ( b'\x4e\xb0\x8b\x74\x97\x90\xfa\x7f') assert encoder.encode(b"custom-value") == ( b'\x4e\xb0\x8b\x74\x97\x9a\x17\xa8\xff')
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_huffman_encode(self): encoder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) assert encoder.encode(b"www.example.com") == (b'\xdb\x6d\x88\x3e\x68\xd1\xcb\x12\x25\xba\x7f') assert encoder.encode(b"no-cache") == (b'\x63\x65\x4a\x13\x98\xff') assert encoder.encode(b"custom-key") == (b'\x4e\xb0\x8b\x74\x97\x90\xfa\x7f') assert encoder.encode(b"custom-value") == (b'\x4e\xb0\x8b\x74\x97\x9a\x17\xa8\xff')
def test_request_huffman_encode(self): encoder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) assert encoder.encode(b"www.example.com") == (b'\xf1\xe3\xc2\xe5\xf2:k\xa0\xab\x90\xf4\xff') assert encoder.encode(b"no-cache") == (b'\xa8\xeb\x10d\x9c\xbf') assert encoder.encode(b"custom-key") == (b'%\xa8I\xe9[\xa9}\x7f') assert encoder.encode(b"custom-value") == (b'%\xa8I\xe9[\xb8\xe8\xb4\xbf')