diff --git a/src/lib.rs b/src/lib.rs index a8f1770..a13ba1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,12 +3,27 @@ use std::{ net::TcpStream, }; +#[derive(Debug)] +pub enum Method { + Get, + Post, + Put, + Delete, + Head, + Options, + Patch, + Connect, + Trace, +} + pub mod server; pub mod tls; +#[derive(Debug)] pub struct Request { host: String, path: String, + method: Method, } impl Request { @@ -16,48 +31,98 @@ impl Request { Self { host: url.to_string(), path: String::from("/"), + method: Method::Get, + } + } + + pub fn from_str(host: &str, req: &str) -> Self { + let first_line = req.lines().next().unwrap_or_default(); + let mut parts = first_line.split_whitespace(); + let method = parts.next().unwrap_or_default(); + let path = parts.next().unwrap_or("/"); + + Self { + host: host.to_string(), + path: path.to_string(), + method: match method { + "GET" => Method::Get, + "POST" => Method::Post, + "PUT" => Method::Put, + "DELETE" => Method::Delete, + "HEAD" => Method::Head, + "OPTIONS" => Method::Options, + "PATCH" => Method::Patch, + "CONNECT" => Method::Connect, + "TRACE" => Method::Trace, + _ => Method::Get, + }, } } } impl Request { - pub fn send(&self) -> String { + pub fn send_bytes(&self) -> Vec { let tcp = TcpStream::connect((self.host.as_str(), 443)).unwrap(); send_request(tcp, &self.host, &self.to_string()) } + pub fn send(&self) -> String { + let tcp = TcpStream::connect((self.host.as_str(), 443)).unwrap(); + String::from_utf8(send_request(tcp, &self.host, &self.to_string())).unwrap() + } + pub fn send_routed(&self, router: &str) -> String { - let mut tcp = TcpStream::connect((router, 80)).unwrap(); + let mut tcp = TcpStream::connect(router).unwrap(); tcp.write_all(format!("ROUTE {}:443", self.host).as_bytes()) .unwrap(); tcp.read(&mut [0; 32]).unwrap(); - send_request(tcp, &self.host, &self.to_string()) + String::from_utf8(send_request(tcp, &self.host, &self.to_string())).unwrap() } pub fn send_routed_secure(&self, router: &str) -> String { let tcp = TcpStream::connect((router, 443)).unwrap(); send_request( tcp.try_clone().unwrap(), - &self.host, + &router, &format!("ROUTE {}:443", self.host), ); - send_request(tcp, &self.host, &self.to_string()) + String::from_utf8(send_request(tcp, &self.host, &self.to_string())).unwrap() } pub fn to_string(&self) -> String { format!( - "GET {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nUser-Agent: rustls/0.23\r\n\r\n", - self.path, self.host + "{} {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nUser-Agent: rustls/0.23\r\n\r\n", + self.method, self.path, self.host ) } } -pub fn send_request(mut stream: TcpStream, host: &str, send: &str) -> String { +pub fn send_request(mut stream: TcpStream, host: &str, send: &str) -> Vec { let mut conn = tls::tls13_handshake(&host, &mut stream).unwrap(); let mut tls = rustls::Stream::new(&mut conn, &mut stream); tls.write_all(send.as_bytes()).unwrap(); tls.flush().unwrap(); let mut resp = Vec::new(); tls.read_to_end(&mut resp).unwrap(); - String::from_utf8(resp).unwrap() + resp +} + +impl std::fmt::Display for Method { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::Get => "GET", + Self::Post => "POST", + Self::Put => "PUT", + Self::Delete => "DELETE", + Self::Head => "HEAD", + Self::Options => "OPTIONS", + Self::Patch => "PATCH", + Self::Connect => "CONNECT", + Self::Trace => "TRACE", + } + ) + } } diff --git a/src/main.rs b/src/main.rs index 83152c0..4eaec1d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ -use ghostnet_rs::Request; - fn main() { ghostnet_rs::server::run(); - // println!("{}", Request::new("example.com").send_routed_secure("localhost")); - // println!("{}", Request::new("example.com").send_routed("localhost")); - // println!("{}", Request::new("example.com").send()); + // println!( + // "{}", + // ghostnet_rs::Request::new("example.com").send_routed("localhost:6930") + // ); } diff --git a/src/server.rs b/src/server.rs index 7d3f8de..825cc69 100644 --- a/src/server.rs +++ b/src/server.rs @@ -3,10 +3,12 @@ use std::{ net::{TcpListener, TcpStream}, }; +const DEFAULT_HOST: &str = "osui.netlify.app"; + pub fn run() { let server = TcpListener::bind(format!( "0.0.0.0:{}", - std::env::var("PORT").unwrap_or("80".to_string()) + std::env::var("PORT").unwrap_or("6930".to_string()) )) .unwrap(); @@ -14,52 +16,59 @@ pub fn run() { for stream in server.incoming() { match stream { Ok(mut client) => { - println!("Client connected"); - let mut buf = [0; 1024]; + std::thread::spawn(move || { + println!("Client connected"); + let mut buf = [0; 1024]; - let buf_len = client.read(&mut buf).unwrap(); + let buf_len = client.read(&mut buf).unwrap(); - let req = String::from_utf8_lossy(&buf[..buf_len]); - let req = req.lines().collect::>(); + let req = String::from_utf8_lossy(&buf[..buf_len]); + let req = req.lines().collect::>(); - if req.len() == 0 { - continue; - } + if req.len() == 0 { + return; + } - if req[0].starts_with("ROUTE") { - println!("Route mode"); - let addr = req[0].split_once(' ').unwrap().1; - println!("Connecting to {addr}"); - let mut target = TcpStream::connect(addr).unwrap(); - let mut target_t = target.try_clone().unwrap(); - let mut client_t = client.try_clone().unwrap(); - println!("Connected to {addr}"); - client.write_all("CONN EST".as_bytes()).unwrap(); + if req[0].starts_with("ROUTE") { + println!("Route mode"); + let addr = req[0].split_once(' ').unwrap().1; + println!("Connecting to {addr}"); + let mut target = TcpStream::connect(addr).unwrap(); + let mut target_t = target.try_clone().unwrap(); + let mut client_t = client.try_clone().unwrap(); + println!("Connected to {addr}"); + client.write_all("CONN EST".as_bytes()).unwrap(); + + std::thread::spawn(move || { + loop { + let mut buf = [0; 2048]; + let buf_len = client_t.read(&mut buf).unwrap(); + if buf_len == 0 { + target_t.shutdown(std::net::Shutdown::Both).unwrap(); + break; + } + target_t.write_all(&buf[..buf_len]).unwrap(); + } + }); - std::thread::spawn(move || { loop { let mut buf = [0; 2048]; - let buf_len = client_t.read(&mut buf).unwrap(); + let buf_len = target.read(&mut buf).unwrap(); if buf_len == 0 { - target_t.shutdown(std::net::Shutdown::Both).unwrap(); + client.shutdown(std::net::Shutdown::Both).unwrap(); break; } - println!("Client -> Target {:?}", &buf[..buf_len]); - target_t.write_all(&buf[..buf_len]).unwrap(); + client.write_all(&buf[..buf_len]).unwrap(); } - }); - - loop { - let mut buf = [0; 2048]; - let buf_len = target.read(&mut buf).unwrap(); - if buf_len == 0 { - client.shutdown(std::net::Shutdown::Both).unwrap(); - break; - } - println!("Target -> Client {:?}", &buf[..buf_len]); - client.write_all(&buf[..buf_len]).unwrap(); + } else { + let req = crate::Request::from_str( + DEFAULT_HOST, + &String::from_utf8_lossy(&buf[..buf_len]), + ); + client.write_all(&req.send_bytes()).unwrap(); + client.flush().unwrap(); } - } + }); } Err(_) => {}