diff --git a/Cargo.lock b/Cargo.lock index 425b5d6..1736077 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,19 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "addr2line" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" -dependencies = [ - "gimli", -] +version = 3 [[package]] -name = "adler" -version = "1.0.2" +name = "anyhow" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" [[package]] name = "autocfg" @@ -21,21 +14,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "backtrace" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "bitflags" version = "1.2.1" @@ -48,12 +26,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" -[[package]] -name = "cc" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" - [[package]] name = "cfg-if" version = "1.0.0" @@ -71,35 +43,12 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "color-eyre" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f1885697ee8a177096d42f158922251a41973117f6d8a234cee94b9509157b7" -dependencies = [ - "backtrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", -] - [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "eyre" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221239d1d5ea86bf5d6f91c9d6bc3646ffe471b08ff9b0f91c44f115ac969d2b" -dependencies = [ - "indenter", - "once_cell", -] - [[package]] name = "fnv" version = "1.0.7" @@ -134,12 +83,6 @@ dependencies = [ "syn", ] -[[package]] -name = "futures-sink" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" - [[package]] name = "futures-task" version = "0.3.15" @@ -163,37 +106,6 @@ dependencies = [ "slab", ] -[[package]] -name = "gimli" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" - -[[package]] -name = "h2" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" - [[package]] name = "heck" version = "0.3.3" @@ -205,9 +117,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -248,21 +160,20 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" [[package]] name = "hyper" -version = "0.14.8" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f71a7eea53a3f8257a7b4795373ff886397178cd634430ea94e12d7fe4fe34" +checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", "http", "http-body", "httparse", "httpdate", "itoa", - "pin-project", + "pin-project-lite", "socket2", "tokio", "tower-service", @@ -270,22 +181,6 @@ dependencies = [ "want", ] -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "itoa" version = "0.4.7" @@ -300,9 +195,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "log" @@ -319,21 +214,11 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] - [[package]] name = "mio" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" dependencies = [ "libc", "log", @@ -370,52 +255,11 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bc1d42047cf336f0f939c99e97183cf31551bf0f2865a2ec9c8d91fd4ffb5e" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" - -[[package]] -name = "owo-colors" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" - -[[package]] -name = "pin-project" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -477,12 +321,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rustc-demangle" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce" - [[package]] name = "slab" version = "0.4.3" @@ -503,7 +341,7 @@ dependencies = [ name = "sthp" version = "0.1.0" dependencies = [ - "color-eyre", + "anyhow", "futures-util", "http", "hyper", @@ -538,9 +376,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -578,9 +416,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a38d31d7831c6ed7aad00aa4c12d9375fd225a6dd77da1d25b707346319a975" +checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" dependencies = [ "autocfg", "bytes", @@ -590,6 +428,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "tokio-macros", + "winapi", ] [[package]] @@ -615,20 +454,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-util" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - [[package]] name = "tower-service" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 273555c..7c4d720 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,10 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -futures-util = "0.3.15" -http = "0.2.4" -hyper = { version = "0.14", features = ["http2", "server", "tcp"] } -structopt = { version = "0.3", default-features = false } +futures-util= "0.3" +http = "0.2" +hyper = { version = "0.14", features = ["http1", "server", "tcp"]} +structopt = { version="0.3", default-features = false} tokio-socks = "0.5" -tokio = { version = "1.6", features = ["macros", "rt-multi-thread"] } -color-eyre = { version = "0.5", default-features = false } +tokio = { version = "1.7", features = ["macros", "rt-multi-thread"] } +anyhow = "1.0.41" \ No newline at end of file diff --git a/README.md b/README.md index 9cd9bbb..c97cca9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# socks-to-http ![Rust](https://github.com/KaranGauswami/socks-to-http/workflows/Rust/badge.svg) ![release](https://img.shields.io/github/v/release/KaranGauswami/socks-to-http?include_prereleases) +# socks-to-http-proxy ![Rust](https://github.com/KaranGauswami/socks-to-http-proxy/workflows/Rust/badge.svg) ![release](https://img.shields.io/github/v/release/KaranGauswami/socks-to-http-proxy?include_prereleases) An executable to convert SOCKS5 proxy into HTTP proxy @@ -6,27 +6,25 @@ An executable to convert SOCKS5 proxy into HTTP proxy `sthp` purpose is to create HTTP proxy on top of the Socks 5 Proxy - ## How it works It uses hyper library HTTP proxy example and adds functionality to connect via Socks5 - ## Compiling Follow these instructions to compile - 1. Ensure you have current version of `cargo` and [Rust](https://www.rust-lang.org) installed - 2. Clone the project `$ git clone https://github.com/KaranGauswami/socks-to-http.git && cd socks-to-http` - 3. Build the project `$ cargo build --release` - 4. Once complete, the binary will be located at `target/release/sthp` - +1. Ensure you have current version of `cargo` and [Rust](https://www.rust-lang.org) installed +2. Clone the project `$ git clone https://github.com/KaranGauswami/socks-to-http-proxy.git && cd socks-to-http-proxy` +3. Build the project `$ cargo build --release` +4. Once complete, the binary will be located at `target/release/sthp` ## Usage ```bash sthp -p 8080 -s 127.0.0.1:1080 ``` + This will create proxy server on 8080 and use localhost:1080 as a Socks5 Proxy ### Options @@ -46,7 +44,6 @@ OPTIONS: -s, --socks-address Socks5 proxy address [default: 127.0.0.1:1080] ``` - ## License `sthp` is released under the terms of either the MIT or Apache 2.0 license. See the LICENSE-MIT or LICENSE-APACHE file for the details. diff --git a/src/main.rs b/src/main.rs index ada7519..ebe8993 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,15 @@ -use color_eyre::eyre::Result; -use futures_util::future::try_join; -use hyper::server::Server; +use anyhow::Result; use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Request, Response}; +use hyper::upgrade::Upgraded; +use hyper::{Body, Request, Response, Server}; use std::convert::Infallible; -use std::net::{SocketAddr, ToSocketAddrs}; +use std::net::SocketAddr; use structopt::StructOpt; +use tokio_socks::tcp::Socks5Stream; use tokio_socks::IntoTargetAddr; #[derive(StructOpt, Debug)] -#[structopt(name = "sthp")] +#[structopt(name = "sthp", about = "Convert Socks5 proxy into Http proxy")] struct Cli { #[structopt(short, long, default_value = "8080")] /// port where Http proxy should listen @@ -17,34 +17,29 @@ struct Cli { /// Socks5 proxy address #[structopt(short, long, default_value = "127.0.0.1:1080")] - socks_address: String, + socks_address: SocketAddr, } #[tokio::main] -async fn main() { +async fn main() -> Result<()> { let args = Cli::from_args(); let socks_address = args.socks_address; let port = args.port; let addr = SocketAddr::from(([127, 0, 0, 1], port)); - let socks_address = socks_address.to_socket_addrs().unwrap().next().unwrap(); - let make_service = make_service_fn(move |_| { - let socks_address = socks_address.clone(); - async move { - Ok::<_, Infallible>(service_fn(move |req| { - let socks_address = socks_address.clone(); - proxy(req, socks_address) - })) - } + let make_service = make_service_fn(move |_| async move { + Ok::<_, Infallible>(service_fn(move |req| proxy(req, socks_address.clone()))) }); - let server = Server::bind(&addr).serve(make_service); + 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); }; + Ok(()) } async fn proxy(req: Request, socks_address: SocketAddr) -> Result> { - let _response = Response::new(Body::empty()); - if req.method() == hyper::Method::CONNECT { tokio::task::spawn(async move { let plain = req.uri().authority().unwrap().as_str().to_string(); @@ -59,44 +54,26 @@ async fn proxy(req: Request, socks_address: SocketAddr) -> Result std::io::Result<()> { - let socket_address = socks_address.to_socket_addrs().unwrap().next().unwrap(); - - let target_addr = target_addr.into_target_addr(); - let target_addr = target_addr.unwrap(); - let socks_stream = tokio_socks::tcp::Socks5Stream::connect(socket_address, target_addr) - .await - .expect("Cannot Connect to Socks5 Server"); - - let amounts = { - let (mut server_rd, mut server_wr) = tokio::io::split(socks_stream); - let (mut client_rd, mut client_wr) = tokio::io::split(upgraded); +async fn tunnel<'t, I>(mut upgraded: Upgraded, plain: I, socks_address: SocketAddr) -> Result<()> +where + I: IntoTargetAddr<'t>, +{ + let mut stream = Socks5Stream::connect(socks_address, plain).await?; - let client_to_server = tokio::io::copy(&mut client_rd, &mut server_wr); - let server_to_client = tokio::io::copy(&mut server_rd, &mut client_wr); - - try_join(client_to_server, server_to_client).await - }; + // Proxying data + let (from_client, from_server) = + tokio::io::copy_bidirectional(&mut upgraded, &mut stream).await?; // Print message when done - match amounts { - Ok((from_client, from_server)) => { - println!( - "client wrote {} bytes and received {} bytes", - from_client, from_server - ); - } - Err(e) => { - eprintln!("tunnel error: {}", e); - } - }; + println!( + "client wrote {} bytes and received {} bytes", + from_client, from_server + ); Ok(()) }