feat(core): add HTTP/2 cleartext proxy support
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# HTTP/2 cleartext and proxying
|
||||
|
||||
TLS HTTP/2 and cleartext HTTP/2 have independent rollout controls:
|
||||
|
||||
- `http2Enabled` advertises `h2` through TLS ALPN.
|
||||
- `http2CleartextEnabled` accepts the HTTP/2 prior-knowledge preface on plaintext listeners.
|
||||
|
||||
Both default to `false`. Cleartext support follows RFC 9113 prior knowledge. The obsolete
|
||||
HTTP/1.1 `Upgrade: h2c` transition is intentionally unsupported.
|
||||
|
||||
## Upstream client
|
||||
|
||||
`Http2Client` is a synchronous, pooled client for reverse-proxy handlers. It supports TLS ALPN and
|
||||
h2c prior knowledge, request and response bodies, flow control, response status, trailers,
|
||||
SETTINGS, PING, GOAWAY and RST_STREAM. Connections are pooled by origin and reused across
|
||||
sequential exchanges. A connection serializes its exchanges deliberately; this keeps ownership
|
||||
and HPACK state explicit and bounded while virtual threads allow independent origins to progress.
|
||||
It is not intended to replace a general-purpose HTTP client.
|
||||
|
||||
`HttpProxy.toHttp2(origin, client)` adapts Flash's shared `Request` and `Response` models to that
|
||||
client. It preserves the incoming raw path and query, body, end-to-end fields and trailers.
|
||||
|
||||
## Header conversion
|
||||
|
||||
`HopByHopHeaders` is the single policy used at connection boundaries. It removes fields named by
|
||||
`Connection`, the standard hop-by-hop set, HTTP/2-forbidden fields and pseudo-fields. `TE` is
|
||||
forwarded only as `trailers` when the target is HTTP/2. Tests execute the same policy for all four
|
||||
HTTP/1.1 and HTTP/2 source/target combinations.
|
||||
|
||||
## Authority and 421
|
||||
|
||||
On TLS HTTP/2 connections, Flash checks `:authority` against the selected certificate's DNS/IP
|
||||
subject alternative names. An authority outside that served set receives `421 Misdirected
|
||||
Request`, allowing a coalescing client to retry on a different connection. Exact names and
|
||||
single-label wildcards are supported; h2c has no certificate identity and is unaffected.
|
||||
|
||||
## Trailer guarantee
|
||||
|
||||
The proxy copies request trailers only after the incoming body reaches EOF and emits upstream
|
||||
trailers as a trailing HEADERS block. Response trailers follow the reverse path and remain
|
||||
trailers on both HTTP/2 and HTTP/1.1 chunked downstream connections. The live relay tests cover
|
||||
both downstream protocols.
|
||||
@@ -982,23 +982,22 @@ window and pool byte capacity together; never raise credit independently of boun
|
||||
|
||||
---
|
||||
|
||||
## DEC-29 — Keep HTTP/2 opt-in through the cleartext rollout boundary
|
||||
## DEC-29 — Keep TLS HTTP/2 opt-in until the compliance gate
|
||||
|
||||
**Context.** Trailers and push streaming make the protocol feature-complete for ordinary and gRPC-
|
||||
shaped traffic, but the dedicated rate-based and composite abuse controls are deliberately owned
|
||||
by the following security phase.
|
||||
|
||||
**Decision.** Keep `FlashConfiguration.http2Enabled` defaulting to `false`. Applications can
|
||||
enable the complete path explicitly. The Phase 13 hostile-peer suite is now green, but the same
|
||||
flag currently also admits cleartext prior-knowledge traffic; Phase 14 owns splitting that into a
|
||||
separate `http2CleartextEnabled` opt-in before the general protocol default can change safely.
|
||||
**Decision.** Keep `FlashConfiguration.http2Enabled` defaulting to `false`. Phase 14 separates
|
||||
cleartext behind its own `http2CleartextEnabled` opt-in, also defaulting to `false`. Passing the
|
||||
hostile-peer gate removes the security blocker, but changing the TLS default remains deferred
|
||||
until the complete external conformance gate is green.
|
||||
|
||||
**Consequence.** Existing deployments do not silently expose a newly completed protocol before its
|
||||
adversarial gate. This is rollout sequencing, not an architectural separation: both protocols use
|
||||
the same public request/response, header, trailer and streaming APIs.
|
||||
|
||||
**Revisit when.** At Phase 14 closure, after TLS HTTP/2 and cleartext h2c have independent rollout
|
||||
controls.
|
||||
**Revisit when.** At Phase 16 closure, after the external compliance matrix is green.
|
||||
|
||||
---
|
||||
|
||||
@@ -1022,3 +1021,24 @@ thread. A fixed control-intent pool and one-in-flight intent per live stream bou
|
||||
aggregate default; tune the threshold from evidence without splitting the defence by frame type.
|
||||
|
||||
---
|
||||
|
||||
## DEC-31 — Keep the upstream HTTP/2 client proxy-oriented and single-owner
|
||||
|
||||
**Context.** A general-purpose HTTP client would introduce a second large public API, redirect,
|
||||
cookie, authentication and retry policy, while the immediate requirement is a reliable Flash
|
||||
reverse-proxy hop with trailers.
|
||||
|
||||
**Decision.** Pool one reusable connection per origin and serialize exchanges on that connection.
|
||||
Reuse the core frame reader/writer and HPACK codec, but keep response assembly and ownership inside
|
||||
the client connection. Expose `HttpProxy.toHttp2` as the protocol-neutral adapter and one shared
|
||||
`HopByHopHeaders` policy for every conversion direction.
|
||||
|
||||
**Consequence.** HPACK and socket state have one clear owner, upstream connections are reused, and
|
||||
trailer semantics cannot diverge by downstream protocol. Concurrent calls to one origin queue
|
||||
behind its active exchange rather than pretending this minimal client is a fully multiplexed
|
||||
general-purpose stack.
|
||||
|
||||
**Revisit when.** Proxy production traces show per-origin serialization is a bottleneck; add a
|
||||
bounded pool or client-side multiplexing without changing the proxy-facing API.
|
||||
|
||||
---
|
||||
|
||||
@@ -75,7 +75,7 @@ Status values: `not started` / `in progress` / `blocked` / `done`.
|
||||
| 11 — DATA, flow control, bodies | done | `feature/core/http2` | Two-level receive/send flow control, consumption-driven WINDOW_UPDATE hysteresis, bounded/coalescing DATA pool, inline and blocking streaming request bodies through the existing `RequestBody`, resumable fixed/known/unknown response streams, content-length and empty-DATA validation. Real TLS HTTP/2 transfer: 100 MiB upload + 100 MiB download verified byte-for-byte. h2spec combined sections 5, 6.1, 6.9 and 8: 50 passed, 1 tool-skipped, 0 failed. JMH: inline materialization exactly one 1,040-byte array; request streaming 0.001 B/op; response streaming 0.002 B/op; full pooled lifecycle 0.003 B/op. 633/633 tests green from a clean `-Pjmh` build. |
|
||||
| 12 — Trailers, half-close, gRPC | done | `feature/core/http2` | Protocol-neutral request/response trailers, bounded push streaming, four half-close orderings and authority-form CONNECT tunnels complete. Real grpcurl 1.9.3 unary/server-streaming/error interop passes. EX-48/49 fixed. HTTP/2 remains opt-in until the Phase 13 hostile-peer gate (DEC-29). 649/649 tests green from a clean `-Pjmh` build. |
|
||||
| 13 — Security hardening & abuse resistance | done | `feature/core/http2` | Two-bucket Rapid Reset/stream/settings/ping/aggregate counters, control/write queue bounds, optional stream/byte/lifetime budgets, absolute header and idle-stream deadlines, and hostile-peer suite complete. Security review found+fixed EX-50/51. JMH counter: 38.083 ns/op, ~10^-4 B/op, no GC. 100k-CONTINUATION attack terminates in under 2 s with bounded retained heap. 663/663 tests green from a clean `-Pjmh` build. |
|
||||
| 14 — h2c prior knowledge + proxy support | not started | — | — |
|
||||
| 14 — h2c prior knowledge + proxy support | done | `feature/core/http2` | Independent TLS/h2c gates, pooled proxy-oriented h2 client with TLS ALPN and h2c, bidirectional h1/h2 trailer relay, shared four-direction hop-by-hop policy and certificate-backed 421 handling complete. Real grpcurl h2c interop passes. 670/670 tests green from a clean `-Pjmh` build. |
|
||||
| 15 — RFC 8441 extended CONNECT (WS over h2) | not started | — | — |
|
||||
| 16 — Compliance test suite | not started | — | — |
|
||||
| 17 — Benchmarks, allocation gates, tuning | not started | — | — |
|
||||
@@ -2906,8 +2906,8 @@ speak h2 as a **client** so Pathway can proxy.
|
||||
`flash/docs/http2/CLEARTEXT-AND-PROXY.md`.
|
||||
|
||||
### DoD
|
||||
- [ ] gRPC over h2c works end to end.
|
||||
- [ ] Trailers survive a Flash→Flash proxy hop in both directions.
|
||||
- [x] gRPC over h2c works end to end.
|
||||
- [x] Trailers survive a Flash→Flash proxy hop in both directions.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user