diff --git a/src/proxy.rs b/src/proxy.rs index 912eeea..d2f6148 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -18,12 +18,21 @@ use rocket::{ }; use tokio_util::compat::FuturesAsyncReadCompatExt; +/// This proxy server implementation proxies requests according to prefixes in their URLs. It +/// strips the mounted prefix from the URL & replaces it with the configured prefix beforing +/// proxying the request. This allows mounting a subdirectory of a server on another subdirectory +/// on the proxy (e.g. /api/v1/posts routes to /v1/posts). #[derive(Clone)] pub struct ProxyServer { + /// Base URL of the server to proxy to. This should include the protocol (http or https), as + /// this value is passed directly to reqwest. root: String, + /// With what prefix the mount prefix should be replaced prefix: PathBuf, + /// Rank of the generated routes rank: isize, + /// Possible options; same as FileServer options: Options, } @@ -31,6 +40,7 @@ impl ProxyServer { const DEFAULT_RANK: isize = 0; + /// Creates a new ProxyServer object. pub fn new>(root: &str, prefix: P, rank: isize, options: Options) -> Self { ProxyServer { @@ -41,6 +51,7 @@ impl ProxyServer } } + /// Convenience function to initialize a ProxyServer with the default rank & options. pub fn from>(root: &str, prefix: P) -> Self { Self::new(root, prefix, Self::DEFAULT_RANK, Options::NormalizeDirs) @@ -49,6 +60,8 @@ impl ProxyServer impl Into> for ProxyServer { + /// Converts the handler into a list of Route objects. This is used internally by Rocket to + /// mount the handler. fn into(self) -> Vec { let mut routes: Vec = Vec::new(); @@ -159,24 +172,31 @@ impl Handler for ProxyServer // And finally, the data // TODO don't hard-code max request size here - static BODY_SIZE: i64 = 2; + static BODY_SIZE: i64 = 10; // TODO remove unwrap - let body: Vec = data + let body = data .open(BODY_SIZE.mebibytes()) .into_bytes() - .await - .unwrap() - .to_vec(); + .await; + + if body.is_err() { + return Outcome::Failure(Status::InternalServerError); + } // TODO remove unwrap // let body = reqwest::Body::wrap_stream(data); let new_res = reqwest::Client::new() .request(method, url) .headers(headers) - .body(body) + .body(body.unwrap().to_vec()) .send() - .await - .unwrap(); + .await; + + if new_res.is_err() { + return Outcome::Failure(Status::InternalServerError); + } + + let new_res = new_res.unwrap(); let mut res_headers = new_res.headers().clone(); let mut res_builder = rocket::Response::build();