From 6f100a7645220cfac76ee30bac4be1816855869d Mon Sep 17 00:00:00 2001 From: Taylor Vann Date: Sat, 15 Aug 2026 23:31:15 -0700 Subject: [PATCH 1/2] no need for response workspace, no need for workspaces actually --- Cargo.toml | 2 +- response/Cargo.toml | 15 --------- reverse_proxy/Cargo.toml | 3 +- reverse_proxy/src/addresses.rs | 19 +++++++----- reverse_proxy/src/config.rs | 16 +++++++--- reverse_proxy/src/errors.rs | 26 ++++++++++++++++ reverse_proxy/src/main.rs | 31 +++++++++++++------ {response => reverse_proxy}/src/requests.rs | 3 +- .../lib.rs => reverse_proxy/src/response.rs | 2 +- reverse_proxy/src/service.rs | 7 +++-- 10 files changed, 80 insertions(+), 44 deletions(-) delete mode 100644 response/Cargo.toml create mode 100644 reverse_proxy/src/errors.rs rename {response => reverse_proxy}/src/requests.rs (97%) rename response/src/lib.rs => reverse_proxy/src/response.rs (99%) diff --git a/Cargo.toml b/Cargo.toml index 9f37d44..3a31358 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["response", "reverse_proxy"] +members = ["reverse_proxy"] [workspace.dependencies] bytes = "1.11" diff --git a/response/Cargo.toml b/response/Cargo.toml deleted file mode 100644 index 374f7f9..0000000 --- a/response/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "response" -version = "0.2.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bytes = { workspace = true } -http-body-util = { workspace = true } -hyper = { workspace = true } -hyper-util = { workspace = true } -native-tls = { workspace = true } -tokio = { workspace = true } -tokio-native-tls = { workspace = true } diff --git a/reverse_proxy/Cargo.toml b/reverse_proxy/Cargo.toml index 2c1e783..de0d7ec 100644 --- a/reverse_proxy/Cargo.toml +++ b/reverse_proxy/Cargo.toml @@ -13,4 +13,5 @@ tokio = { workspace = true } tokio-native-tls = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } -response = { path = "../response" } +http-body-util = { workspace = true } +bytes = { workspace = true } \ No newline at end of file diff --git a/reverse_proxy/src/addresses.rs b/reverse_proxy/src/addresses.rs index 4d06275..3e6cdf1 100644 --- a/reverse_proxy/src/addresses.rs +++ b/reverse_proxy/src/addresses.rs @@ -1,10 +1,9 @@ use crate::config::Config; +use crate::errors::Error; +use crate::response::{AddressMap, AddressParams}; use hyper::Uri; -use response::{AddressMap, AddressParams}; -// Three map errors - -pub fn create_address_map(config: &Config) -> Result { +pub fn create_address_map(config: &Config) -> Result { let mut hashmap = AddressMap::new(); if let Err(e) = add_addresses_to_map(&mut hashmap, &config.addresses, false) { return Err(e); @@ -23,21 +22,25 @@ fn add_addresses_to_map( url_map: &mut AddressMap, addresses: &Vec<(String, String)>, is_dangerous: bool, -) -> Result<(), String> { +) -> Result<(), Error> { for (source_str, target_str) in addresses { let source_uri = match Uri::try_from(source_str) { Ok(uri) => uri, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Uri(e)), }; let source_host = match source_uri.host() { Some(h) => h, - _ => return Err("could not parse host from source uri".to_string()), + _ => { + return Err(Error::Custom( + "could not parse host from source uri".to_string(), + )) + } }; let uri = match Uri::try_from(target_str) { Ok(uri) => uri, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Uri(e)), }; url_map.insert(source_host.to_string(), AddressParams { uri, is_dangerous }); diff --git a/reverse_proxy/src/config.rs b/reverse_proxy/src/config.rs index e3453b0..e93afde 100644 --- a/reverse_proxy/src/config.rs +++ b/reverse_proxy/src/config.rs @@ -4,6 +4,8 @@ use std::path; use std::path::PathBuf; use tokio::fs; +use crate::errors::Error; + #[derive(Clone, Serialize, Deserialize, Debug)] pub struct Config { pub host_and_port: String, @@ -15,25 +17,29 @@ pub struct Config { // Serde path fs errors in one function -pub async fn from_filepath(filepath: &PathBuf) -> Result { +pub async fn from_filepath(filepath: &PathBuf) -> Result { let config_path = match path::absolute(filepath) { Ok(pb) => pb, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Io(e)), }; let json_as_str = match fs::read_to_string(&config_path).await { Ok(r) => r, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Io(e)), }; let parent_dir = match config_path.parent() { Some(p) => p.to_path_buf(), - _ => return Err("parent directory of config not found".to_string()), + _ => { + return Err(Error::Custom( + "parent directory of config not found".to_string(), + )) + } }; let mut config: Config = match serde_json::from_str(&json_as_str) { Ok(j) => j, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::SerdeJson(e)), }; config.key_filepath = parent_dir.join(&config.key_filepath); diff --git a/reverse_proxy/src/errors.rs b/reverse_proxy/src/errors.rs new file mode 100644 index 0000000..6fd83e2 --- /dev/null +++ b/reverse_proxy/src/errors.rs @@ -0,0 +1,26 @@ +use hyper::http::uri::InvalidUri; +use native_tls::Error as NativeTlsError; +use serde_json::Error as SerdeJsonError; +use std::fmt; +use std::io::Error as IoError; + +#[derive(Debug)] +pub enum Error { + Io(IoError), + SerdeJson(SerdeJsonError), + NativeTls(NativeTlsError), + Uri(InvalidUri), + Custom(String), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Io(err) => write!(f, "{}", err), + Error::NativeTls(err) => write!(f, "{}", err), + Error::SerdeJson(err) => write!(f, "{}", err), + Error::Uri(err) => write!(f, "{}", err), + Error::Custom(err) => write!(f, "{}", err), + } + } +} diff --git a/reverse_proxy/src/main.rs b/reverse_proxy/src/main.rs index b93946e..31af262 100644 --- a/reverse_proxy/src/main.rs +++ b/reverse_proxy/src/main.rs @@ -8,18 +8,28 @@ use tokio::net::TcpListener; mod addresses; mod config; +mod errors; +mod requests; +mod response; mod service; +use crate::errors::Error; + // Needs to be errors // create key errors #[tokio::main] -async fn main() -> Result<(), String> { +async fn main() -> Result<(), Error> { // create config let args = match env::args().nth(1) { Some(a) => path::PathBuf::from(a), - None => return Err("argument error: argv[0] config path not provided".to_string()), + None => { + return Err(Error::Custom( + "argument error: argv[0] config path not provided".to_string(), + )) + } }; + let config = match config::from_filepath(&args).await { Ok(c) => c, Err(e) => return Err(e), @@ -34,27 +44,27 @@ async fn main() -> Result<(), String> { // tls cert and keys let cert = match fs::read(&config.cert_filepath).await { Ok(f) => f, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Io(e)), }; let key = match fs::read(&config.key_filepath).await { Ok(f) => f, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Io(e)), }; let identity = match Identity::from_pkcs8(&cert, &key) { Ok(pk) => pk, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::NativeTls(e)), }; // create tls acceptor let tls_acceptor = match native_tls::TlsAcceptor::new(identity) { Ok(acceptor) => tokio_native_tls::TlsAcceptor::from(acceptor), - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::NativeTls(e)), }; // bind tcp listeners let listener = match TcpListener::bind(&config.host_and_port).await { Ok(l) => l, - Err(e) => return Err(e.to_string()), + Err(e) => return Err(Error::Io(e)), }; println!("Reverse Proxy: {}", &config.host_and_port); @@ -62,7 +72,7 @@ async fn main() -> Result<(), String> { loop { let (socket, _remote_addr) = match listener.accept().await { Ok(s) => s, - Err(e) => return Err(e.to_string()), + Err(_e) => continue, }; let acceptor = tls_acceptor.clone(); @@ -74,7 +84,10 @@ async fn main() -> Result<(), String> { tokio::task::spawn(async move { let io = match acceptor.accept(socket).await { Ok(s) => TokioIo::new(s), - Err(_e) => return, + Err(e) => { + println!("{}", e); + return; + } }; if let Err(e) = Builder::new(TokioExecutor::new()) diff --git a/response/src/requests.rs b/reverse_proxy/src/requests.rs similarity index 97% rename from response/src/requests.rs rename to reverse_proxy/src/requests.rs index ef5c98d..188640d 100644 --- a/response/src/requests.rs +++ b/reverse_proxy/src/requests.rs @@ -16,7 +16,8 @@ const FAILED_TO_PROCESS_REQUEST_ERROR: &str = "failed to process request"; fn get_host_and_authority<'a>(uri: &Uri) -> Result<(String, String), &'a str> { let host = match uri.host() { Some(h) => h.to_string(), - _ => return Err("failed to retrieve URI from upstream URI"), + _ => return Err("failed to retrieve downstream URI from upstream URI"), + // _ => return Err(Error::Custom("failed to retrieve downstream URI from upstream URI".to_string())), }; let port = match uri.port() { diff --git a/response/src/lib.rs b/reverse_proxy/src/response.rs similarity index 99% rename from response/src/lib.rs rename to reverse_proxy/src/response.rs index 0c614ac..4cfe810 100644 --- a/response/src/lib.rs +++ b/reverse_proxy/src/response.rs @@ -6,7 +6,7 @@ use hyper::{header, Request, Response, StatusCode, Uri}; use std::collections::HashMap; use std::sync::Arc; -mod requests; +use crate::requests; pub type BoxedResponse = Response>; diff --git a/reverse_proxy/src/service.rs b/reverse_proxy/src/service.rs index 373f6c5..73c59ff 100644 --- a/reverse_proxy/src/service.rs +++ b/reverse_proxy/src/service.rs @@ -1,7 +1,8 @@ +use crate::response::{build_response, AddressMap, BoxedResponse}; use hyper::body::Incoming; +use hyper::http; use hyper::service::Service; use hyper::Request; -use response::{build_response, AddressMap}; use std::future::Future; use std::pin::Pin; use std::sync::Arc; @@ -11,8 +12,8 @@ pub struct Svc { } impl Service> for Svc { - type Response = response::BoxedResponse; - type Error = hyper::http::Error; + type Response = BoxedResponse; + type Error = http::Error; type Future = Pin> + Send>>; fn call(&self, req: Request) -> Self::Future { From c98d86d3e38b40cc918cae720fb8bfc82ff49074 Mon Sep 17 00:00:00 2001 From: Taylor Vann Date: Sun, 16 Aug 2026 07:54:34 -0700 Subject: [PATCH 2/2] de-workspace --- Cargo.toml | 9 +++++---- reverse_proxy/Cargo.toml | 17 ----------------- {reverse_proxy/src => src}/addresses.rs | 2 +- {reverse_proxy/src => src}/config.rs | 2 +- {reverse_proxy/src => src}/errors.rs | 0 {reverse_proxy/src => src}/main.rs | 5 +---- {reverse_proxy/src => src}/requests.rs | 10 +++++----- {reverse_proxy/src => src}/response.rs | 6 +++--- {reverse_proxy/src => src}/service.rs | 4 ++-- 9 files changed, 18 insertions(+), 37 deletions(-) delete mode 100644 reverse_proxy/Cargo.toml rename {reverse_proxy/src => src}/addresses.rs (98%) rename {reverse_proxy/src => src}/config.rs (98%) rename {reverse_proxy/src => src}/errors.rs (100%) rename {reverse_proxy/src => src}/main.rs (97%) rename {reverse_proxy/src => src}/requests.rs (98%) rename {reverse_proxy/src => src}/response.rs (97%) rename {reverse_proxy/src => src}/service.rs (90%) diff --git a/Cargo.toml b/Cargo.toml index 3a31358..805ba61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,9 @@ -[workspace] -resolver = "2" -members = ["reverse_proxy"] +[package] +name = "reverse_proxy" +version = "0.2.1" +edition = "2024" -[workspace.dependencies] +[dependencies] bytes = "1.11" http-body-util = "0.1" hyper = { version = "1.9", features = ["full"] } diff --git a/reverse_proxy/Cargo.toml b/reverse_proxy/Cargo.toml deleted file mode 100644 index de0d7ec..0000000 --- a/reverse_proxy/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "reverse_proxy" -version = "0.2.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -hyper = { workspace = true } -hyper-util = { workspace = true } -native-tls = { workspace = true } -tokio = { workspace = true } -tokio-native-tls = { workspace = true } -serde = { workspace = true } -serde_json = { workspace = true } -http-body-util = { workspace = true } -bytes = { workspace = true } \ No newline at end of file diff --git a/reverse_proxy/src/addresses.rs b/src/addresses.rs similarity index 98% rename from reverse_proxy/src/addresses.rs rename to src/addresses.rs index 3e6cdf1..0c7b1a3 100644 --- a/reverse_proxy/src/addresses.rs +++ b/src/addresses.rs @@ -34,7 +34,7 @@ fn add_addresses_to_map( _ => { return Err(Error::Custom( "could not parse host from source uri".to_string(), - )) + )); } }; diff --git a/reverse_proxy/src/config.rs b/src/config.rs similarity index 98% rename from reverse_proxy/src/config.rs rename to src/config.rs index e93afde..07cbaf0 100644 --- a/reverse_proxy/src/config.rs +++ b/src/config.rs @@ -33,7 +33,7 @@ pub async fn from_filepath(filepath: &PathBuf) -> Result { _ => { return Err(Error::Custom( "parent directory of config not found".to_string(), - )) + )); } }; diff --git a/reverse_proxy/src/errors.rs b/src/errors.rs similarity index 100% rename from reverse_proxy/src/errors.rs rename to src/errors.rs diff --git a/reverse_proxy/src/main.rs b/src/main.rs similarity index 97% rename from reverse_proxy/src/main.rs rename to src/main.rs index 31af262..e31736d 100644 --- a/reverse_proxy/src/main.rs +++ b/src/main.rs @@ -15,9 +15,6 @@ mod service; use crate::errors::Error; -// Needs to be errors -// create key errors - #[tokio::main] async fn main() -> Result<(), Error> { // create config @@ -26,7 +23,7 @@ async fn main() -> Result<(), Error> { None => { return Err(Error::Custom( "argument error: argv[0] config path not provided".to_string(), - )) + )); } }; diff --git a/reverse_proxy/src/requests.rs b/src/requests.rs similarity index 98% rename from reverse_proxy/src/requests.rs rename to src/requests.rs index 188640d..2234e0d 100644 --- a/reverse_proxy/src/requests.rs +++ b/src/requests.rs @@ -3,7 +3,7 @@ use http_body_util::combinators::BoxBody; use http_body_util::{BodyExt, Full}; use hyper::body::Incoming; use hyper::client::conn::{http1, http2}; -use hyper::{header, Request, Response, StatusCode, Uri}; +use hyper::{Request, Response, StatusCode, Uri, header}; use hyper_util::rt::{TokioExecutor, TokioIo}; use native_tls::TlsConnector; use tokio::net::TcpStream; @@ -91,7 +91,7 @@ pub async fn send_http1_request( return create_fallback_response( &StatusCode::SERVICE_UNAVAILABLE, &UPSTREAM_HANDSHAKE_ERROR, - ) + ); } }; @@ -126,7 +126,7 @@ pub async fn send_http1_tls_request( return create_fallback_response( &StatusCode::SERVICE_UNAVAILABLE, &UPSTREAM_HANDSHAKE_ERROR, - ) + ); } }; @@ -160,7 +160,7 @@ pub async fn send_http2_request( return create_fallback_response( &StatusCode::SERVICE_UNAVAILABLE, &UPSTREAM_HANDSHAKE_ERROR, - ) + ); } }; @@ -195,7 +195,7 @@ pub async fn send_http2_tls_request( return create_fallback_response( &StatusCode::SERVICE_UNAVAILABLE, &UPSTREAM_HANDSHAKE_ERROR, - ) + ); } }; diff --git a/reverse_proxy/src/response.rs b/src/response.rs similarity index 97% rename from reverse_proxy/src/response.rs rename to src/response.rs index 4cfe810..a725d04 100644 --- a/reverse_proxy/src/response.rs +++ b/src/response.rs @@ -2,7 +2,7 @@ use bytes::Bytes; use http_body_util::combinators::BoxBody; use hyper::body::Incoming; use hyper::http::uri::InvalidUriParts; -use hyper::{header, Request, Response, StatusCode, Uri}; +use hyper::{Request, Response, StatusCode, Uri, header}; use std::collections::HashMap; use std::sync::Arc; @@ -31,7 +31,7 @@ pub async fn build_response( return requests::create_fallback_response( &StatusCode::BAD_REQUEST, &URI_FROM_REQUEST_ERROR, - ) + ); } }; @@ -42,7 +42,7 @@ pub async fn build_response( return requests::create_fallback_response( &StatusCode::BAD_GATEWAY, &URI_FROM_REQUEST_ERROR, - ) + ); } }; diff --git a/reverse_proxy/src/service.rs b/src/service.rs similarity index 90% rename from reverse_proxy/src/service.rs rename to src/service.rs index 73c59ff..02d92f7 100644 --- a/reverse_proxy/src/service.rs +++ b/src/service.rs @@ -1,8 +1,8 @@ -use crate::response::{build_response, AddressMap, BoxedResponse}; +use crate::response::{AddressMap, BoxedResponse, build_response}; +use hyper::Request; use hyper::body::Incoming; use hyper::http; use hyper::service::Service; -use hyper::Request; use std::future::Future; use std::pin::Pin; use std::sync::Arc;