Overview
HTTP/1.1 is Pounce's default and only required protocol. Two parsers are used depending on the worker mode:
| Parser | Type | Worker | Speed |
|---|---|---|---|
| h11 | Pure Python | Async workers | ~22 µs/req |
| Built-in fast parser | Pure Python | Sync workers | ~3 µs/req |
The sync worker hot path automatically uses the fast built-in parser (_fast_h1.py) for
simple request-response handling. Complex requests (chunked bodies, trailer headers) fall
through to h11.
h11 Backend
The async worker parser. Pure Python, no compilation needed:
import pounce
pounce.run("myapp:app")
h11 is a state-machine-based HTTP/1.1 parser. It's well-tested, handles edge cases correctly, and is easy to debug.
Fast Built-in Parser
The sync worker hot path uses a custom parser measured around ~3 µs/req on the local parser microbenchmark, with tested safety checks:
- Method-token validation (rejects malformed tokens; valid extension methods pass through)
- Header size limits (16 KB, prevents exhaustion)
- Null byte and control character injection detection
- Duplicate Content-Length detection (request smuggling prevention)
- Content-Length + Transfer-Encoding conflict detection
Extension Methods andQUERY
Pounce preserves syntactically valid HTTP method tokens instead of maintaining
an allowlist. In particular,QUERYrequests and their bodies reach the ASGI
application withscope["method"] == "QUERY"on HTTP/1.1, HTTP/2, and HTTP/3.
This behavior is tested through each protocol path.
QUERYremains defined by an
active IETF Internet-Draft,
not a published RFC. Pounce supplies transport and ASGI forwarding only: the
application owns query semantics, media-type validation, caching, authorization,
and anyAccept-Queryresponse field. Intermediaries in front of Pounce must
also be configured to pass the method and request body.
Keep-Alive
Pounce reuses TCP connections between requests (HTTP/1.1 keep-alive). The timeout is configurable:
pounce.run("myapp:app", keep_alive_timeout=5.0) # seconds
After the timeout, idle connections are closed. Set max_requests_per_connectionto limit requests per connection (0 = unlimited).
Chunked Transfer
Pounce handles chunked transfer encoding transparently. When your ASGI app sends multiplehttp.response.body events with more_body=True, Pounce uses chunked encoding automatically.
Expect: 100-continue
When a client sends anExpect: 100-continuerequest header, it withholds the
request body until the server acknowledges with an interim100 Continue
status line. Pounce emits that interim response before reading the body on both
the async (h11) and sync (fast parser) HTTP/1.1 worker paths, so clients that
wait for it do not stall. This is HTTP/1.1 only; HTTP/2 and HTTP/3 use their own
flow-control mechanisms instead.
Trailers
HTTP/1.1 trailing headers (sent after a chunked body) are not supported. Pounce does not surface request trailers to the ASGI app and does not emit response trailers. Applications that rely on trailers should not depend on them with Pounce.
Limits
| Setting | Default | Description |
|---|---|---|
max_request_size |
1 MB | Maximum request body size |
max_header_size |
64 KB | Maximum total header size |
max_headers |
100 | Maximum number of headers |
h11_max_incomplete_event_size |
16 KB | h11 parser buffer limit |
See Also
- HTTP/2 — Stream multiplexing and header compression
- ServerConfig — All configuration options