use color_eyre::eyre::Result; use hyper::service::{make_service_fn, service_fn}; use hyper::upgrade::Upgraded; use hyper::{Body, Request, Response, Server}; use std::convert::Infallible; use std::net::{SocketAddr, ToSocketAddrs}; use structopt::StructOpt; use tokio_socks::IntoTargetAddr; #[derive(StructOpt, Debug)] #[structopt(name = "sthp")] struct Cli { #[structopt(short, long, default_value = "8080")] /// port where Http proxy should listen port: u16, /// Socks5 proxy address #[structopt(short, long, default_value = "127.0.0.1:1080")] socks_address: String, } #[tokio::main] async fn main() { let args = Cli::from_args(); let socks_address = args.socks_address; let socks_address = socks_address.to_socket_addrs().unwrap().next().unwrap(); let port = args.port; let addr = SocketAddr::from(([127, 0, 0, 1], port)); let make_service = make_service_fn(move |_| { let socks_address = socks_address.clone(); async move { Ok::<_, Infallible>(service_fn(move |req| proxy(req, socks_address.clone()))) } }); let server = Server::bind(&addr) .http1_preserve_header_case(true) .http1_title_case_headers(true) .serve(make_service); println!("Server is listening on {}", addr); if let Err(e) = server.await { eprintln!("{:?}", e); }; } async fn proxy(req: Request
, socks_address: SocketAddr) -> Result