diff --git a/examples/reverse-proxy/Cargo.toml b/examples/reverse-proxy/Cargo.toml new file mode 100644 index 00000000..4a13668f --- /dev/null +++ b/examples/reverse-proxy/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "example-reverse-proxy" +version = "0.1.0" +edition = "2018" + +[dependencies] +axum = { path = "../.." } +hyper = { version = "0.14", features = ["full"] } +tokio = { version = "1", features = ["full"] } +tracing = "0.1" +tracing-subscriber = "0.2" diff --git a/examples/reverse-proxy/src/main.rs b/examples/reverse-proxy/src/main.rs new file mode 100644 index 00000000..5ea93744 --- /dev/null +++ b/examples/reverse-proxy/src/main.rs @@ -0,0 +1,63 @@ +//! Reverse proxy listening in "localhost:4000" will proxy all requests to "localhost:3000" +//! endpoint. +//! +//! Run with +//! +//! ```not_rust +//! cargo run -p example-reverse-proxy +//! ``` + +use axum::{ + extract::Extension, + handler::get, + http::{uri::Uri, Request, Response}, + AddExtensionLayer, Router, +}; +use hyper::{client::HttpConnector, Body}; +use std::{convert::TryFrom, net::SocketAddr}; + +type Client = hyper::client::Client; + +#[tokio::main] +async fn main() { + tokio::spawn(server()); + + let client = Client::new(); + + let app = Router::new() + .route("/", get(handler)) + .layer(AddExtensionLayer::new(client)); + + let addr = SocketAddr::from(([127, 0, 0, 1], 4000)); + println!("reverse proxy listening on {}", addr); + axum::Server::bind(&addr) + .serve(app.into_make_service()) + .await + .unwrap(); +} + +async fn handler(Extension(client): Extension, mut req: Request) -> Response { + let path = req.uri().path(); + let path_query = req + .uri() + .path_and_query() + .map(|v| v.as_str()) + .unwrap_or(path); + + let uri = format!("http://127.0.0.1:3000{}", path_query); + + *req.uri_mut() = Uri::try_from(uri).unwrap(); + + client.request(req).await.unwrap() +} + +async fn server() { + let app = Router::new().route("/", get(|| async { "Hello, world!" })); + + let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); + println!("server listening on {}", addr); + axum::Server::bind(&addr) + .serve(app.into_make_service()) + .await + .unwrap(); +}