Add add/remove_path_prefix fields to domain settings

This commit is contained in:
Brian Picciano 2023-07-19 16:18:13 +02:00
parent edadaab792
commit 91dce87c88
5 changed files with 42 additions and 5 deletions

View File

@ -252,7 +252,12 @@ impl Manager for ManagerImpl {
return Err(unexpected::Error::from("origin is proxy, can't serve file").into()); 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) Ok(f)
} }

View File

@ -1,6 +1,8 @@
use crate::error::unexpected::{self, Mappable}; use crate::error::unexpected::{self, Mappable};
use crate::origin; use crate::origin;
use std::borrow;
use hex::ToHex; use hex::ToHex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
@ -11,6 +13,9 @@ use sha2::{Digest, Sha256};
pub struct Settings { pub struct Settings {
#[serde(flatten)] #[serde(flatten)]
pub origin_descr: origin::Descr, pub origin_descr: origin::Descr,
pub remove_path_prefix: Option<String>,
pub add_path_prefix: Option<String>,
} }
impl Settings { impl Settings {
@ -19,4 +24,23 @@ impl Settings {
serde_json::to_writer(&mut h, self).or_unexpected()?; serde_json::to_writer(&mut h, self).or_unexpected()?;
Ok(h.finalize().encode_hex::<String>()) Ok(h.finalize().encode_hex::<String>())
} }
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
}
} }

View File

@ -181,6 +181,8 @@ mod tests {
url: "bar".to_string(), url: "bar".to_string(),
branch_name: "baz".to_string(), branch_name: "baz".to_string(),
}, },
remove_path_prefix: None,
add_path_prefix: None,
}; };
assert!(matches!( assert!(matches!(
@ -203,6 +205,8 @@ mod tests {
url: "BAR".to_string(), url: "BAR".to_string(),
branch_name: "BAZ".to_string(), branch_name: "BAZ".to_string(),
}, },
remove_path_prefix: None,
add_path_prefix: None,
}; };
store.set(&domain, &new_settings).expect("set"); store.set(&domain, &new_settings).expect("set");

View File

@ -30,7 +30,7 @@ pub async fn serve_http_request(
mut req: hyper::Request<hyper::Body>, mut req: hyper::Request<hyper::Body>,
req_is_https: bool, req_is_https: bool,
) -> unexpected::Result<hyper::Response<hyper::Body>> { ) -> unexpected::Result<hyper::Response<hyper::Body>> {
let (proxy_url, request_http_headers) = if let origin::Descr::Proxy { let (url, request_http_headers) = if let origin::Descr::Proxy {
ref url, ref url,
ref request_http_headers, ref request_http_headers,
} = settings.origin_descr } = settings.origin_descr
@ -67,12 +67,12 @@ pub async fn serve_http_request(
.insert("x-forwarded-proto", HeaderValue::from_static("https")); .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), Ok(res) => Ok(res),
// ProxyError doesn't actually implement Error :facepalm: so we have to format the error // ProxyError doesn't actually implement Error :facepalm: so we have to format the error
// manually // manually
Err(e) => Err(unexpected::Error::from( 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(),
)), )),
} }
} }

View File

@ -31,7 +31,11 @@ impl TryFrom<FlatDomainSettings> for domain::Settings {
_ => Err("invalid domain_setting_origin_descr_kind".to_string()), _ => 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,
})
} }
} }