wstcp 0.2.1

WebSocket to TCP proxy server
Documentation
#[macro_use]
extern crate clap;
#[macro_use]
extern crate trackable;

use async_std::net::TcpListener;
use clap::Arg;
use slog::o;
use sloggers::terminal::{Destination, TerminalLoggerBuilder};
use sloggers::types::SourceLocation;
use sloggers::Build;
use std::net::{SocketAddr, ToSocketAddrs};
use wstcp::{Error, ProxyServer};

macro_rules! try_parse {
    ($expr:expr) => {
        track_any_err!($expr.parse())
    };
}

fn main() -> trackable::result::TopLevelResult {
    let matches = app_from_crate!()
        .arg(
            Arg::with_name("REAL_SERVER_ADDR")
                .help("The TCP address of the real server")
                .index(1)
                .takes_value(true)
                .required(true),
        )
        .arg(
            Arg::with_name("LOG_LEVEL")
                .long("log-level")
                .takes_value(true)
                .default_value("info")
                .possible_values(&["debug", "info", "warning", "error"]),
        )
        .arg(
            Arg::with_name("BIND_ADDR")
                .help("TCP address to which the WebSocket proxy bind")
                .long("bind-addr")
                .takes_value(true)
                .default_value("0.0.0.0:13892"),
        )
        .get_matches();

    let bind_addr: SocketAddr = try_parse!(matches.value_of("BIND_ADDR").unwrap())?;
    let tcp_server_addr: SocketAddr = track_assert_some!(
        track_any_err!(matches
            .value_of("REAL_SERVER_ADDR")
            .unwrap()
            .to_socket_addrs())?
        .next(),
        trackable::error::Failed
    );
    let log_level = try_parse!(matches.value_of("LOG_LEVEL").unwrap())?;
    let logger = track!(TerminalLoggerBuilder::new()
        .source_location(SourceLocation::None)
        .destination(Destination::Stderr)
        .level(log_level)
        .build())?;

    async_std::task::block_on(async {
        let logger = logger.new(
            o!("proxy_addr" => bind_addr.to_string(), "server_addr" => tcp_server_addr.to_string()),
        );
        let listener = track!(TcpListener::bind(bind_addr).await.map_err(Error::from))
            .expect("failed to start listening on the given proxy address");

        let proxy = ProxyServer::new(logger, listener.incoming(), tcp_server_addr)
            .await
            .unwrap_or_else(|e| panic!("{}", e));
        proxy.await.unwrap_or_else(|e| panic!("{}", e));
    });

    Ok(())
}