Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
sock = listener.accept()[0]
# Do the handshake: conn header, settings, send settings, recv ack.
frame_buffer.add_data(receive_preamble(sock))
# Now expect some data. One headers frame and one data frame.
req_wait = True
while req_wait:
frame_buffer.add_data(sock.recv(65535))
with reusable_frame_buffer(frame_buffer) as fr:
for f in fr:
if isinstance(f, DataFrame):
req_wait = False
# Respond!
h = HeadersFrame(1)
h.data = self.get_encoder().encode(
[
(':status', 200),
('content-type', 'not/real'),
('content-length', 20),
]
)
h.flags.add('END_HEADERS')
sock.send(h.serialize())
d = DataFrame(1)
d.data = b'1234567890' * 2
d.flags.add('END_STREAM')
sock.send(d.serialize())
# keep the socket open for clean shutdown
recv_event.wait(5)
def add_headers_frame(self, stream_id, headers, end_block=True,
end_stream=False):
frame = HeadersFrame(stream_id)
frame.data = self.encoder.encode(headers)
if end_block:
frame.flags.add('END_HEADERS')
if end_stream:
frame.flags.add('END_STREAM')
self.frames.append(frame)
def create_socket(status_code, data, headers):
# test helper method
encoder = Encoder()
h1 = HeadersFrame(1)
h1.data = encoder.encode(
[(':status', status_code), ('content-length', len(data))] + headers
)
h1.flags |= set(['END_HEADERS'])
d1 = DataFrame(1)
d1.data = data
d2 = DataFrame(1)
d2.flags |= set(['END_STREAM'])
content = b''.join(f.serialize() for f in [h1, d1, d2])
buffer = BytesIO(content)
return DummySocket(buffer)
def build_headers_frame(self,
headers,
flags=[],
stream_id=1,
**priority_kwargs):
"""
Builds a single valid headers frame out of the contained headers.
"""
f = HeadersFrame(stream_id)
f.data = self.encoder.encode(headers)
f.flags.add('END_HEADERS')
for flag in flags:
f.flags.add(flag)
for k, v in priority_kwargs.items():
setattr(f, k, v)
return f
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
buffer.max_frame_size = 65535
data = c.data_to_send()
buffer.add_data(data[:-1])
# Drain the buffer, confirming that it only provides a single frame
# (the settings frame)
assert len(list(buffer)) == 1
# Get the cached frames.
frames = buffer._headers_buffer
# Split the frames up.
headers_frame = frames[0]
continuation_frames = frames[1:]
assert isinstance(headers_frame, hyperframe.frame.HeadersFrame)
assert all(
map(
lambda f: isinstance(f, hyperframe.frame.ContinuationFrame),
continuation_frames)
)
assert all(
map(lambda f: len(f.data) <= c.max_outbound_frame_size, frames)
)
assert frames[0].flags == {'END_STREAM'}
buffer.add_data(data[-1:])
headers = list(buffer)[0]
assert isinstance(headers, hyperframe.frame.HeadersFrame)
def test_connection_window_increments_appropriately(self, frame_buffer):
e = Encoder()
h = HeadersFrame(1)
h.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
h.flags = set(['END_HEADERS'])
d = DataFrame(1)
d.data = b'hi there sir'
d2 = DataFrame(1)
d2.data = b'hi there sir again'
d2.flags = set(['END_STREAM'])
sock = DummySocket()
sock.buffer = BytesIO(h.serialize() + d.serialize() + d2.serialize())
c = HTTP20Connection('www.google.com')
c._sock = sock
c.window_manager.window_size = 1000
c.window_manager.initial_window_size = 1000
c.request('GET', '/')
resp = c.get_response()
def test_read_headers_out_of_order(self):
# If header blocks aren't decoded in the same order they're received,
# regardless of the stream they belong to, the decoder state will
# become corrupted.
e = Encoder()
h1 = HeadersFrame(1)
h1.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
h1.flags |= set(['END_HEADERS', 'END_STREAM'])
h3 = HeadersFrame(3)
h3.data = e.encode([(':status', 200), ('content-type', 'baz/qux')])
h3.flags |= set(['END_HEADERS', 'END_STREAM'])
sock = DummySocket()
sock.buffer = BytesIO(h1.serialize() + h3.serialize())
c = HTTP20Connection('www.google.com')
c._sock = sock
r1 = c.request('GET', '/a')
r3 = c.request('GET', '/b')
assert c.get_response(r3).headers == HTTPHeaderMap(
[('content-type', 'baz/qux')]
)
assert c.get_response(r1).headers == HTTPHeaderMap(
[('content-type', 'foo/bar')]
)
flags = self.flag_byte
header = _STRUCT_HBBBL.pack(
(self.body_len >> 8) & 0xFFFF, # Length spread over top 24 bits
self.body_len & 0xFF,
self.type,
flags,
self.stream_id & 0x7FFFFFFF # Stream ID is 32 bits.
)
return header + self.body
_FRAME_CLASSES = [
DataFrame,
HeadersFrame,
PriorityFrame,
RstStreamFrame,
SettingsFrame,
PushPromiseFrame,
PingFrame,
GoAwayFrame,
WindowUpdateFrame,
ContinuationFrame,
AltSvcFrame,
]
#: FRAMES maps the type byte for each frame to the class used to represent that
#: frame.
FRAMES = {cls.type: cls for cls in _FRAME_CLASSES}
def _receive_transmission(self, stream_id=None, include_body=True):
if not include_body:
raise NotImplementedError()
body_expected = True
header_blocks = b''
body = b''
while True:
frm = self.read_frame()
if (
(isinstance(frm, hyperframe.frame.HeadersFrame) or isinstance(frm, hyperframe.frame.ContinuationFrame)) and
(stream_id is None or frm.stream_id == stream_id)
):
stream_id = frm.stream_id
header_blocks += frm.data
if 'END_STREAM' in frm.flags:
body_expected = False
if 'END_HEADERS' in frm.flags:
break
else:
self._handle_unexpected_frame(frm)
while body_expected:
frm = self.read_frame()
if isinstance(frm, hyperframe.frame.DataFrame) and frm.stream_id == stream_id:
body += frm.data
if 'END_STREAM' in frm.flags: