axum-reverse-proxy 0.1.0

A flexible and efficient reverse proxy implementation for Axum web applications
Documentation

axum-reverse-proxy

CI

A flexible and efficient reverse proxy implementation for Axum web applications. This library provides a simple way to forward HTTP requests from your Axum application to upstream servers.

Features

  • 🛣️ Path-based routing
  • 🔄 Automatic retry mechanism with exponential backoff
  • 📨 Header forwarding (with host header management)
  • ⚙️ Configurable HTTP client settings
  • 🔌 Easy integration with Axum's Router
  • 🧰 Custom client configuration support
  • 🔒 HTTPS support

Installation

Add this to your Cargo.toml:

[dependencies]
axum-reverse-proxy = "0.1.0"

Quick Start

Here's a simple example that forwards all requests under /api to httpbin.org:

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();

Advanced Usage

Merging with Existing Router

You can merge the proxy with your existing Axum router:

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 });

Custom Client Configuration

For more control over the HTTP client behavior:

use axum_reverse_proxy::ReverseProxy;
use hyper_util::client::legacy::{Client, connect::HttpConnector};
use axum::body::Body;

let mut connector = HttpConnector::new();
connector.set_nodelay(true);
connector.enforce_http(false);
connector.set_keepalive(Some(std::time::Duration::from_secs(60)));

let client = Client::builder(hyper_util::rt::TokioExecutor::new())
    .pool_idle_timeout(std::time::Duration::from_secs(60))
    .pool_max_idle_per_host(32)
    .build(connector);

let proxy = ReverseProxy::new_with_client("/api", "https://api.example.com", client);

Configuration

The default configuration includes:

  • 3 retry attempts with exponential backoff
  • 60-second keepalive timeout
  • 10-second connect timeout
  • TCP nodelay enabled
  • Connection pooling with 32 idle connections per host
  • Automatic host header management

Examples

Check out the examples directory for more usage examples:

  • Basic Proxy - Shows how to set up a basic reverse proxy with path-based routing

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.