use hyper::server::conn::AddrStream; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Request, Response, Server, StatusCode}; use hyper_reverse_proxy::ReverseProxy; use hyper_trust_dns::{RustlsHttpsConnector, TrustDnsResolver}; use std::net::IpAddr; use std::{convert::Infallible, net::SocketAddr}; lazy_static::lazy_static! { static ref PROXY_CLIENT: ReverseProxy = { ReverseProxy::new( hyper::Client::builder().build::<_, hyper::Body>(TrustDnsResolver::default().into_rustls_webpki_https_connector()), ) }; } fn debug_request(req: &Request) -> Result, Infallible> { let body_str = format!("{:?}", req); Ok(Response::new(Body::from(body_str))) } async fn handle(client_ip: IpAddr, req: Request) -> Result, Infallible> { if req.uri().path().starts_with("/target/first") { match PROXY_CLIENT .call(client_ip, "http://127.0.0.1:13901", req) .await { Ok(response) => Ok(response), Err(_error) => Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::empty()) .unwrap()), } } else if req.uri().path().starts_with("/target/second") { match PROXY_CLIENT .call(client_ip, "http://127.0.0.1:13902", req) .await { Ok(response) => Ok(response), Err(_error) => Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::empty()) .unwrap()), } } else { debug_request(&req) } } #[tokio::main] async fn main() { let bind_addr = "127.0.0.1:8000"; let addr: SocketAddr = bind_addr.parse().expect("Could not parse ip:port."); let make_svc = make_service_fn(|conn: &AddrStream| { let remote_addr = conn.remote_addr().ip(); async move { Ok::<_, Infallible>(service_fn(move |req| handle(remote_addr, req))) } }); let server = Server::bind(&addr).serve(make_svc); println!("Running server on {:?}", addr); if let Err(e) = server.await { eprintln!("server error: {}", e); } }