http3-server · v0.1.0 · 2026-07-13 · sha256 c6cd63af66bc594e

http3-server v0.1.0A

Immutable. This exact content is served forever at /api/v1/blob/c6cd63af66bc594e.

---
name: http3-server
description: Embed sparq's internal opt-in HTTP/3-over-QUIC bridge into an axum server with rustls 0.23/aws-lc-rs, Quinn, peer ConnectInfo injection, and graceful shutdown.
license: MIT
metadata:
  version: "0.1.0"
  homepage: https://github.com/jeswr/sparq
---

# sparq HTTP/3 server bridge

Use `sparq-http3` when a sparq HTTP server needs a second, encrypted UDP listener that
dispatches into the same `axum::Router` as its existing HTTP/1.1 or HTTP/2 listener. The
crate is internal and unstable (`publish = false`), and its `server` feature is off by
default so Quinn and the pre-1.0 h3 stack do not enter ordinary workspace builds.

## Add the opt-in dependency

```toml
[features]
default = []
http3 = ["dep:sparq-http3"]

[dependencies]
sparq-http3 = { path = "../sparq-http3", optional = true, features = ["server"] }
```

The downstream crate owns certificate/key loading and runtime configuration. Build a
`rustls::ServerConfig` with the aws-lc-rs provider, TLS 1.3, and the exact `h3` ALPN token:

```rust
use std::sync::Arc;

let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
let mut tls = rustls::ServerConfig::builder_with_provider(provider)
    .with_protocol_versions(&[&rustls::version::TLS13])?
    .with_no_client_auth()
    .with_single_cert(certificates, private_key)?;
tls.alpn_protocols = vec![b"h3".to_vec()];

let quic = sparq_http3::quic_server_config(tls)?;
let endpoint = quinn::Endpoint::server(quic, udp_addr)?;
# Ok::<(), Box<dyn std::error::Error>>(())
```

`quic_server_config` fails closed when `h3` is missing from ALPN or the provider lacks
QUIC's required initial cipher suite.

## Serve the shared router

```rust
sparq_http3::serve_h3(endpoint, router.clone(), async move {
    shutdown_signal.await;
})
.await?;
# Ok::<(), std::io::Error>(())
```

The bridge clones the router per connection and request, streams request and response
bodies, and inserts the Quinn peer address as `axum::extract::ConnectInfo<SocketAddr>`.
That extension is load-bearing for request policies keyed by the remote socket address.
Protocol failures are isolated to their connection or stream; resolving the shutdown
future closes the endpoint and waits for its QUIC connections to drain.

## Solid/LDP server integration

`sparq-lws-core` carries this bridge behind its default-off `http3` feature
([GPT-5.6] sq-oprna.2):

```sh
SOLID_SERVER_TLS_CERT=/path/to/cert.pem \
SOLID_SERVER_TLS_KEY=/path/to/key.pem \
cargo run -p sparq-lws-core --features http3
```

When both TLS paths are configured, the binary binds QUIC/UDP to the same resolved
`SOLID_SERVER_BIND` address and port as TLS/TCP and serves one cloned
`build_router_with_overload` router. The TCP rustls configuration remains exactly
`[h2, http/1.1]`; a clone used only by Quinn advertises the exact `h3` token. Every
QUIC request receives peer `ConnectInfo`, so the pre-crypto per-IP rate limiter does
not fail open to the ordinary auth stack. With no TLS configuration, enabling the
Cargo feature does not create a QUIC listener. WebSocket notifications continue over
HTTP/1.1 or HTTP/2 because RFC 9220 extended CONNECT is outside this integration.

## Boundaries

- The caller owns rustls policy, certificates, client authentication, Quinn transport
  tuning, listener binding, and process-wide provider installation.
- HTTP/3 is a separate UDP listener. Keep the existing TCP listener running for HTTP/1.1
  and HTTP/2 clients.
- `h3` and `h3-quinn` are pre-1.0 dependencies; keep all direct use inside this helper.
- WebSocket-over-HTTP/3 extended CONNECT is not implemented. WebSocket clients fall back
  to the existing TCP listener.
- Do not advertise `Alt-Svc` until the UDP listener has successfully bound.

## Related material

- `crates/sparq-http3/README.md` — crate scope and opt-in posture.
- `research/http3-quic-servers-design.md` — shared-listener architecture and maturity
  boundary.
- `skills/http-server/SKILL.md` — the SPARQL Protocol server surface.