Expand description
A flexible and efficient reverse proxy implementation for Axum web applications.
This crate provides a reverse proxy that can be easily integrated into Axum applications, allowing for seamless forwarding of HTTP requests and WebSocket connections to upstream servers. It supports:
- Path-based routing
- Automatic retry mechanism
- Header forwarding
- Configurable HTTP client settings
- WebSocket proxying with:
- Automatic upgrade handling
- Bidirectional message forwarding
- Text and binary message support
- Proper close frame handling
- Easy integration with Axum’s Router
- Full Tower middleware support
§Basic Example
use axum::Router;
use axum_reverse_proxy::ReverseProxy;
// Create a reverse proxy that forwards requests from /api to httpbin.org
let proxy = ReverseProxy::new("/api", "https://httpbin.org");
// Convert the proxy to a router and use it in your Axum application
let app: Router = proxy.into();
§Using Tower Middleware
The proxy integrates seamlessly with Tower middleware, allowing you to transform requests and responses, add authentication, logging, timeouts, and more:
use axum::{body::Body, Router};
use axum_reverse_proxy::ReverseProxy;
use http::Request;
use tower::ServiceBuilder;
use tower_http::{
timeout::TimeoutLayer,
validate_request::ValidateRequestHeaderLayer,
};
use std::time::Duration;
// Create a reverse proxy
let proxy = ReverseProxy::new("/api", "https://api.example.com");
// Convert to router
let proxy_router: Router = proxy.into();
// Add middleware layers
let app = proxy_router.layer(
ServiceBuilder::new()
// Add request timeout
.layer(TimeoutLayer::new(Duration::from_secs(10)))
// Require API key
.layer(ValidateRequestHeaderLayer::bearer("secret-token"))
// Transform requests
.map_request(|mut req: Request<Body>| {
req.headers_mut().insert(
"X-Custom-Header",
"custom-value".parse().unwrap(),
);
req
})
);
Common middleware use cases include:
- Request/response transformation
- Authentication and authorization
- Rate limiting
- Request validation
- Logging and tracing
- Timeouts and retries
- Caching
- Compression
- Request buffering (via tower-buffer)
See the tower_middleware
example for a complete working example.
§State Management
You can merge the proxy with an existing router that has state:
use axum::{routing::get, Router, response::IntoResponse, extract::State};
use axum_reverse_proxy::ReverseProxy;
#[derive(Clone)]
struct AppState { foo: usize }
async fn root_handler(State(state): State<AppState>) -> impl IntoResponse {
(axum::http::StatusCode::OK, format!("Hello, World! {}", state.foo))
}
let app: Router<AppState> = Router::new()
.route("/", get(root_handler))
.merge(ReverseProxy::new("/api", "https://httpbin.org"))
.with_state(AppState { foo: 42 });
§WebSocket Support
The proxy automatically detects WebSocket upgrade requests and handles them appropriately:
use axum::Router;
use axum_reverse_proxy::ReverseProxy;
// Create a reverse proxy that forwards both HTTP and WebSocket requests
let proxy = ReverseProxy::new("/ws", "http://websocket.example.com");
// WebSocket connections to /ws will be automatically proxied
let app: Router = proxy.into();
The proxy handles:
- WebSocket upgrade handshake
- Bidirectional message forwarding
- Text and binary messages
- Ping/Pong frames
- Connection close frames
- Multiple concurrent connections
Structs§
- Reverse
Proxy - A reverse proxy that forwards HTTP requests to an upstream server.
- Rfc9110
Config - Configuration for RFC9110 middleware
- Rfc9110
Layer - Layer that applies RFC9110 middleware