Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
data.append(sock.recv(65535))
req_event.wait(5)
h = HeadersFrame(1)
h.data = self.get_encoder().encode(
[
(':status', 200),
('content-type', 'not/real'),
('content-length', 12),
('server', 'socket-level-server')
]
)
h.flags.add('END_HEADERS')
sock.send(h.serialize())
d = DataFrame(1)
d.data = b'thisisaproxy'
d.flags.add('END_STREAM')
sock.send(d.serialize())
recv_event.wait(5)
sock.close()
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 socket_handler(listener):
sock = listener.accept()[0]
# We should get one packet. Rather than respond to it, send a
# GOAWAY frame with error code 0 indicating clean shutdown.
sock.recv(65535)
# Now, send the shut down.
f = GoAwayFrame(0)
f.error_code = 0
sock.send(f.serialize())
# Wait for the message from the main thread.
recv_event.wait(5)
sock.close()
conn = self.get_connection()
conn.connect()
send_event.wait(5)
# Get the chunk of data after the preamble and decode it into frames.
# We actually expect two, but only the second one contains ENABLE_PUSH.
preamble_size = len(b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n')
data = data[0][preamble_size:]
frame_buffer.add_data(data)
frames = list(frame_buffer)
f = frames[1]
assert isinstance(f, SettingsFrame)
assert f.stream_id == 0
assert f.settings == {
SettingsFrame.ENABLE_PUSH: 0,
}
self.tear_down()
setting.new_value,
)
# HEADER_TABLE_SIZE changes by the remote part affect our encoder: cf.
# RFC 7540 Section 6.5.2.
if SettingCodes.HEADER_TABLE_SIZE in changes:
setting = changes[SettingCodes.HEADER_TABLE_SIZE]
self.encoder.header_table_size = setting.new_value
if SettingCodes.MAX_FRAME_SIZE in changes:
setting = changes[SettingCodes.MAX_FRAME_SIZE]
self.max_outbound_frame_size = setting.new_value
for stream in self.streams.values():
stream.max_outbound_frame_size = setting.new_value
f = SettingsFrame(0)
f.flags.add('ACK')
return [f]
:type settings_header: ``bytes``
:returns: For clients, a bytestring to put in the ``HTTP2-Settings``.
For servers, returns nothing.
:rtype: ``bytes`` or ``None``
"""
self.config.logger.debug(
"Upgrade connection. Current settings: %s", self.local_settings
)
frame_data = None
# Begin by getting the preamble in place.
self.initiate_connection()
if self.config.client_side:
f = SettingsFrame(0)
for setting, value in self.local_settings.items():
f.settings[setting] = value
frame_data = f.serialize_body()
frame_data = base64.urlsafe_b64encode(frame_data)
elif settings_header:
# We have a settings header from the client. This needs to be
# applied, but we want to throw away the ACK. We do this by
# inserting the data into a Settings frame and then passing it to
# the state machine, but ignoring the return value.
settings_header = base64.urlsafe_b64decode(settings_header)
f = SettingsFrame(0)
f.parse_body(settings_header)
self._receive_settings_frame(f)
# Set up appropriate state. Stream 1 in a half-closed state:
def socket_handler(listener):
sock = listener.accept()[0]
# Dispose of the first packet.
sock.recv(65535)
# Send a Settings frame that reduces the flow-control window to
# 64 bytes.
f = SettingsFrame(0)
f.settings[SettingsFrame.INITIAL_WINDOW_SIZE] = 64
sock.send(f.serialize())
# Grab three frames, the settings ACK, the initial headers frame,
# and the first data frame.
for x in range(0, 3):
data.append(sock.recv(65535))
# Send a WindowUpdate giving more window room to the stream.
f = WindowUpdateFrame(1)
f.window_increment = 64
sock.send(f.serialize())
# Send one that gives more room to the connection.
f = WindowUpdateFrame(0)
f.window_increment = 64
def sanity_check_data_frame(data_frame,
expected_flow_controlled_length,
expect_padded_flag,
expected_data_frame_pad_length):
"""
``data_frame`` is a frame of type ``hyperframe.frame.DataFrame``,
and the ``flags`` and ``flow_controlled_length`` of ``data_frame``
match expectations.
"""
assert isinstance(data_frame, hyperframe.frame.DataFrame)
assert data_frame.flow_controlled_length == expected_flow_controlled_length
if expect_padded_flag:
assert 'PADDED' in data_frame.flags
else:
assert 'PADDED' not in data_frame.flags
assert data_frame.pad_length == expected_data_frame_pad_length
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 test_body_length_behaves_correctly(self):
f = DataFrame(1)
f.data = b'\x01' * 300
# Initially the body length is zero. For now this is incidental, but
# I'm going to test it to ensure that the behaviour is codified. We
# should change this test if we change that.
assert f.body_len == 0
f.serialize()
assert f.body_len == 300