h11r 0.1.0

Sans-I/O HTTP/1.1 protocol engine
Documentation
  • Coverage
  • 100%
    61 out of 61 items documented0 out of 14 items with examples
  • Size
  • Source code size: 185.13 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.79 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • cnzakii/h11r
    2 1 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • cnzakii

h11r translates between bytes and HTTP events. It handles message framing, connection state, and protocol errors without reading from or writing to the network. Connect it to synchronous sockets, asyncio, Trio, or any other transport that can move bytes.

The protocol core is an independent Rust crate exposed as a typed Python package through PyO3. Its connection model is inspired by h11, while request, response, and trailer head parsing is built on httparse.

h11r is currently alpha software. Its public API may change before the first stable release.

Performance

Python benchmark comparing h11r and h11

The chart compares protocol-layer throughput for h11r and h11 0.16.0 across five equivalent Python HTTP/1.1 workloads that reuse their connections. Each workload uses public APIs and includes protocol state transitions. It does not include socket, TLS, or asynchronous runtime overhead. Higher is faster.

The results were produced by the pyperf benchmark. The raw pyperf result used to render the chart is included for reproduction and inspection. The measurement environment is recorded in the chart. Results will vary with hardware and Python version.

Quick Start

Add h11r to a uv-managed project:

uv add h11r

Or install it with pip:

pip install h11r

This server-side example parses one request and produces a complete response. The caller remains responsible for network I/O.

import h11r

connection = h11r.Connection(h11r.Role.SERVER)

# Bytes received from any synchronous or asynchronous transport.
connection.receive_data(
    b"GET / HTTP/1.1\r\n"
    b"Host: example.com\r\n"
    b"\r\n"
)

request = connection.next_event()
end = connection.next_event()

assert isinstance(request, h11r.Request)
assert request.method == b"GET"
assert isinstance(end, h11r.EndOfMessage)

# Write the returned bytes to the same transport.
outbound = connection.send_response(
    200,
    [("Content-Length", "2")],
    reason="OK",
)
outbound += connection.send_data(b"OK")
outbound += connection.end_of_message()

A Protocol Component, Not an HTTP Client

h11r does not open sockets, choose a concurrency model, or handle TLS, connection pooling, redirects, cookies, or routing. It maintains the protocol state of one HTTP/1.1 connection while higher-level clients, servers, proxies, and test tools decide how to schedule I/O.

It supports client and server roles, HTTP/1.0 peers, Content-Length and chunked framing, keep-alive cycles, informational responses, trailers, and protocol handoff after Upgrade. Input size and header count have independent limits, and local API misuse is reported separately from remote protocol errors.

Acknowledgements

h11r follows the Sans-I/O approach of keeping protocol state separate from network I/O. Its connection lifecycle and event model are inspired by h11. It is not a drop-in replacement for h11; it is a Rust-powered Python implementation built in the same tradition.

Low-level HTTP head parsing is provided by httparse. h11r owns the full message framing, connection state machine, resource boundaries, and Python API.

Contributing

See CONTRIBUTING.md for development and release guidance.

License

MIT