Add in-memory HTTP response cache using pingora-cache MemCache backend.
Cache runs after the detection pipeline so cache hits bypass upstream
request modifications and body rewriting. Respects Cache-Control
(no-store, private, s-maxage, max-age), skips caching for routes with
body rewrites or auth subrequest headers, and supports configurable
default TTL, stale-while-revalidate, and max file size per route.
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
Add static file serving with try_files chain ($uri, $uri.html,
$uri/index.html, fallback), regex-based URL rewrites compiled at
startup, response body find/replace for text/html and JS content,
auth subrequests with header capture for path routes, and custom
response headers per route. Extends RouteConfig with static_root,
fallback, rewrites, body_rewrites, and response_headers fields.
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
Generate UUID v4 request IDs per request, create manual tracing spans
(Pingora types don't impl Debug), record Prometheus metrics for
detection decisions and request totals, and forward X-Request-Id to
both upstream requests and downstream responses.
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
Add a prometheus metrics module with counters for requests, DDoS/scanner/
rate-limit decisions, active connections gauge, and request duration
histogram. Spawn a lightweight HTTP server on a configurable port
(default 9090) serving /metrics and /health endpoints.
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
Wire up all three detection layers in request_filter with pipeline
logging at each stage for unfiltered training data. Add DDoS, scanner,
and rate_limit config sections. Bot allowlist check before scanner
model on the hot path. CLI subcommands for train/replay.
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
This commit implements comprehensive dual-stack support for the proxy,
allowing it to listen on both IPv4 and IPv6 addresses simultaneously.
Key changes:
- Added new dual_stack.rs module with DualStackTcpListener implementation
- Updated SSH module to use dual-stack listener
- Updated configuration documentation to reflect IPv6 support
- Added comprehensive tests for dual-stack functionality
The implementation is inspired by tokio_dual_stack but implemented
natively without external dependencies. It provides fair connection
distribution between IPv4 and IPv6 clients while maintaining full
backward compatibility with existing IPv4-only configurations.
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
Root cause: upstream_request_filter was inserting x-forwarded-proto with
a raw headers.insert() call (via DerefMut) which only updates base.headers
but NOT the CaseMap. header_to_h1_wire zips CaseMap with base.headers, so
headers added without a CaseMap entry are silently dropped on the wire.
Fix: use insert_header() which keeps both maps in sync.
Also adds:
- src/lib.rs + [lib] section: exposes SunbeamProxy/RouteConfig/AcmeRoutes
to integration tests without re-declaring modules in main.rs
- tests/e2e.rs: real end-to-end test — starts a SunbeamProxy over plain
HTTP, routes it to a TCP echo backend, and asserts x-forwarded-proto: http
is present in the upstream request headers
- Updated unit tests to verify header_to_h1_wire round-trip (not just that
HeaderMap::insert works in isolation)
Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>