axum_reverse_proxy/lib.rs
1//! A flexible and efficient reverse proxy implementation for Axum web applications.
2//!
3//! This crate provides a reverse proxy that can be easily integrated into Axum applications,
4//! allowing for seamless forwarding of HTTP requests and WebSocket connections to upstream servers.
5//! It supports:
6//!
7//! - Path-based routing
8//! - Automatic retry mechanism
9//! - Header forwarding
10//! - Configurable HTTP client settings
11//! - WebSocket proxying with:
12//! - Automatic upgrade handling
13//! - Bidirectional message forwarding
14//! - Text and binary message support
15//! - Proper close frame handling
16//! - Easy integration with Axum's Router
17//! - Full Tower middleware support
18//!
19//! # Basic Example
20//!
21//! ```rust
22//! use axum::Router;
23//! use axum_reverse_proxy::ReverseProxy;
24//!
25//! // Create a reverse proxy that forwards requests from /api to httpbin.org
26//! let proxy = ReverseProxy::new("/api", "https://httpbin.org");
27//!
28//! // Convert the proxy to a router and use it in your Axum application
29//! let app: Router = proxy.into();
30//! ```
31//!
32//! # Using Tower Middleware
33//!
34//! The proxy integrates seamlessly with Tower middleware, allowing you to transform requests
35//! and responses, add authentication, logging, timeouts, and more:
36//!
37//! ```rust
38//! use axum::{body::Body, Router};
39//! use axum_reverse_proxy::ReverseProxy;
40//! use http::Request;
41//! use tower::ServiceBuilder;
42//! use tower_http::{
43//! timeout::TimeoutLayer,
44//! validate_request::ValidateRequestHeaderLayer,
45//! };
46//! use std::time::Duration;
47//!
48//! // Create a reverse proxy
49//! let proxy = ReverseProxy::new("/api", "https://api.example.com");
50//!
51//! // Convert to router
52//! let proxy_router: Router = proxy.into();
53//!
54//! // Add middleware layers
55//! let app = proxy_router.layer(
56//! ServiceBuilder::new()
57//! // Add request timeout
58//! .layer(TimeoutLayer::new(Duration::from_secs(10)))
59//! // Require API key
60//! .layer(ValidateRequestHeaderLayer::bearer("secret-token"))
61//! // Transform requests
62//! .map_request(|mut req: Request<Body>| {
63//! req.headers_mut().insert(
64//! "X-Custom-Header",
65//! "custom-value".parse().unwrap(),
66//! );
67//! req
68//! })
69//! );
70//! ```
71//!
72//! Common middleware use cases include:
73//! - Request/response transformation
74//! - Authentication and authorization
75//! - Rate limiting
76//! - Request validation
77//! - Logging and tracing
78//! - Timeouts and retries
79//! - Caching
80//! - Compression
81//! - Request buffering (via tower-buffer)
82//!
83//! See the `tower_middleware` example for a complete working example.
84//!
85//! # State Management
86//!
87//! You can merge the proxy with an existing router that has state:
88//!
89//! ```rust
90//! use axum::{routing::get, Router, response::IntoResponse, extract::State};
91//! use axum_reverse_proxy::ReverseProxy;
92//!
93//! #[derive(Clone)]
94//! struct AppState { foo: usize }
95//!
96//! async fn root_handler(State(state): State<AppState>) -> impl IntoResponse {
97//! (axum::http::StatusCode::OK, format!("Hello, World! {}", state.foo))
98//! }
99//!
100//! let app: Router<AppState> = Router::new()
101//! .route("/", get(root_handler))
102//! .merge(ReverseProxy::new("/api", "https://httpbin.org"))
103//! .with_state(AppState { foo: 42 });
104//! ```
105//!
106//! # WebSocket Support
107//!
108//! The proxy automatically detects WebSocket upgrade requests and handles them appropriately:
109//!
110//! ```rust
111//! use axum::Router;
112//! use axum_reverse_proxy::ReverseProxy;
113//!
114//! // Create a reverse proxy that forwards both HTTP and WebSocket requests
115//! let proxy = ReverseProxy::new("/ws", "http://websocket.example.com");
116//!
117//! // WebSocket connections to /ws will be automatically proxied
118//! let app: Router = proxy.into();
119//! ```
120//!
121//! The proxy handles:
122//! - WebSocket upgrade handshake
123//! - Bidirectional message forwarding
124//! - Text and binary messages
125//! - Ping/Pong frames
126//! - Connection close frames
127//! - Multiple concurrent connections
128
129mod proxy;
130mod rfc9110;
131mod router;
132mod websocket;
133
134pub use proxy::ReverseProxy;
135pub use rfc9110::{Rfc9110Config, Rfc9110Layer};