From 598b99252e2e02325b43daccca2212b5ce77c7aa Mon Sep 17 00:00:00 2001 From: Stefan Sundin Date: Thu, 16 May 2024 21:16:47 -0700 Subject: [PATCH] Update README.md a bit. --- README.md | 106 ++++++------------------------------------------------ 1 file changed, 10 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index 9055a87..4fabde9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # This is a fork -This repo contains a fork of the[original hyper-reverse-proxy +This repo contains a fork of the [original hyper-reverse-proxy codebase][upstream], adding to it a few improvements: - Fix to a bug where the `Host` header was getting overwritten on the upstream @@ -17,13 +17,10 @@ Plus more as time goes on. # hyper-reverse-proxy [![License][license-img]](LICENSE) -[![CI][ci-img]][ci-url] [![docs][docs-img]][docs-url] [![version][version-img]][version-url] [license-img]: https://img.shields.io/crates/l/hyper-reverse-proxy.svg -[ci-img]: https://github.com/felipenoris/hyper-reverse-proxy/workflows/CI/badge.svg -[ci-url]: https://github.com/felipenoris/hyper-reverse-proxy/actions/workflows/main.yml [docs-img]: https://docs.rs/hyper-reverse-proxy/badge.svg [docs-url]: https://docs.rs/hyper-reverse-proxy [version-img]: https://img.shields.io/crates/v/hyper-reverse-proxy.svg @@ -43,108 +40,25 @@ The implementation is based on Go's [`httputil.ReverseProxy`]. # Example -Add these dependencies to your `Cargo.toml` file. +Run the example by cloning this repository and running: -```toml -[dependencies] -hyper-reverse-proxy = "?" -hyper = { version = "?", features = ["full"] } -tokio = { version = "?", features = ["full"] } -lazy_static = "?" -hyper-trust-dns = { version = "?", features = [ - "rustls-http2", - "dnssec-ring", - "dns-over-https-rustls", - "rustls-webpki", - "https-only" -] } +```shell +cargo run --example simple ``` -The following example will set up a reverse proxy listening on `127.0.0.1:13900`, -and will proxy these calls: +The example will set up a reverse proxy listening on `127.0.0.1:8000`, and will proxy these calls: -* `"/target/first"` will be proxied to `http://127.0.0.1:13901` +* `http://service1.localhost:8000` will be proxied to `http://127.0.0.1:13901` -* `"/target/second"` will be proxied to `http://127.0.0.1:13902` +* `http://service2.localhost:8000` will be proxied to `http://127.0.0.1:13902` -* All other URLs will be handled by `debug_request` function, that will display request information. - -```rust -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); - } -} -``` +* All other URLs will display request information. ### A word about Security Handling outgoing requests can be a security nightmare. This crate does not control the client for the outgoing requests, as it needs to be supplied to the proxy call. The following chapters may give you an overview on how you can secure your client using the `hyper-trust-dns` crate. -> You can see them being used in the example. +> You can see them being used in the example. #### HTTPS @@ -164,7 +78,7 @@ As dns queries and entries aren't "trustworthy" by default from a security stand #### HTTP/2 -By default only rustlss `http1` feature is enabled for dns queries. While `http/3` might be just around the corner. `http/2` support can be enabled using the `rustls-http2` feature. +By default only rustls `http1` feature is enabled for dns queries. While `http/3` might be just around the corner. `http/2` support can be enabled using the `rustls-http2` feature. #### DoT & DoH