Skip to content

blackbull.protocol.frame_types

blackbull.protocol.frame_types

HTTP/2 frame type definitions (RFC 9113 §6; supersedes RFC 7540 §6).

Frame-type classes, enums, and the FrameBase registry. HPACK compression/decompression is delegated to the hpack library.

FrameFactory lives in frame.py; this module is kept free of factory / parsing logic so the type hierarchy can be imported without pulling in the codec.

Continuation

Bases: FrameBase

docstring for Continuation

Data

Bases: FrameBase

docstring for Data

FrameBase

docstring for FrameBase

FrameFlags

Bases: IntEnum

Common base for all HTTP/2 frame flag enums.

Inheriting from this empty base allows type annotations to reference FrameFlags instead of listing every concrete flag enum. Because FrameFlags itself has no members, Python's restriction on subclassing a non-empty IntEnum does not apply.

FrameFormatError

Bases: ValueError

A frame the RFC calls malformed, carrying the code its own section names.

A parser that raises a bare Exception leaves the caller to guess the error code from the message, and the guess is the thing the peer acts on. ValueError because that is what the padding checks already raised.

GoAway

Bases: FrameBase

RFC 9113 §6.8 — GOAWAY frame.

The frame's stream identifier (set by FrameBase) MUST be 0; this is a connection-level frame. The first 4 bytes of the payload are the last_stream_id (a separate field) and the next 4 bytes are the error code. Earlier revisions of this class assigned the payload's last_stream_id back into self.stream_id, which made every outgoing GOAWAY ship with the wrong frame header — h2spec saw a malformed GOAWAY and reported "Error: connection error: PROTOCOL_ERROR" instead of accepting the GOAWAY for the connection-error tests.

Headers

Bases: FrameBase

parse_payload()

Decode the field block, which may span several frames.

Padding and priority belong to the frame that carried the flags, and self.length is that frame's payload; everything past it was appended by CONTINUATION and is fragment throughout.

Ping

Bases: FrameBase

docstring for Ping

PriorityUpdate

Bases: FrameBase

RFC 9218 §7.1 — PRIORITY_UPDATE frame (type 0x10).

Payload: 4-byte Prioritized Stream ID + ASCII Priority field value (e.g. u=3 or u=0, i). The server receives and logs the hint but does not reorder stream processing.

PseudoHeaders

Bases: StrEnum

RFC 7540 §8.1.2 pseudo-header field names.

PushPromise

Bases: FrameBase

RFC 7540 §6.6 — PUSH_PROMISE frame (type 0x05).

Sent on the initiating (parent) stream; carries the promised stream ID and the HPACK-encoded synthetic request headers for the pushed resource.

parse_payload()

Decode the promised block and discard it: the side effect on the connection-wide HPACK table is the point, and RFC 9113 §4.3 requires it even though the client acts on no push.

Splitting works as in :meth:Headers.parse_payload.

SettingFrame

Bases: FrameBase

docstring for SettingFrame

WindowUpdate

Bases: FrameBase

docstring for WindowUpdate

field_name_is_valid(name)

RFC 9113 §8.2.1 — is name a legal HTTP/2 field name?

A field name MUST NOT contain characters in 0x00-0x20 (controls and SP), 0x41-0x5A (uppercase), or 0x7F-0xFF. It MUST NOT include a colon (0x3A) other than the single leading octet that marks a pseudo-header field. Rejecting these closes a header-injection / request-smuggling vector.

field_value_is_valid(value)

RFC 9113 §8.2.1 — a field value MUST NOT contain NUL, LF, or CR.

no_hpack_context(frame, codec)

The refusal for a header frame that cannot name its connection's codec.

HPACK state is connection-wide and the peer keeps exactly one table for it (RFC 7541 §2.3, RFC 9113 §4.3), so a substitute codec is never a weaker version of the right one — it is a different table. Both directions fail the same way and silently: a private encoder writes indices the peer resolves against entries someone else inserted, and a block that never reaches the connection's decoder leaves it behind its peer for good. Valid-looking bytes, wrong fields, no exception on either side.

The message has to send the reader to the connection rather than to the signature, because "missing argument" is answered by passing any codec.

parse_priority_field(s)

Parse an RFC 9218 Priority field value (a Structured Fields Dictionary).

"u=5, i"{'urgency': 5, 'incremental': True}

Defaults per RFC 9218 §4.1: urgency=3, incremental=False. A value that fails strict RFC 9651 parsing is ignored entirely (RFC 9218 §5), and out-of-range or mistyped members are ignored individually (RFC 9218 §4) — either way the defaults apply.