#reverse-proxy #proxy-server #proxy #reverse #warp #filter #http-proxy

warp-reverse-proxy

Warp filter that acts as a reverse proxy, forwarding the request to a proxy address and extracting a response

9 releases (1 stable)

1.0.0 Dec 19, 2022
0.5.0 Mar 18, 2022
0.4.0 Oct 3, 2021
0.3.2 Jun 2, 2021
0.1.0 Aug 17, 2020

#552 in HTTP server

Download history 4058/week @ 2024-08-12 4771/week @ 2024-08-19 4179/week @ 2024-08-26 3844/week @ 2024-09-02 4765/week @ 2024-09-09 4405/week @ 2024-09-16 4460/week @ 2024-09-23 5523/week @ 2024-09-30 4941/week @ 2024-10-07 4146/week @ 2024-10-14 4776/week @ 2024-10-21 4099/week @ 2024-10-28 4450/week @ 2024-11-04 5016/week @ 2024-11-11 6017/week @ 2024-11-18 2987/week @ 2024-11-25

18,597 downloads per month
Used in 21 crates (4 directly)

Custom license

20KB
250 lines

warp-reverse-proxy

MIT licensed GHA Build Status Docs Badge

Fully composable warp filter that can be used as a reverse proxy. It forwards the request to the desired address and replies back the remote address response.

Add the library dependency

[dependencies]
warp = "0.3"
warp-reverse-proxy = "1"

Use it as simple as:

use warp::{hyper::Body, Filter, Rejection, Reply, http::Response};
use warp_reverse_proxy::reverse_proxy_filter;

async fn log_response(response: Response<Body>) -> Result<impl Reply, Rejection> {
    println!("{:?}", response);
    Ok(response)
}

#[tokio::main]
async fn main() {
    let hello = warp::path!("hello" / String).map(|name| format!("Hello, {}!", name));
    // // spawn base server
    tokio::spawn(warp::serve(hello).run(([0, 0, 0, 0], 8080)));
    // Forward request to localhost in other port
    let app = warp::path!("hello" / ..).and(
        reverse_proxy_filter("".to_string(), "http://127.0.0.1:8080/".to_string())
            .and_then(log_response),
    );
    // spawn proxy server
    warp::serve(app).run(([0, 0, 0, 0], 3030)).await;
}

For more control. You can compose inner library filters to help you compose your own reverse proxy:

#[tokio::main]
async fn main() {
    let hello = warp::path!("hello" / String).map(|name| format!("Hello port, {}!", name));

    // // spawn base server
    tokio::spawn(warp::serve(hello).run(([0, 0, 0, 0], 8080)));

    let request_filter = extract_request_data_filter();
    let app = warp::path!("hello" / String)
        // build proxy address and base path data from current filter
        .map(|port| (format!("http://127.0.0.1:{}/", port), "".to_string()))
        .untuple_one()
        // build the request with data from previous filters
        .and(request_filter)
        .and_then(proxy_to_and_forward_response)
        .and_then(log_response);

    // spawn proxy server
    warp::serve(app).run(([0, 0, 0, 0], 3030)).await;
}

Requests client initialization

By default, a simple reqwests::Client is initialized and used. In case some specific client configuration need to be used it can be overridden:

use warp_reverse_proxy::{reverse_proxy_filter, CLIENT as PROXY_CLIENT};

#[tokio::main]
async fn main() {
    let client = reqwest::Client::builder()
        .default_headers(headers)
        .build().expect("client goes boom...");
    PROXY_CLIENT.set(client).expect("client couldn't be set");
    ...
}

Dependencies

~11–25MB
~385K SLoC