diff --git a/Cargo.toml b/Cargo.toml index 4bb2b2d..68f346d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ base64 = "0.13.0" figment = { version = "*", features = [ "yaml" ] } mimalloc = { version = "0.1.26", default_features = false } reqwest = { version = "0.11.6", features = [ "stream" ] } -tokio-util = {version="*", features=["compat"]} +tokio-util = {version="*", features=[ "compat" ] } bytes = "*" futures = "0.3.18" diff --git a/src/main.rs b/src/main.rs index e17d557..2c27cd3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -129,11 +129,15 @@ fn rocket() -> _ .expect("services config"); rocket - .mount("/api/v1/posts", ProxyServer::from(&services_conf.blog, "/v1/posts")) + .mount( + "/api/v1/posts", + ProxyServer::from(&services_conf.blog, "/v1/posts"), + ) .mount( "/api/v1/sections", ProxyServer::from(&services_conf.blog, "/v1/sections"), ) + .mount("/yeet", ProxyServer::from("http://localhost:5000", "/")) .manage(jwt_conf) .manage(admin_conf) .attach(AdHoc::try_on_ignite("Create admin user", create_admin_user)) diff --git a/src/proxy.rs b/src/proxy.rs index 8801647..c70443e 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,7 +1,4 @@ -use std::{ - io::Cursor, - path::{Path, PathBuf}, -}; +use std::path::{Path, PathBuf}; use futures::stream::TryStreamExt; use reqwest::{ @@ -10,8 +7,7 @@ use reqwest::{ }; use rocket::{ data::ToByteUnit, - http::{Header, Method}, - response::{stream::ByteStream, Redirect}, + http::{Method, Status}, route::{Handler, Outcome}, Data, Request, Route, }; @@ -82,21 +78,25 @@ impl Handler for ProxyServer { async fn handle<'r>(&self, req: &'r Request<'_>, data: Data<'r>) -> Outcome<'r> { - println!("{:?}", req); - // The goals here is to convert a Rocket request into a reqwest one + // ROCKET REQUEST -> REQWEST REQUEST - // First, we convert the headers + // Headers let mut headers = HeaderMap::new(); for header in req.headers().iter() { - // TODO remove unwrap - headers.insert( - HeaderName::from_lowercase(header.name.into_string().as_bytes()).unwrap(), - HeaderValue::from_str(&header.value.into_owned()).unwrap(), - ); + let name = match HeaderName::from_lowercase(header.name.into_string().as_bytes()) { + Ok(val) => val, + Err(_) => return Outcome::Failure(Status::BadRequest), + }; + let value = match HeaderValue::from_str(&header.value.into_owned()) { + Ok(val) => val, + Err(_) => return Outcome::Failure(Status::BadRequest), + }; + + headers.insert(name, value); } - // Then the method + // Method let method = match req.method() { Method::Delete => ReqMethod::DELETE, Method::Get => ReqMethod::GET, @@ -106,9 +106,12 @@ impl Handler for ProxyServer _ => todo!(), }; - // Then the URL + // URL // We first extract all URL segments starting from the mountpoint - let segments: PathBuf = req.segments(0..).unwrap(); + let segments: PathBuf = match req.segments(0..) { + Ok(val) => val, + Err(_) => return Outcome::Failure(Status::InternalServerError), + }; let query_part = req .uri() @@ -118,8 +121,8 @@ impl Handler for ProxyServer let url = format!( "{}{}/{}{}", self.root, - self.prefix.to_str().unwrap(), - segments.to_str().unwrap(), + self.prefix.to_str().unwrap_or(""), + segments.to_str().unwrap_or(""), query_part ); @@ -127,7 +130,7 @@ impl Handler for ProxyServer // TODO don't hard-code max request size here static BODY_SIZE: i64 = 2; // TODO remove unwrap - let data: Vec = data + let body: Vec = data .open(BODY_SIZE.mebibytes()) .into_bytes() .await @@ -135,16 +138,20 @@ impl Handler for ProxyServer .to_vec(); // TODO remove unwrap + // let body = reqwest::Body::wrap_stream(data); let new_res = reqwest::Client::new() .request(method, url) .headers(headers) - .body(data) + .body(body) .send() .await .unwrap(); let mut res_headers = new_res.headers().clone(); let mut res_builder = rocket::Response::build(); + + // Let us thank this Git repo for showing me how to do this + // https://github.com/benkay86/async-applied/blob/master/reqwest-tokio-compat/src/main.rs let mut res_builder = res_builder .status(rocket::http::Status::new(new_res.status().as_u16())) .streamed_body(