hyper-reverse-proxy 0.2.1

A simple reverse proxy, to be used with Hyper and Tokio.

A simple reverse proxy, to be used with Hyper and Tokio.

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.

Example

Because the reverse proxy needs client, we also need a Handle. This means that we can't take advantage of hyper's handy Http::bind method to quickly set up the server. Instead we do things manually:

extern crate futures;
extern crate hyper;
extern crate hyper_reverse_proxy;
extern crate tokio_core;

use futures::Stream;
use hyper::Client;
use hyper::server::Http;
use hyper_reverse_proxy::ReverseProxy;
use tokio_core::net::TcpListener;
use tokio_core::reactor::Core;
use std::net::{SocketAddr, Ipv4Addr};

fn run() -> hyper::Result<()> {
    // Set up the Tokio reactor core
    let mut core = Core::new()?;
    let handle = core.handle();

    // Set up a TCP socket to listen to
    let listen_addr = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), 8080);
    let listener = TcpListener::bind(&listen_addr, &handle)?;

    // Listen to incoming requests over TCP, and forward them to a new `ReverseProxy`
    let http = Http::new();
    let server = listener.incoming().for_each(|(socket, addr)| {
        let client = Client::new(&handle);
        let service = ReverseProxy::new(client, Some(addr.ip()));
        http.bind_connection(&handle, socket, addr, service);
        Ok(())
    });

    // Start our server on the reactor core
    core.run(server)?;

    Ok(())
}

fn main() {
    use std::io::{self, Write};

    if let Err(error) = run() {
        write!(&mut io::stderr(), "{}", error).expect("Error writing to stderr");
        std::process::exit(1);
    }
}

Note that in a production system we might also want to:

  • listen for SIGINT and SIGTERM signals using tokio_signal
  • shut down the server gracefully, waiting for outstanding requests to complete

To see an example of this, look at examples/extended.rs.