diff --git a/src/lib.rs b/src/lib.rs index 942ccc5..d496553 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,87 @@ +//! +//! A simple reverse proxy, to be used with [Hyper]. +//! +//! The implementation ensures that [Hop-by-hop headers] are stripped correctly in both directions, +//! and adds the client's IP address to a comma-space-separated list of forwarding addresses in the +//! `X-Forwarded-For` header. +//! +//! The implementation is based on Go's [`httputil.ReverseProxy`]. +//! +//! [Hyper]: http://hyper.rs/ +//! [Hop-by-hop headers]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html +//! [`httputil.ReverseProxy`]: https://golang.org/pkg/net/http/httputil/#ReverseProxy +//! +//! # Example +//! +//! Add these dependencies to your `Cargo.toml` file. +//! +//! ``` +//! [dependencies] +//! hyper-reverse-proxy = "0.3.0" +//! hyper = "0.12.24" +//! futures = "0.1" +//! ``` +//! +//! The following example will set up a reverse proxy listening on `127.0.0.1:13900`, +//! and will proxy these calls: +//! +//! * `"/target/first"` will be proxied to `http://127.0.0.1:13901` +//! +//! * `"/target/second"` 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,no_run +//! extern crate hyper; +//! extern crate hyper_reverse_proxy; +//! extern crate futures; +//! +//! use hyper::server::conn::AddrStream; +//! use hyper::{Body, Request, Response, Server}; +//! use hyper::service::{service_fn, make_service_fn}; +//! use futures::future::{self, Future}; +//! +//! type BoxFut = Box, Error=hyper::Error> + Send>; +//! +//! fn debug_request(req: Request) -> BoxFut { +//! let body_str = format!("{:?}", req); +//! let response = Response::new(Body::from(body_str)); +//! Box::new(future::ok(response)) +//! } +//! +//! fn main() { +//! +//! // This is our socket address... +//! let addr = ([127, 0, 0, 1], 13900).into(); +//! +//! // A `Service` is needed for every connection, so this +//! // creates one from our `hello_world` function. +//! let make_svc = make_service_fn(|socket: &AddrStream| { +//! let remote_addr = socket.remote_addr(); +//! service_fn(move |req: Request| { // returns BoxFut +//! +//! // Auth +//! if req.uri().path().starts_with("/target/first") { +//! return hyper_reverse_proxy::call(remote_addr.ip(), "http://127.0.0.1:13901", req) +//! } else if req.uri().path().starts_with("/target/second") { +//! return hyper_reverse_proxy::call(remote_addr.ip(), "http://127.0.0.1:13902", req) +//! } else { +//! debug_request(req) +//! } +//! }) +//! }); +//! +//! let server = Server::bind(&addr) +//! .serve(make_svc) +//! .map_err(|e| eprintln!("server error: {}", e)); +//! +//! println!("Running server on {:?}", addr); +//! +//! // Run this server for... forever! +//! hyper::rt::run(server); +//! } +//! ``` +//! extern crate hyper; extern crate futures;