v0.9.0
flare v0.9.0 is the release where a single Handler serves HTTP/1.1, h2c, HTTP/2, and HTTP/3 at once, and HttpClient speaks all four back. 149 commits since v0.8.1. The headline is the HTTP/3 client and the QUIC hardening that makes it hold up on a real network, but the cycle also closed the ergonomics gap the wire work had opened: streaming responses through the normal handler path, full gRPC, WebSocket over HTTP/2, sessions, OpenAPI, and reliability middleware.
This is a minor bump. Existing serve / Handler / ChunkSource call sites compile unchanged; everything below is additive.
HTTP/3 and QUIC
HttpClient(prefer_http3=True)/.with_prefer_h3()dials HTTP/3 over QUIC, discovers origins viaAlt-Svc(RFC 7838), and races h3 against h2/h1 with happy-eyeballs so a dead QUIC path never costs a timeout. Connections pool and multiplex per origin; idempotent requests can ride 0-RTT and replay at 1-RTT if the server rejects early data.- QUIC server: Retry issuance plus client-side Retry handling (RFC 9000 sec 8.1), connection migration with a strict egress hold, RFC 9221 datagrams, stateless reset on unknown DCIDs, and structural PTO / ack-delay timers.
flare.quic.ccships NewReno, CUBIC, and HyStart++; the 1-RTT path runs an RTT estimator and ACK-based loss detection (RFC 9002).- Batched UDP I/O:
recvmmsgingress on by default,sendmmsg/ GSO egress available, behind an ENOSYS fallback. - On the gate workload flare HTTP/3 runs at 74,653 req/s, about 2.9% ahead of quiche 0.22.
Streaming-proxy surface
The shape an inference or reverse-proxy front needs, without a raw reactor loop or pointer smuggling. StreamHandler + StreamConn give you a typed lifecycle and framework-owned per-connection state; UpstreamChunkSource streams a body off a reactor-registered fd; FrameMux multiplexes logical streams over one Unix socket; watermark backpressure couples upstream reads to downstream writability. serve_streaming runs it single- or multi-worker. A complete single-upstream relay is on_open (attach a source) plus on_upstream (conn.relay_upstream()). ByteReader / ByteWriter replace raw-pointer framing.
gRPC
All four server shapes mount on HttpServer: unary, server-streaming (incrementally flushed, one DATA frame per message), client-streaming, and bidi. grpc-timeout deadlines are enforced and gzip message compression is negotiated. tools/proto_gen.py emits proto3 messages and service-block code (server trait, per-RPC adapters, typed client stub, serialized FileDescriptorProto). Server reflection answers list_services, file_by_filename, and file_containing_symbol; grpc.health.v1.Health ships Check and Watch. The client covers unary plus server-, client-, and bidi-streaming. Maps and oneof in the message codegen are the one remaining gap.
WebSocket
- WebSocket over HTTP/2 (RFC 8441 Extended CONNECT), client and server, including reactor sidecar dispatch (
WsH2Handler+HttpServer.serve[H, W]). - Stateful server handlers via the
WsHandlertrait andWsServer.serve[H]. permessage-deflatecontext-takeover (RFC 7692 §7.1) with a persistent compressor pair.WsAutoClientpicks the carrier wire (h1 or h2) from the negotiated ALPN and drives the handshake.
HTTP client
Connection pooling keyed on (scheme, host, port), with a TLS pool for HTTPS keep-alive. RequestBuilder for per-request method/headers/query/body, MultipartFormBuilder for multipart/form-data, chunked streaming upload (send_chunked), and streaming download (get_streaming) that reads the body in bounded memory. Redirect policies, a cookie jar, retry with backoff, and transparent gzip/deflate/brotli decompression bounded by a 16 MiB zip-bomb cap. HTTP proxy support via CONNECT tunnels and the HTTP_PROXY / HTTPS_PROXY / NO_PROXY env vars.
Routing, state, sessions, OpenAPI, caching
Routeris nowDefaultableand composes with stock middleware;Router.mount(prefix, sub)mounts sub-routers.State[T]carries registration-time state (a DB pool, config) beside request extractors, the analogue of axum'sState(db). TypedJson[T]/Form[T]/JsonAs[T]/Sessionextractors landed.- Sessions gained a pluggable
SessionBackendwith TTL expiry, CSPRNG session ids, and signed-cookie carriers. spec_from_routerderives an OpenAPI 3.1 spec by walking a runtimeRouter.- RFC 9111 HTTP caching:
Cache[Inner, S]middleware, a directive parser, and an in-memory store.
Reliability and errors
RateLimit, CircuitBreaker, and PostHocDeadline middleware. DeadlineWatchdog flips a Cancel cell from a background thread, so cooperative handlers get real mid-flight deadline enforcement. Typed errors map to status now: ValidationError to 400, AuthError to 401/403, plus unauthorized() and forbidden() builders.
Security
The H2 DoS mitigations are enforced in code now, not advertised-only: max_header_list_size on HEADERS+CONTINUATION returns RST with ENHANCE_YOUR_CALM, a CONTINUATION frame cap (CVE-2024-27316), and an RST_STREAM flood answered with GOAWAY (CVE-2023-44487). The client decompression path is bounded by a 16 MiB cap.
Testing and fuzzing
62 fuzz harnesses (58 fuzz + 4 property), 9M+ runs combined, zero known crashes, an ASan CI gate, and h1/ws conformance corpora. H2cTestClient[H] exercises the HTTP/2 handler path in-process without TLS.
Known limits (tracked for v0.9.x)
- QUIC server-side loss-driven retransmit and send pacing are not wired yet; the bench gate is met without them.
HttpClient.get_streaming()raises on HTTPS; use bufferedget()there.- The HTTP/3 client rejects request bodies larger than one packet.
- The io_uring bufring handler stays opt-in (
FLARE_BUFRING_HANDLER=1).
Full inventory in docs/features.md.
Full Changelog: v0.8.1...v0.9.0