Module

protocols.h2

HTTP/2 connection handler — sans-I/O wrapper around the h2 library.

Unlike H1Protocol (which handles one request at a time), H2Connection manages a multiplexed HTTP/2 connection with concurrent streams. Each stream maps to one ASGI request.

The h2 library is a sans-I/O state machine: we feed it bytes and it produces events and output bytes. H2Connection translates between h2's internal events and pounce's typed ProtocolEvent system.

Requires theh2 optional dependency (pip install pounce[h2]).

All state is per-connection. No shared mutable state.

Classes

H2RequestReceived 2
HTTP/2 request headers received on a stream.

HTTP/2 request headers received on a stream.

Attributes

Name Type Description
stream_id int

The h2 stream identifier.

request RequestReceived

The pounce RequestReceived event.

H2BodyReceived 2
HTTP/2 request body data received on a stream.

HTTP/2 request body data received on a stream.

Attributes

Name Type Description
stream_id int

The h2 stream identifier.

body BodyReceived

The pounce BodyReceived event.

H2StreamReset 2
Client sent RST_STREAM — cancel the ASGI task for this stream.

Client sent RST_STREAM — cancel the ASGI task for this stream.

Attributes

Name Type Description
stream_id int

The h2 stream identifier.

error_code int

The h2 error code.

H2GoAway 2
Remote sent GOAWAY — no new streams, finish existing ones.

Remote sent GOAWAY — no new streams, finish existing ones.

Attributes

Name Type Description
last_stream_id int

The last stream the remote will process.

error_code int

The h2 error code.

H2WindowUpdated 1
Flow control window was updated — may resume sending.

Flow control window was updated — may resume sending.

Attributes

Name Type Description
stream_id int

The stream id (0 = connection-level).

H2WebSocketRequest 3
Extended CONNECT for WebSocket over HTTP/2 (RFC 8441). The client used ``:method = CONNECT`` with …

Extended CONNECT for WebSocket over HTTP/2 (RFC 8441).

The client used:method = CONNECT with :protocol = websocket to request a WebSocket stream within the HTTP/2 connection.

Attributes

Name Type Description
stream_id int

The h2 stream identifier.

request RequestReceived

The pounce RequestReceived event (method set to CONNECT).

ws_path bytes

The:pathpseudo-header (WebSocket target).

_StreamState 2
Mutable per-stream tracking within an H2Connection.

Mutable per-stream tracking within an H2Connection.

Attributes

Name Type Description
headers_received bool
ended bool
H2Connection 13
HTTP/2 connection state machine backed by the h2 library. Sans-I/O: accepts raw bytes from the net…

HTTP/2 connection state machine backed by the h2 library.

Sans-I/O: accepts raw bytes from the network and produces:

  1. H2 stream events for the worker to dispatch as ASGI scopes
  2. Raw bytes to write back to the network (flow control, acks, etc.)

The worker is responsible for:

  • Callingreceive_data(bytes)with incoming network data
  • Callingdata_to_send()to get output bytes after each operation
  • Callingsend_response_headers() / send_data()for responses
  • Managing per-stream ASGI tasks

Methods

is_closed 0 bool
True if the connection has received GOAWAY.
property
def is_closed(self) -> bool
Returns
bool
active_stream_count 0 int
Number of currently active streams.
property
def active_stream_count(self) -> int
Returns
int
initiate_connection 0
Send the HTTP/2 connection preface. Must be called once after creation. The ou…
def initiate_connection(self) -> None

Send the HTTP/2 connection preface.

Must be called once after creation. The output bytes (settings frame) should be written to the network viadata_to_send().

Enables RFC 8441 Extended CONNECT protocol for WebSocket over H2.

receive_data 1 list[H2Event]
Feed raw bytes from the network and return h2 stream events. After calling thi…
def receive_data(self, data: bytes) -> list[H2Event]

Feed raw bytes from the network and return h2 stream events.

After calling this, always calldata_to_send()to get any pending output (e.g., window updates, settings acks).

Parameters
Name Type Description
data

Raw bytes from the network.

Returns
list[H2Event] List of typed H2 events for the worker to process.
send_response_headers 4
Send response headers on a stream.
def send_response_headers(self, stream_id: int, status: int, headers: list[tuple[bytes, bytes]], *, end_stream: bool = False) -> None
Parameters
Name Type Description
stream_id

The h2 stream identifier.

status

HTTP status code.

headers

Response headers as (name, value) byte pairs.

end_stream

If True, close the stream after headers.

Default:False
send_data 3
Send response body data on a stream. Respects h2 flow control: only sends up t…
def send_data(self, stream_id: int, data: bytes, *, end_stream: bool = False) -> None

Send response body data on a stream.

Respects h2 flow control: only sends up to the available window size. Returns the amount actually sent; the caller should retry with remaining data after a WindowUpdated event.

Parameters
Name Type Description
stream_id

The h2 stream identifier.

data

Response body bytes to send.

end_stream

If True, close the stream after this data.

Default:False
reset_stream 2
Send RST_STREAM to cancel a stream.
def reset_stream(self, stream_id: int, error_code: int = 0) -> None
Parameters
Name Type Description
stream_id

The stream to reset.

error_code

The h2 error code (default: NO_ERROR).

Default:0
close_connection 1
Send GOAWAY to gracefully shut down the connection.
def close_connection(self, error_code: int = 0) -> None
Parameters
Name Type Description
error_code

The h2 error code (default: NO_ERROR).

Default:0
data_to_send 0 bytes
Get pending output bytes to write to the network. Must be called after every `…
def data_to_send(self) -> bytes

Get pending output bytes to write to the network.

Must be called after everyreceive_data(), send_*()call.

Returns
bytes Bytes to write to the socket. May be empty.
local_flow_control_window 1 int
Check available flow control window for a stream.
def local_flow_control_window(self, stream_id: int) -> int
Parameters
Name Type Description
stream_id

The stream to check.

Returns
int Number of bytes that can be sent without blocking.
stream_ended 1 bool
Check if a stream's request is complete.
def stream_ended(self, stream_id: int) -> bool
Parameters
Name Type Description
stream_id
Returns
bool
remove_stream 1
Remove a stream from tracking (after ASGI task completes).
def remove_stream(self, stream_id: int) -> None
Parameters
Name Type Description
stream_id
Internal Methods 1
__init__ 1
def __init__(self, *, client_side: bool = False) -> None
Parameters
Name Type Description
client_side Default:False

Functions

is_h2_available 0 bool
Check if h2 is installed.
def is_h2_available() -> bool
Returns
bool