feat(http): implement HttpAdapter (ProtocolHandler for h2/http1.1, axum over QUIC)

Wires the axum Router (gateway endpoints + /healthz + /openapi.json + MCP +
custom routes via extra_routes merge ADR-046) and drives hyper's HTTP/1.1 or
HTTP/2 connection driver over a single QUIC bidirectional stream. The
QUIC-to-hyper bridge wraps the (SendStream, RecvStream) pair as a
TokioIo-compatible duplex and feeds it to hyper-util's auto Builder (which
auto-detects HTTP/1.1 vs HTTP/2). h3 ALPN is not registered (ADR-044).

Route handlers, healthz/decoy logic, openapi.json, the MCP route, and the WS
upgrade handler are wired as 501 Not Implemented placeholders for their
respective tasks. The router state holds Arc<OperationRegistry> +
Arc<dyn IdentityProvider>; the router is built once at construction and
cloned per connection (cheap Arc clone). DecoyConfig defaults to NotFound.

Adds hyper-util dependency (server, service, tokio features).
This commit is contained in:
2026-07-01 18:07:56 +00:00
parent 9df9900bb9
commit b313dcbf20
5 changed files with 497 additions and 4 deletions

View File

@@ -12,15 +12,16 @@ name = "alknet_http"
[features]
default = ["h2", "http1"]
mcp = ["dep:rmcp"]
h2 = ["dep:hyper"]
http1 = ["dep:hyper"]
h2 = ["dep:hyper", "hyper-util/http2", "hyper/http2"]
http1 = ["dep:hyper", "hyper-util/http1", "hyper/http1"]
[dependencies]
alknet-core = { path = "../alknet-core" }
alknet-call = { path = "../alknet-call" }
arc-swap = "1"
axum = { version = "0.8", features = ["ws"] }
hyper = { version = "1", optional = true, features = ["server", "http1", "http2"] }
hyper = { version = "1", optional = true, features = ["server"] }
hyper-util = { version = "0.1", features = ["server", "service", "tokio"] }
httpdate = "1"
reqwest = { version = "0.13", default-features = false, features = ["json", "stream", "rustls"] }
reqwest-middleware = "0.5"