Proxy Overview
Two ways to use rws as a reverse proxy — zero-code config-driven mode and programmatic library mode.
rust-web-server ships a full-featured proxy stack. You can use it in two distinct ways depending on how much control you need.
Mode 1 — Config-driven proxy (no code)
Drop a rws.config.toml file next to the binary and run rws. As soon as the file contains at least one [[route]] or [[upstream]] section, the server automatically switches into proxy mode. No Rust code is required.
# rws.config.toml
[[upstream]]
name = "api"
backends = ["localhost:3000", "localhost:3001"]
[[route]]
name = "api-proxy"
[route.match]
path = "/api/*"
[route.action]
type = "proxy"
[route.action.proxy]
upstream = "api"
rws # proxy mode activated automaticallyBest for: ops teams, sidecar containers, API gateways, and situations where you just need to route traffic without touching Rust.
Mode 2 — Library / programmatic
Add rust-web-server as a dependency and compose the proxy middleware stack in code.
use rust_web_server::app::App;
use rust_web_server::core::New;
use rust_web_server::proxy::ReverseProxy;
use rust_web_server::server::Server;
let app = App::new()
.wrap(ReverseProxy::new(["http://backend:3000"])
.path_prefix("/api"));
let (listener, pool) = Server::setup().unwrap();
Server::run(listener, pool, app); // async builds: Server::run_tls(listener, pool, app).awaitBest for: services that need custom routing logic, per-request auth, conditional proxying, or tight integration with application code.
Side-by-side comparison
| Config-driven | Library | |
|---|---|---|
| Requires Rust code | No | Yes |
| Hot-reload via SIGHUP | Yes (routes + upstreams) | No |
| Health checks | Yes (built-in) | Manual (BackendPool + CircuitBreaker) |
| L4 TCP / UDP / WS proxies | Yes (config sections) | Yes (standalone structs) |
| Path rewriting | Yes (strip_path_prefix, add_path_prefix) |
Yes (RewriteLayer) |
| Per-route rate limiting | Yes | Yes (RateLimitLayer) |
| Auth | Yes (bearer token from env var, JWT, htpasswd basic) | Yes (JwtLayer, BasicAuthLayer) |
| Response caching | Yes ([route.middleware.cache]) |
Yes (CacheLayer) |
| gRPC | Yes (type = "grpc") |
Yes (GrpcProxy, requires http2 feature) |
| Canary / traffic splitting | No (planned) | Yes (CanaryLayer) |
| Service discovery | No (planned) | Yes (BackendPool) |
| Circuit breaker / retry | No (planned) | Yes (CircuitBreaker, RetryLayer) |
Behind an L4 load balancer (PROXY protocol)
A TCP load balancer (HAProxy in mode tcp, AWS NLB, GCP's TCP proxy) hides
the client's address: rws sees the balancer's. With the PROXY protocol the
balancer prepends the client's address to each connection; turn it on in rws
(since 18.3.0):
proxy_protocol = true # RWS_CONFIG_PROXY_PROTOCOLEvery connection to the main listener must then start with a version 1 or
version 2 header — before the TLS handshake on HTTPS — and the address in it
is the client address: in access logs, rate limits, IP filters and
X-Forwarded-For to upstreams. A connection without a valid header within
10 seconds is closed, so only enable it when every client comes through the
balancer. The balancer's own health checks (v2 LOCAL, v1 UNKNOWN) keep
its address. The setting is read at startup.
# HAProxy
backend rws
mode tcp
server rws1 10.0.0.5:443 send-proxy-v2 # or send-proxy for version 1HTTP/3 (QUIC) has no PROXY protocol; it is unaffected.
Detection logic
At startup main() calls ProxyConfig::is_proxy_mode(), which reads rws.config.toml (or the path in RWS_CONFIG_FILE) and returns true if the text contains [[route]] or [[upstream]]. When true, build_from_file() compiles the config into a ConfigDrivenApp that replaces the default App.
What to read next
- Config-Driven Proxy — full
rws.config.tomlreference - Reverse Proxy —
ReverseProxymiddleware API - Load Balancing — round-robin, random, IP-hash and least-connections
- Health Checks — automatic backend health monitoring
- Circuit Breaker — failure isolation and retry
- Canary — weighted traffic splitting
- Service Discovery — dynamic backend pools
- TCP Proxy — L4 TCP tunnel
- UDP Proxy — datagram proxy
- WebSocket Proxy — WS upgrade tunneling
- gRPC Proxy — HTTP/2 gRPC forwarding