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_base_frame_cant_serialize(self):
f = Frame(stream_id=0)
with pytest.raises(NotImplementedError):
f.serialize()
def test_base_frame_cant_parse_body(self):
data = b''
f = Frame(stream_id=0)
with pytest.raises(NotImplementedError):
f.parse_body(data)
def test_repr(self, monkeypatch):
f = Frame(stream_id=0)
monkeypatch.setattr(Frame, "serialize_body", lambda _: b"body")
assert repr(f) == "Frame(Stream: 0; Flags: None): 626f6479"
monkeypatch.setattr(Frame, "serialize_body", lambda _: b"A"*25)
assert repr(f) == (
"Frame(Stream: 0; Flags: None): {}...".format("41"*10)
)
def parse_body(self, data):
if len(data) != 4:
raise InvalidFrameError(
"RST_STREAM must have 4 byte body: actual length %s." %
len(data)
)
try:
self.error_code = _STRUCT_L.unpack(data)[0]
except struct.error: # pragma: no cover
raise InvalidFrameError("Invalid RST_STREAM body")
self.body_len = 4
class SettingsFrame(Frame):
"""
The SETTINGS frame conveys configuration parameters that affect how
endpoints communicate. The parameters are either constraints on peer
behavior or preferences.
Settings are not negotiated. Settings describe characteristics of the
sending peer, which are used by the receiving peer. Different values for
the same setting can be advertised by each peer. For example, a client
might set a high initial flow control window, whereas a server might set a
lower value to conserve resources.
"""
#: The flags defined for SETTINGS frames.
defined_flags = [Flag('ACK', 0x01)]
#: The type byte defined for SETTINGS frames.
type = 0x04
def parse_body(self, data):
try:
origin_len = _STRUCT_H.unpack(data[0:2])[0]
self.origin = data[2:2+origin_len].tobytes()
if len(self.origin) != origin_len:
raise InvalidFrameError("Invalid ALTSVC frame body.")
self.field = data[2+origin_len:].tobytes()
except (struct.error, ValueError):
raise InvalidFrameError("Invalid ALTSVC frame body.")
self.body_len = len(data)
class ExtensionFrame(Frame):
"""
ExtensionFrame is used to wrap frames which are not natively interpretable
by hyperframe.
Although certain byte prefixes are ordained by specification to have
certain contextual meanings, frames with other prefixes are not prohibited,
and may be used to communicate arbitrary meaning between HTTP/2 peers.
Thus, hyperframe, rather than raising an exception when such a frame is
encountered, wraps it in a generic frame to be properly acted upon by
upstream consumers which might have additional context on how to use it.
.. versionadded:: 5.0.0
"""
stream_association = _STREAM_ASSOC_EITHER
)
try:
self.window_increment = _STRUCT_L.unpack(data)[0]
except struct.error:
raise InvalidFrameError("Invalid WINDOW_UPDATE body")
if not 1 <= self.window_increment <= 2**31-1:
raise InvalidFrameError(
"WINDOW_UPDATE increment must be between 1 to 2^31-1"
)
self.body_len = 4
class HeadersFrame(Padding, Priority, Frame):
"""
The HEADERS frame carries name-value pairs. It is used to open a stream.
HEADERS frames can be sent on a stream in the "open" or "half closed
(remote)" states.
The HeadersFrame class is actually basically a data frame in this
implementation, because of the requirement to control the sizes of frames.
A header block fragment that doesn't fit in an entire HEADERS frame needs
to be followed with CONTINUATION frames. From the perspective of the frame
building code the header block is an opaque data segment.
"""
#: The flags defined for HEADERS frames.
defined_flags = [
Flag('END_STREAM', 0x01),
Flag('END_HEADERS', 0x04),
Flag('PADDED', 0x08),
data = self.opaque_data
data += b'\x00' * (8 - len(self.opaque_data))
return data
def parse_body(self, data):
if len(data) != 8:
raise InvalidFrameError(
"PING frame must have 8 byte length: got %s" % len(data)
)
self.opaque_data = data.tobytes()
self.body_len = 8
class GoAwayFrame(Frame):
"""
The GOAWAY frame informs the remote peer to stop creating streams on this
connection. It can be sent from the client or the server. Once sent, the
sender will ignore frames sent on new streams for the remainder of the
connection.
"""
#: The flags defined for GOAWAY frames.
defined_flags = []
#: The type byte defined for GOAWAY frames.
type = 0x07
stream_association = _STREAM_ASSOC_NO_STREAM
def __init__(self,
stream_id=0,
def serialize_body(self):
return self.serialize_priority_data()
def parse_body(self, data):
if len(data) > 5:
raise InvalidFrameError(
"PRIORITY must have 5 byte body: actual length %s." %
len(data)
)
self.parse_priority_data(data)
self.body_len = 5
class RstStreamFrame(Frame):
"""
The RST_STREAM frame allows for abnormal termination of a stream. When sent
by the initiator of a stream, it indicates that they wish to cancel the
stream or that an error condition has occurred. When sent by the receiver
of a stream, it indicates that either the receiver is rejecting the stream,
requesting that the stream be cancelled or that an error condition has
occurred.
"""
#: The flags defined for RST_STREAM frames.
defined_flags = []
#: The type byte defined for RST_STREAM frames.
type = 0x03
stream_association = _STREAM_ASSOC_HAS_STREAM
self.data = (
data[padding_data_length + 4:len(data)-self.pad_length].tobytes()
)
self.body_len = len(data)
if self.promised_stream_id == 0 or self.promised_stream_id % 2 != 0:
raise InvalidFrameError(
"Invalid PUSH_PROMISE promised stream id: %s" %
self.promised_stream_id
)
if self.pad_length and self.pad_length >= self.body_len:
raise InvalidPaddingError("Padding is too long.")
class PingFrame(Frame):
"""
The PING frame is a mechanism for measuring a minimal round-trip time from
the sender, as well as determining whether an idle connection is still
functional. PING frames can be sent from any endpoint.
"""
#: The flags defined for PING frames.
defined_flags = [Flag('ACK', 0x01)]
#: The type byte defined for PING frames.
type = 0x06
stream_association = _STREAM_ASSOC_NO_STREAM
def __init__(self, stream_id=0, opaque_data=b'', **kwargs):
super(PingFrame, self).__init__(stream_id, **kwargs)