A simple reverse proxy for use with Hyper and Tokio
Go to file
Felipe Noronha aa8947a614 fix tests
2019-02-16 16:01:00 -02:00
src fix tests 2019-02-16 16:01:00 -02:00
.gitignore Initial commit 2017-07-15 16:28:59 +10:00
.travis.yml Initial commit 2017-07-15 16:28:59 +10:00
Cargo.toml update deps 2019-02-16 15:20:18 -02:00
LICENSE Initial commit 2017-07-15 16:28:59 +10:00
README.md update README 2019-02-16 15:46:52 -02:00

hyper-reverse-proxy

Build Status Documentation Version License

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.

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.

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<Future<Item=Response<Body>, Error=hyper::Error> + Send>;

fn debug_request(req: Request<Body>) -> 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<Body>| { // 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);
}