Commit Graph

2 Commits

Author SHA1 Message Date
b6c96ad42f Add integration tests for multi-hop, gRPC trailers, and HTTP/1.1
Multi-hop integration tests (server package):
- TestMultiHopProxyProtocol: full edge→origin deployment with two
  mc-proxy instances. Edge uses L4 passthrough with send_proxy_protocol,
  origin has proxy_protocol listener with L7 route. Verifies the real
  client IP (127.0.0.1) flows through PROXY protocol into the origin's
  X-Forwarded-For header on the h2c backend.
- TestMultiHopFirewallBlocksRealIP: origin firewall blocks an IP from
  the PROXY header while allowing the TCP peer (edge proxy). Verifies
  the backend is never reached.

L7 package integration tests:
- TestL7LargeResponse: 1 MB response through the reverse proxy.
- TestL7GRPCTrailers: HTTP/2 trailer propagation (Grpc-Status,
  Grpc-Message) through the reverse proxy, validating gRPC
  compatibility.
- TestL7HTTP11Fallback: client negotiates HTTP/1.1 only (no h2 ALPN),
  verifies the proxy falls back to HTTP/1.1 serving and still
  forwards to the h2c backend successfully.

Also updates PROGRESS.md to mark all five phases complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 14:02:45 -07:00
97909b7fbc Add L7 TLS-terminating HTTP/2 reverse proxy
New internal/l7 package implements TLS termination and HTTP/2 reverse
proxying for L7 routes. The proxy terminates the client TLS connection
using per-route certificates, then forwards HTTP/2 traffic to backends
over h2c (plaintext HTTP/2) or h2 (re-encrypted TLS).

PrefixConn replays the peeked ClientHello bytes into crypto/tls.Server
so the TLS handshake sees the complete ClientHello despite SNI
extraction having already read it.

Serve() is the L7 entry point: TLS handshake with route certificate,
ALPN negotiation (h2 preferred, HTTP/1.1 fallback), then HTTP reverse
proxy via httputil.ReverseProxy. Backend transport uses h2c by default
(AllowHTTP + plain TCP dial) or h2-over-TLS when backend_tls is set.

Forwarding headers (X-Forwarded-For, X-Forwarded-Proto, X-Real-IP)
are injected from the real client IP in the Rewrite function. PROXY
protocol v2 is sent to backends when send_proxy_protocol is enabled,
using the request context to carry the client address through the
HTTP/2 transport's dial function.

Server integration: handleConn dispatches to handleL7 when route.Mode
is "l7". The L7 handler converts RouteInfo to l7.RouteConfig and
delegates to l7.Serve.

L7 package tests: PrefixConn (4 tests), h2c backend round-trip,
forwarding header injection, backend unreachable (502), multiple
HTTP/2 requests over one connection.

Server integration tests: L7 route through full server pipeline with
TLS client, mixed L4+L7 routes on the same listener verifying both
paths work independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:43:20 -07:00