Classes
SendState
2
▼
Mutable holder for response metrics populated by the send callable.
The worker reads these after t…
SendState
2
▼
Mutable holder for response metrics populated by the send callable.
The worker reads these after the ASGI app completes to get the actual HTTP status code and byte count for access logging.
Attributes
| Name | Type | Description |
|---|---|---|
status |
int
|
— |
bytes_sent |
int
|
— |
Functions
_sanitize_headers
1
list[tuple[bytes, bytes]]
▼
Strip CR/LF characters from response header names and values.
Prevents CRLF in…
_sanitize_headers
1
list[tuple[bytes, bytes]]
▼
def _sanitize_headers(headers: list[tuple[bytes, bytes]]) -> list[tuple[bytes, bytes]]
Strip CR/LF characters from response header names and values.
Prevents CRLF injection attacks where a malicious ASGI app could inject extra headers or split the HTTP response. This is defense-in-depth — h11 also validates header content, but we guard before serialization.
Parameters
| Name | Type | Description |
|---|---|---|
headers |
list[tuple[bytes, bytes]] |
Returns
list[tuple[bytes, bytes]]
build_scope
4
dict[str, Any]
▼
Build an ASGI HTTP scope dict from a parsed request.
build_scope
4
dict[str, Any]
▼
def build_scope(request: RequestReceived, config: ServerConfig, client: tuple[str, int], server: tuple[str, int]) -> dict[str, Any]
Parameters
| Name | Type | Description |
|---|---|---|
request |
RequestReceived |
The parsed HTTP request head. |
config |
ServerConfig |
Server configuration. |
client |
tuple[str, int] |
Client (host, port) tuple. |
server |
tuple[str, int] |
Server (host, port) tuple. |
Returns
dict[str, Any]
create_receive
1
Receive
▼
Create an ASGI receive callable from a body event queue.
The worker pushes Bod…
create_receive
1
Receive
▼
def create_receive(body_events: asyncio.Queue[BodyReceived]) -> Receive
Create an ASGI receive callable from a body event queue.
The worker pushes BodyReceived events into the queue as they arrive. The ASGI app calls receive() to consume them as http.request messages.
Parameters
| Name | Type | Description |
|---|---|---|
body_events |
asyncio.Queue[BodyReceived] |
Queue of body events from the protocol layer. |
Returns
Receive
create_empty_receive
0
Receive
▼
Create a fast-path receive for bodyless requests (GET, HEAD, etc.).
Returns a …
create_empty_receive
0
Receive
▼
def create_empty_receive() -> Receive
Create a fast-path receive for bodyless requests (GET, HEAD, etc.).
Returns a static empty-body message without asyncio.Queue overhead. Called at most once per request — second call would hang, but ASGI apps should not call receive() twice for bodyless requests.
Returns
Receive
create_disconnect_receive
1
Receive
▼
Create a receive callable that delivers ``http.disconnect``.
For bodyless requ…
create_disconnect_receive
1
Receive
▼
def create_disconnect_receive(disconnect: asyncio.Event) -> Receive
Create a receive callable that delivershttp.disconnect.
For bodyless requests (GET, HEAD, etc.): returns the empty body message
on first call, then waits for the disconnect event before returning
http.disconnect. This allows ASGI apps (e.g. Chirp's SSE handler)
to detect client disconnects and stop producing events.
Parameters
| Name | Type | Description |
|---|---|---|
disconnect |
asyncio.Event |
Event set by the connection monitor when the client closes the socket. |
Returns
Receive
create_receive_with_disconnect
2
Receive
▼
Create a receive callable that delivers body events then ``http.disconnect``.
…
create_receive_with_disconnect
2
Receive
▼
def create_receive_with_disconnect(body_events: asyncio.Queue[BodyReceived], disconnect: asyncio.Event) -> Receive
Create a receive callable that delivers body events thenhttp.disconnect.
Used when the request has a body (POST, PUT, etc.). Delivers body chunks
from the queue until the body is complete, then waits for the disconnect
event and returnshttp.disconnect.
Parameters
| Name | Type | Description |
|---|---|---|
body_events |
asyncio.Queue[BodyReceived] |
Queue of body events from the protocol layer. |
disconnect |
asyncio.Event |
Event set by the connection monitor when the client closes the socket. |
Returns
Receive
create_send
7
Send
▼
Create an ASGI send callable that streams to the transport.
Streaming-first: e…
create_send
7
Send
▼
def create_send(protocol: ProtocolHandler, writer: asyncio.StreamWriter, state: SendState, *, timing: ServerTiming | None = None, compressor: Compressor | None = None, request_method: bytes = b'GET', request_id: str | None = None) -> Send
Create an ASGI send callable that streams to the transport.
Streaming-first: each response.body chunk is written immediately. No buffering — the client sees data as soon as the app produces it.
Write coalescing: the response head is held back and combined with
the first body chunk in a singlewriter.write()call when the
total fits within_COALESCE_THRESHOLD. This halves the number
of syscalls for small responses (the common case).
Parameters
| Name | Type | Description |
|---|---|---|
protocol |
ProtocolHandler |
Protocol handler for serialization. |
writer |
asyncio.StreamWriter |
Asyncio stream writer for the connection. |
state |
SendState |
Mutable holder populated with response status and byte count. |
timing |
ServerTiming | None |
Optional Server-Timing header builder. Default:None
|
compressor |
Compressor | None |
Optional content compressor for the response. Default:None
|
request_method |
bytes |
Default:b'GET'
|
request_id |
str | None |
Default:None
|
Returns
Send