Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def process_input(self, input_):
"""
Process a specific input in the state machine.
"""
if not isinstance(input_, StreamInputs):
raise ValueError("Input must be an instance of StreamInputs")
try:
func, target_state = _transitions[(self.state, input_)]
except KeyError:
old_state = self.state
self.state = StreamState.CLOSED
raise ProtocolError(
"Invalid input %s in state %s" % (input_, old_state)
)
else:
previous_state = self.state
self.state = target_state
if func is not None:
try:
return func(self, previous_state)
except ProtocolError:
self.state = StreamState.CLOSED
raise
except AssertionError as e: # pragma: no cover
self.state = StreamState.CLOSED
raise ProtocolError(e)
return []
# ProtocolError. If the frame *is* valid, append it to the header
# buffer.
if self._headers_buffer:
stream_id = self._headers_buffer[0].stream_id
valid_frame = (
f is not None and
isinstance(f, ContinuationFrame) and
f.stream_id == stream_id
)
if not valid_frame:
raise ProtocolError("Invalid frame during header block.")
# Append the frame to the buffer.
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.
def process_input(self, input_):
"""
Process a specific input in the state machine.
"""
if not isinstance(input_, ConnectionInputs):
raise ValueError("Input must be an instance of ConnectionInputs")
try:
func, target_state = self._transitions[(self.state, input_)]
except KeyError:
old_state = self.state
self.state = ConnectionState.CLOSED
raise ProtocolError(
"Invalid input %s in state %s" % (input_, old_state)
)
else:
self.state = target_state
if func is not None: # pragma: no cover
return func()
return []
def _add_frame_priority(frame, weight=None, depends_on=None, exclusive=None):
"""
Adds priority data to a given frame. Does not change any flags set on that
frame: if the caller is adding priority information to a HEADERS frame they
must set that themselves.
This method also deliberately sets defaults for anything missing.
This method validates the input values.
"""
# A stream may not depend on itself.
if depends_on == frame.stream_id:
raise ProtocolError(
"Stream %d may not depend on itself" % frame.stream_id
)
# Weight must be between 1 and 256.
if weight is not None:
if weight > 256 or weight < 1:
raise ProtocolError(
"Weight must be between 1 and 256, not %d" % weight
)
else:
# Weight is an integer between 1 and 256, but the byte only allows
# 0 to 255: subtract one.
weight -= 1
# Set defaults for anything not provided.
weight = weight if weight is not None else 15
# If we have not-None values for these variables, then we know we saw
# the corresponding header.
authority_present = (authority_header_val is not None)
host_present = (host_header_val is not None)
# It is an error for a request header block to contain neither
# an :authority header nor a Host header.
if not authority_present and not host_present:
raise ProtocolError(
"Request header block does not have an :authority or Host header."
)
# If we receive both headers, they should definitely match.
if authority_present and host_present:
if authority_header_val != host_header_val:
raise ProtocolError(
"Request header block has mismatched :authority and "
"Host headers: %r / %r"
% (authority_header_val, host_header_val)
)
def send_push_on_closed_stream(self, previous_state):
"""
Called when an attempt is made to push on an already-closed stream.
This essentially overrides the standard logic by providing a more
useful error message. It's necessary because simply indicating that the
stream is closed is not enough: there is now a new stream that is not
allowed to be there. The only recourse is to tear the whole connection
down.
"""
raise ProtocolError("Attempted to push on closed stream.")
"""
An action was attempted in violation of the HTTP/2 protocol.
"""
#: The error code corresponds to this kind of Protocol Error.
error_code = h2.errors.ErrorCodes.PROTOCOL_ERROR
class FrameTooLargeError(ProtocolError):
"""
The frame that we tried to send or that we received was too large.
"""
#: This error code that corresponds to this kind of Protocol Error.
error_code = h2.errors.ErrorCodes.FRAME_SIZE_ERROR
class FrameDataMissingError(ProtocolError):
"""
The frame that we received is missing some data.
.. versionadded:: 2.0.0
"""
#: The error code that corresponds to this kind of Protocol Error
error_code = h2.errors.ErrorCodes.FRAME_SIZE_ERROR
class TooManyStreamsError(ProtocolError):
"""
An attempt was made to open a stream that would lead to too many concurrent
streams.
"""
pass
def dataReceived(self, data):
if not self.known_proto:
self.known_proto = True
try:
events = self.conn.receive_data(data)
except ProtocolError:
if self.conn.data_to_send:
self.transport.write(self.conn.data_to_send())
self.transport.loseConnection()
else:
for event in events:
if isinstance(event, RequestReceived):
self.requestReceived(event.headers, event.stream_id)
elif isinstance(event, DataReceived):
self.dataFrameReceived(event.stream_id)
elif isinstance(event, WindowUpdated):
self.windowUpdated(event)
if self.conn.data_to_send:
self.transport.write(self.conn.data_to_send())
def inner():
for header in headers:
if header[0] in (b':path', u':path'):
if not header[1]:
raise ProtocolError("An empty :path header is forbidden")
yield header