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) -> ReverseProxy
pub fn new<I, S>(backends: I) -> ReverseProxy
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>) -> ReverseProxy
pub fn with_circuit_breaker(self, breaker: Arc<dyn Breaker>) -> ReverseProxy
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>) -> ReverseProxy
pub fn path_prefix(self, prefix: impl Into<String>) -> ReverseProxy
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) -> ReverseProxy
pub fn strategy(self, _strategy: LoadBalancing) -> ReverseProxy
Override the load balancing strategy (currently only RoundRobin).
Sourcepub fn connect_timeout_ms(self, ms: u64) -> ReverseProxy
pub fn connect_timeout_ms(self, ms: u64) -> ReverseProxy
Override the TCP connect timeout (default: 5 000 ms).
Sourcepub fn read_timeout_ms(self, ms: u64) -> ReverseProxy
pub fn read_timeout_ms(self, ms: u64) -> ReverseProxy
Override the response read timeout (default: 30 000 ms).
Sourcepub fn with_pool(self, pool: Arc<Pool<TcpStream>>) -> ReverseProxy
pub fn with_pool(self, pool: Arc<Pool<TcpStream>>) -> ReverseProxy
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<ReverseProxy, String>
pub fn tls_ca_file(self, path: &str) -> Result<ReverseProxy, 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<ReverseProxy, String>
pub fn tls_client_cert( self, cert: &str, key: &str, ) -> Result<ReverseProxy, 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) -> ReverseProxy
pub fn max_idle_conns(self, n: usize) -> ReverseProxy
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.Source§fn layer_name(&self) -> &'static str
fn layer_name(&self) -> &'static str
Application::middleware_names): by default the type’s name
without its module path or generic parameters (CacheLayer). Since
18.28.0.Auto Trait Implementations§
impl !Freeze for ReverseProxy
impl !RefUnwindSafe for ReverseProxy
impl !UnwindSafe for ReverseProxy
impl Send for ReverseProxy
impl Sync for ReverseProxy
impl Unpin for ReverseProxy
impl UnsafeUnpin for ReverseProxy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ServiceExt for T
impl<T> ServiceExt for T
Source§fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
map-response-body only.Source§fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
trace only.Source§fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
trace only.