pub struct ReverseProxy { /* private fields */ }Expand description
Reverse proxy middleware.
Forwards incoming requests to one of the configured backends over HTTP/1.1.
On connection failure the next backend in the list is tried; when all
backends have failed the middleware returns 502 Bad Gateway.
Hop-by-hop headers are stripped before forwarding. X-Forwarded-For and
Via are added to every forwarded request.
Idle connections are pooled and reused across requests (up to
64 idle per backend, 60-second timeout).
This eliminates per-request TCP handshake overhead and ephemeral-port
exhaustion. Use ReverseProxy::with_pool to share a pool across
multiple proxy instances or to tune pool parameters.
Implementations§
Source§impl ReverseProxy
impl ReverseProxy
Sourcepub fn new<I, S>(backends: I) -> Self
pub fn new<I, S>(backends: I) -> Self
Create a proxy that distributes requests across backends in
round-robin order. Each entry must be "http://host:port" or
"host:port" (port defaults to 80).
Sourcepub fn with_circuit_breaker(self, breaker: Arc<dyn Breaker>) -> Self
pub fn with_circuit_breaker(self, breaker: Arc<dyn Breaker>) -> Self
Wire a crate::circuit_breaker::CircuitBreaker or
crate::circuit_breaker::RedisCircuitBreaker into this proxy:
before dialing a backend, its breaker state is checked (an Open
backend is skipped with no TCP attempt, exactly like a caller
manually checking is_available around each proxied call); after a
dial, record_success/record_failure is called automatically.
No breaker is wired by default — existing ReverseProxy callers see
no behavior change unless they opt in here.
use std::sync::Arc;
use rust_web_server::circuit_breaker::global as global_breaker;
use rust_web_server::proxy::ReverseProxy;
let proxy = ReverseProxy::new(["http://backend-1:8080", "http://backend-2:8080"])
.with_circuit_breaker(Arc::new(global_breaker()));Sourcepub fn path_prefix(self, prefix: impl Into<String>) -> Self
pub fn path_prefix(self, prefix: impl Into<String>) -> Self
Only proxy requests whose URI starts with prefix.
Other requests are passed through to the next layer in the middleware chain (or the inner application).
Sourcepub fn strategy(self, _strategy: LoadBalancing) -> Self
pub fn strategy(self, _strategy: LoadBalancing) -> Self
Override the load balancing strategy (currently only RoundRobin).
Sourcepub fn connect_timeout_ms(self, ms: u64) -> Self
pub fn connect_timeout_ms(self, ms: u64) -> Self
Override the TCP connect timeout (default: 5 000 ms).
Sourcepub fn read_timeout_ms(self, ms: u64) -> Self
pub fn read_timeout_ms(self, ms: u64) -> Self
Override the response read timeout (default: 30 000 ms).
Sourcepub fn with_pool(self, pool: Arc<ConnPool>) -> Self
pub fn with_pool(self, pool: Arc<ConnPool>) -> Self
Attach a shared connection pool.
Useful for sharing one pool across multiple ReverseProxy instances
or for tuning pool parameters (capacity, idle timeout).
Sourcepub fn tls_ca_file(self, path: &str) -> Result<Self, String>
pub fn tls_ca_file(self, path: &str) -> Result<Self, String>
Trust the CA certificates in the PEM file path for https://
backends, instead of the public WebPKI roots — for internal
services behind a private CA or a self-signed certificate.
Sourcepub fn tls_client_cert(self, cert: &str, key: &str) -> Result<Self, String>
pub fn tls_client_cert(self, cert: &str, key: &str) -> Result<Self, String>
Present the client certificate in the PEM file cert (with its
private key in key) to https:// backends that require one —
mutual TLS to the upstream. Since 18.3.0.
Sourcepub fn max_idle_conns(self, n: usize) -> Self
pub fn max_idle_conns(self, n: usize) -> Self
Set the maximum number of idle connections per backend (default: 64).
Trait Implementations§
Source§impl Middleware for ReverseProxy
impl Middleware for ReverseProxy
fn handle( &self, request: &Request, connection: &ConnectionInfo, next: &dyn Application, ) -> Result<Response, String>
Source§fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool
fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool
true when this layer’s own work for request never blocks (in-memory
state, atomics, short mutexes) — see Application::runs_inline. A
WithMiddleware stack runs inline only if every layer and the inner
application agree. Default false.Source§fn is_passthrough(
&self,
_request: &Request,
_connection: &ConnectionInfo,
) -> bool
fn is_passthrough( &self, _request: &Request, _connection: &ConnectionInfo, ) -> bool
true when handle would do nothing for request but call next
(e.g. a rate limit that isn’t configured). A WithMiddleware stack
offers the inner application’s execute_async only if every layer
passes the request through. Default false.Source§fn accepts_streamed_body(
&self,
_request: &Request,
_connection: &ConnectionInfo,
) -> bool
fn accepts_streamed_body( &self, _request: &Request, _connection: &ConnectionInfo, ) -> bool
true when this layer never reads request.body, so the inner
application may receive it as a stream (Application::streams_body).
A layer that inspects the body (CSRF tokens in a form, request
signatures, rewriting) must keep the default false: it would see an
empty body.Source§fn answers_streamed_body(
&self,
_request: &Request,
_connection: &ConnectionInfo,
) -> bool
fn answers_streamed_body( &self, _request: &Request, _connection: &ConnectionInfo, ) -> bool
true when this layer answers request itself — it doesn’t call
next — and reads its body as a stream (a proxy forwarding it as it
arrives). The body is then streamed whatever the layers after it and
the application would say. Requires accepts_streamed_body. Since
18.3.0.