rcs_backend 0.2.1

otafablab rust code server backend
Documentation
use hyper::service::{make_service_fn, service_fn};
use hyper::{Client, Server};
use rcs_backend::config::Config;
use rcs_backend::proxy::proxy;
use std::convert::Infallible;
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(Debug, StructOpt, Clone)]
struct Opt {
    /// Path to configuration file. If left out, default configuration will be used.
    #[structopt(short, long)]
    config: Option<PathBuf>,
}

#[tokio::main]
async fn main() {
    let opt = Opt::from_args();

    let config = match opt.config.map(Config::open) {
        Some(Ok(config)) => config,
        Some(Err(error)) => panic!("{:?}", error),
        None => Config::default(),
    };
    let config = Box::new(config);

    let addr = config.listen_address;
    let client = Client::builder()
        .http1_title_case_headers(true)
        .http1_preserve_header_case(true)
        .build_http();

    let leak: &'static Config = Box::leak(config.clone());
    // The closure inside `make_service_fn` is run for each connection
    let make_service = make_service_fn(move |_| {
        let client = client.clone();
        async move { Ok::<_, Infallible>(service_fn(move |req| proxy(client.clone(), req, leak))) }
    });

    let server = Server::bind(&addr)
        .http1_preserve_header_case(true)
        .http1_title_case_headers(true)
        .serve(make_service);

    println!("Listening on http://{}", addr);

    if let Err(e) = server.await {
        eprintln!("server error: {}", e);
    }
}