# h2

URL: /pounce/api/protocols/h2/
Section: protocols
Description: 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 the ``h2`` optional dependency (``pip install bengal-pounce[h2]``).

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

---

> For a complete page index, fetch /pounce/llms.txt.

Open LLM text
(/pounce/api/protocols/h2/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2Fprotocols%2Fh2%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2Fprotocols%2Fh2%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2Fprotocols%2Fh2%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2Fprotocols%2Fh2%2Findex.txt)

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 the`h2` optional dependency (`pip install bengal-pounce[h2]`).

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

8Classes1Function

## 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 (/pounce/api/protocols/_base/#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 (/pounce/api/protocols/_base/#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 (/pounce/api/protocols/_base/#RequestReceived)`

The pounce RequestReceived event (method set to CONNECT).

`ws_path`

`bytes`

The`:path`pseudo-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`

14

▼

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:

- H2 stream events for the worker to dispatch as ASGI scopes

- Raw bytes to write back to the network (flow control, acks, etc.)

The worker is responsible for:

- Calling`receive_data(bytes)`with incoming network data

- Calling `data_to_send()` (/pounce/api/protocols/h2/#H2Connection) to get output bytes after each operation

- Calling `send_response_headers()` (/pounce/api/protocols/h2/#H2Connection) / `send_data()` (/pounce/api/protocols/h2/#H2Connection) for responses

- Managing per-stream ASGI tasks

#### Methods

`max_outbound_frame_size`

0

`int`

▼

Maximum DATA payload size currently accepted by the peer.

property

`def max_outbound_frame_size(self) -> int`

##### Returns

`int`

`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 via `data_to_send()` (/pounce/api/protocols/h2/#H2Connection).

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 call `data_to_send()` (/pounce/api/protocols/h2/#H2Connection) 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 every`receive_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`
