Support website publishing #7

Merged
lx merged 61 commits from feature/website into master 2021-01-15 16:49:51 +00:00
4 changed files with 54 additions and 6 deletions
Showing only changes of commit 4093833ae8 - Show all commits

1
Cargo.lock generated
View file

@ -661,6 +661,7 @@ dependencies = [
"http", "http",
"hyper", "hyper",
"log", "log",
"percent-encoding",
"rand", "rand",
"rmp-serde", "rmp-serde",
"roxmltree", "roxmltree",

View file

@ -54,7 +54,8 @@ pub struct ApiConfig {
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
pub struct WebConfig { pub struct WebConfig {
pub web_bind_addr: SocketAddr, pub bind_addr: SocketAddr,
pub root_domain: String,
} }
fn default_max_concurrent_rpc_requests() -> usize { fn default_max_concurrent_rpc_requests() -> usize {

View file

@ -36,6 +36,7 @@ tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-
http = "0.2" http = "0.2"
hyper = "0.13" hyper = "0.13"
percent-encoding = "2.1.0"
rustls = "0.17" rustls = "0.17"
webpki = "0.21" webpki = "0.21"

View file

@ -15,7 +15,7 @@ pub async fn run_web_server(
garage: Arc<Garage>, garage: Arc<Garage>,
shutdown_signal: impl Future<Output = ()>, shutdown_signal: impl Future<Output = ()>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let addr = &garage.config.s3_web.web_bind_addr; let addr = &garage.config.s3_web.bind_addr;
let service = make_service_fn(|conn: &AddrStream| { let service = make_service_fn(|conn: &AddrStream| {
let garage = garage.clone(); let garage = garage.clone();
@ -43,17 +43,23 @@ async fn handler(
addr: SocketAddr, addr: SocketAddr,
) -> Result<Response<Body>, Error> { ) -> Result<Response<Body>, Error> {
// Get http authority string (eg. [::1]:3902) // Get http authority string (eg. [::1]:3902 or garage.tld:80)
let authority = req let authority = req
.headers() .headers()
.get(HOST) .get(HOST)
.ok_or(Error::BadRequest(format!("HOST header required")))? .ok_or(Error::BadRequest(format!("HOST header required")))?
.to_str()?; .to_str()?;
info!("authority is {}", authority);
// Get HTTP domain/ip from host // Get bucket
let host = authority_to_host(authority)?; let host = authority_to_host(authority)?;
info!("host is {}", host); let root = &garage.config.s3_web.root_domain;
let bucket = host_to_bucket(&host, root);
// Get path
let path = req.uri().path().to_string();
let key = percent_encoding::percent_decode_str(&path).decode_utf8()?;
info!("host: {}, bucket: {}, key: {}", host, bucket, key);
Ok(Response::new(Body::from("hello world\n"))) Ok(Response::new(Body::from("hello world\n")))
} }
@ -81,6 +87,18 @@ fn authority_to_host(authority: &str) -> Result<String, Error> {
} }
} }
fn host_to_bucket<'a>(host: &'a str, root: &str) -> &'a str {
if root.len() >= host.len() || !host.ends_with(root) {
return host;
quentin marked this conversation as resolved
Review

Rewrite as only two cases:

BucketState::Present(params) if params.website.get() => Ok(()),
_ => Err(Error::NotFound),
Rewrite as only two cases: ``` BucketState::Present(params) if params.website.get() => Ok(()), _ => Err(Error::NotFound), ```
}
let len_diff = host.len() - root.len();
let missing_starting_dot = root.chars().next() != Some('.');
let cursor = if missing_starting_dot { len_diff - 1 } else { len_diff };
&host[..cursor]
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@ -107,4 +125,31 @@ mod tests {
assert_eq!(domain3, "127.0.0.1"); assert_eq!(domain3, "127.0.0.1");
Ok(()) Ok(())
quentin marked this conversation as resolved Outdated
Outdated
Review

NO!! expect makes us crash (panic) if the condition is not verified, this is not acceptable (we don't want to assume that authority is well formed, maybe hyper checks it for us but maybe not and we don't want to take risks)

NO!! `expect` makes us crash (panic) if the condition is not verified, this is not acceptable (we don't want to assume that authority is well formed, maybe hyper checks it for us but maybe not and we don't want to take risks)
} }
#[test]
fn host_to_bucket_test() {
assert_eq!(
host_to_bucket("john.doe.garage.tld", ".garage.tld"),
"john.doe");
assert_eq!(
host_to_bucket("john.doe.garage.tld", "garage.tld"),
"john.doe");
assert_eq!(
host_to_bucket("john.doe.com", "garage.tld"),
"john.doe.com");
assert_eq!(
host_to_bucket("john.doe.com", ".garage.tld"),
"john.doe.com");
assert_eq!(
host_to_bucket("garage.tld", "garage.tld"),
"garage.tld");
assert_eq!(
host_to_bucket("garage.tld", ".garage.tld"),
"garage.tld");
}
} }