Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_push_promise_frame_flags(self):
f = PushPromiseFrame(1)
flags = f.parse_flags(0xFF)
assert flags == set(['END_HEADERS', 'PADDED'])
def test_push_promise_frame_with_no_length_parses(self):
# Fixes issue with empty data frames raising InvalidPaddingError.
f = PushPromiseFrame(1, 2)
f.data = b''
data = f.serialize()
new_frame = decode_frame(data)
assert new_frame.data == b''
def build_push_promise_frame(self,
stream_id,
promised_stream_id,
headers,
flags=[]):
"""
Builds a single PUSH_PROMISE frame.
"""
f = PushPromiseFrame(stream_id)
f.promised_stream_id = promised_stream_id
f.data = self.encoder.encode(headers)
f.flags = set(flags)
f.flags.add('END_HEADERS')
return f
def test_push_promise_frame_invalid(self):
data = PushPromiseFrame(1, 0).serialize()
with pytest.raises(InvalidFrameError):
decode_frame(data)
data = PushPromiseFrame(1, 3).serialize()
with pytest.raises(InvalidFrameError):
decode_frame(data)
c = h2.connection.H2Connection()
c.initiate_connection()
c.send_headers(
stream_id=1, headers=self.request_header_block
)
c.clear_outbound_data_buffer()
f = frame_factory.build_headers_frame(
self.response_header_block + self.first_header_block
)
data = f.serialize()
c.receive_data(data)
# Build the attack payload. We need to shrink it by four bytes because
# the promised_stream_id consumes four bytes of body.
attack_frame = hyperframe.frame.PushPromiseFrame(stream_id=3)
attack_frame.promised_stream_id = 2
attack_frame.data = self.second_header_block[:-4]
attack_frame.flags.add('END_HEADERS')
data = attack_frame.serialize()
with pytest.raises(h2.exceptions.DenialOfServiceError):
c.receive_data(data)
expected_frame = frame_factory.build_goaway_frame(
last_stream_id=0, error_code=h2.errors.ErrorCodes.ENHANCE_YOUR_CALM
)
assert c.data_to_send() == expected_frame.serialize()
def test_push_promise_frame_invalid(self):
data = PushPromiseFrame(1, 0).serialize()
with pytest.raises(InvalidFrameError):
decode_frame(data)
data = PushPromiseFrame(1, 3).serialize()
with pytest.raises(InvalidFrameError):
decode_frame(data)
def build_push_promise_frame(self,
stream_id,
promised_stream_id,
headers,
flags=[]):
"""
Builds a single PUSH_PROMISE frame.
"""
f = PushPromiseFrame(stream_id)
f.promised_stream_id = promised_stream_id
f.data = self.encoder.encode(headers)
f.flags = set(flags)
f.flags.add('END_HEADERS')
return f
def push_stream_in_band(self, related_stream_id, headers, encoder):
"""
Returns a list of PUSH_PROMISE/CONTINUATION frames to emit as a pushed
stream header. Called on the stream that has the PUSH_PROMISE frame
sent on it.
"""
self.config.logger.debug("Push stream %r", self)
# Because encoding headers makes an irreversible change to the header
# compression context, we make the state transition *first*.
events = self.state_machine.process_input(
StreamInputs.SEND_PUSH_PROMISE
)
ppf = PushPromiseFrame(self.stream_id)
ppf.promised_stream_id = related_stream_id
hdr_validation_flags = self._build_hdr_validation_flags(events)
frames = self._build_headers_frames(
headers, encoder, ppf, hdr_validation_flags
)
return frames
# Also used to determine whether we should consider a frame received
# while a stream is closed as either a stream error or a connection
# error.
self._closed_streams = SizeLimitDict(
size_limit=self.MAX_CLOSED_STREAMS
)
# The flow control window manager for the connection.
self._inbound_flow_control_window_manager = WindowManager(
max_window_size=self.local_settings.initial_window_size
)
# When in doubt use dict-dispatch.
self._frame_dispatch_table = {
HeadersFrame: self._receive_headers_frame,
PushPromiseFrame: self._receive_push_promise_frame,
SettingsFrame: self._receive_settings_frame,
DataFrame: self._receive_data_frame,
WindowUpdateFrame: self._receive_window_update_frame,
PingFrame: self._receive_ping_frame,
RstStreamFrame: self._receive_rst_stream_frame,
PriorityFrame: self._receive_priority_frame,
GoAwayFrame: self._receive_goaway_frame,
ContinuationFrame: self._receive_naked_continuation,
AltSvcFrame: self._receive_alt_svc_frame,
ExtensionFrame: self._receive_unknown_frame
}
self._headers_buffer.append(f)
if len(self._headers_buffer) > CONTINUATION_BACKLOG:
raise ProtocolError("Too many continuation frames received.")
# If this is the end of the header block, then we want to build a
# mutant HEADERS frame that's massive. Use the original one we got,
# then set END_HEADERS and set its data appopriately. If it's not
# the end of the block, lose the current frame: we can't yield it.
if 'END_HEADERS' in f.flags:
f = self._headers_buffer[0]
f.flags.add('END_HEADERS')
f.data = b''.join(x.data for x in self._headers_buffer)
self._headers_buffer = []
else:
f = None
elif (isinstance(f, (HeadersFrame, PushPromiseFrame)) and
'END_HEADERS' not in f.flags):
# This is the start of a headers block! Save the frame off and then
# act like we didn't receive one.
self._headers_buffer.append(f)
f = None
return f