From 91dce87c88e24a828f5dac83c630e7b50de29b80 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Wed, 19 Jul 2023 16:18:13 +0200 Subject: [PATCH] Add add/remove_path_prefix fields to domain settings --- src/domain/manager.rs | 7 ++++++- src/domain/settings.rs | 24 ++++++++++++++++++++++++ src/domain/store.rs | 4 ++++ src/origin/proxy.rs | 6 +++--- src/service/util.rs | 6 +++++- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/domain/manager.rs b/src/domain/manager.rs index c8e499c..e2ce452 100644 --- a/src/domain/manager.rs +++ b/src/domain/manager.rs @@ -252,7 +252,12 @@ impl Manager for ManagerImpl { return Err(unexpected::Error::from("origin is proxy, can't serve file").into()); } - let f = self.origin_store.get_file(&settings.origin_descr, path)?; + let path = settings.process_path(path); + + let f = self + .origin_store + .get_file(&settings.origin_descr, path.as_ref())?; + Ok(f) } diff --git a/src/domain/settings.rs b/src/domain/settings.rs index 791d95d..f02c0dd 100644 --- a/src/domain/settings.rs +++ b/src/domain/settings.rs @@ -1,6 +1,8 @@ use crate::error::unexpected::{self, Mappable}; use crate::origin; +use std::borrow; + use hex::ToHex; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -11,6 +13,9 @@ use sha2::{Digest, Sha256}; pub struct Settings { #[serde(flatten)] pub origin_descr: origin::Descr, + + pub remove_path_prefix: Option, + pub add_path_prefix: Option, } impl Settings { @@ -19,4 +24,23 @@ impl Settings { serde_json::to_writer(&mut h, self).or_unexpected()?; Ok(h.finalize().encode_hex::()) } + + pub fn process_path<'a>(&self, path: &'a str) -> borrow::Cow<'a, str> { + let mut path = borrow::Cow::Borrowed(path); + + if let Some(ref remove_path_prefix) = self.remove_path_prefix { + if path.starts_with(remove_path_prefix.as_str()) { + *path.to_mut() = path.strip_prefix(remove_path_prefix).unwrap().to_string(); + } + } + + if let Some(ref add_path_prefix) = self.add_path_prefix { + let mut prefixed_path = String::with_capacity(add_path_prefix.len() + path.len()); + prefixed_path.push_str(add_path_prefix); + prefixed_path.push_str(path.as_ref()); + *path.to_mut() = prefixed_path; + } + + path + } } diff --git a/src/domain/store.rs b/src/domain/store.rs index efe3a68..bc0297f 100644 --- a/src/domain/store.rs +++ b/src/domain/store.rs @@ -181,6 +181,8 @@ mod tests { url: "bar".to_string(), branch_name: "baz".to_string(), }, + remove_path_prefix: None, + add_path_prefix: None, }; assert!(matches!( @@ -203,6 +205,8 @@ mod tests { url: "BAR".to_string(), branch_name: "BAZ".to_string(), }, + remove_path_prefix: None, + add_path_prefix: None, }; store.set(&domain, &new_settings).expect("set"); diff --git a/src/origin/proxy.rs b/src/origin/proxy.rs index 9f6ac8c..057fa4a 100644 --- a/src/origin/proxy.rs +++ b/src/origin/proxy.rs @@ -30,7 +30,7 @@ pub async fn serve_http_request( mut req: hyper::Request, req_is_https: bool, ) -> unexpected::Result> { - let (proxy_url, request_http_headers) = if let origin::Descr::Proxy { + let (url, request_http_headers) = if let origin::Descr::Proxy { ref url, ref request_http_headers, } = settings.origin_descr @@ -67,12 +67,12 @@ pub async fn serve_http_request( .insert("x-forwarded-proto", HeaderValue::from_static("https")); } - match hyper_reverse_proxy::call(client_ip, proxy_url, req).await { + match hyper_reverse_proxy::call(client_ip, url, req).await { Ok(res) => Ok(res), // ProxyError doesn't actually implement Error :facepalm: so we have to format the error // manually Err(e) => Err(unexpected::Error::from( - format!("error while proxying to {proxy_url}: {e:?}").as_str(), + format!("error while proxying to {url}: {e:?}").as_str(), )), } } diff --git a/src/service/util.rs b/src/service/util.rs index e4eec2f..624d2d7 100644 --- a/src/service/util.rs +++ b/src/service/util.rs @@ -31,7 +31,11 @@ impl TryFrom for domain::Settings { _ => Err("invalid domain_setting_origin_descr_kind".to_string()), }?; - Ok(Self { origin_descr }) + Ok(Self { + origin_descr, + remove_path_prefix: None, + add_path_prefix: None, + }) } }