Loading crates/s3s-fs/src/main.rs +2 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ use s3s_fs::FileSystem; use s3s_fs::Result; use s3s::auth::SimpleAuth; use s3s::host::SingleDomain; use s3s::service::S3ServiceBuilder; use std::io::IsTerminal; Loading Loading @@ -103,7 +104,7 @@ async fn run(opt: Opt) -> Result { // Enable parsing virtual-hosted-style requests if let Some(domain_name) = opt.domain_name { b.set_base_domain(domain_name); b.set_host(SingleDomain::new(domain_name)); info!("virtual-hosted-style requests are enabled"); } Loading crates/s3s-fs/tests/it_aws.rs +2 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ )] use s3s::auth::SimpleAuth; use s3s::host::SingleDomain; use s3s::service::S3ServiceBuilder; use s3s_fs::FileSystem; Loading Loading @@ -64,7 +65,7 @@ fn config() -> &'static SdkConfig { let service = { let mut b = S3ServiceBuilder::new(fs); b.set_auth(SimpleAuth::from_single(cred.access_key_id(), cred.secret_access_key())); b.set_base_domain(DOMAIN_NAME); b.set_host(SingleDomain::new(DOMAIN_NAME)); b.build() }; Loading crates/s3s-proxy/src/main.rs +2 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ #![deny(clippy::all, clippy::pedantic)] use s3s::auth::SimpleAuth; use s3s::host::SingleDomain; use s3s::service::S3ServiceBuilder; use tokio::net::TcpListener; Loading Loading @@ -66,7 +67,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> { // Enable parsing virtual-hosted-style requests if let Some(domain_name) = opt.domain_name { b.set_base_domain(domain_name); b.set_host(SingleDomain::new(domain_name)); } b.build() Loading crates/s3s/src/host.rs 0 → 100644 +76 −0 Original line number Diff line number Diff line use crate::error::S3Result; use std::borrow::Cow; #[derive(Debug, Clone)] pub struct VirtualHost<'a> { domain: Cow<'a, str>, bucket: Option<Cow<'a, str>>, // pub(crate) region: Option<Cow<'a, str>>, } impl<'a> VirtualHost<'a> { pub fn new(domain: impl Into<Cow<'a, str>>) -> Self { Self { domain: domain.into(), bucket: None, } } pub fn with_bucket(domain: impl Into<Cow<'a, str>>, bucket: impl Into<Cow<'a, str>>) -> Self { Self { domain: domain.into(), bucket: Some(bucket.into()), } } #[inline] #[must_use] pub fn domain(&self) -> &str { self.domain.as_ref() } #[inline] #[must_use] pub fn bucket(&self) -> Option<&str> { self.bucket.as_deref() } } pub trait S3Host: Send + Sync + 'static { /// Parses the `Host` header of the HTTP request. /// /// # Errors /// Returns an error if the `Host` is invalid for this service. fn parse_host_header<'a>(&'a self, host: &'a str) -> S3Result<VirtualHost<'a>>; } pub struct SingleDomain { base_domain: String, } impl SingleDomain { #[must_use] pub fn new(base_domain: impl Into<String>) -> Self { Self { base_domain: base_domain.into(), } } } impl S3Host for SingleDomain { fn parse_host_header<'a>(&'a self, host: &'a str) -> S3Result<VirtualHost<'a>> { let base_domain = self.base_domain.as_str(); if host == base_domain { return Ok(VirtualHost::new(base_domain)); } if let Some(bucket) = host.strip_suffix(&self.base_domain).and_then(|h| h.strip_suffix('.')) { return Ok(VirtualHost::with_bucket(base_domain, bucket)); }; let bucket = host.to_ascii_lowercase(); Ok(VirtualHost::with_bucket(host, bucket)) } } crates/s3s/src/lib.rs +3 −4 Original line number Diff line number Diff line Loading @@ -35,16 +35,15 @@ mod sig_v2; mod sig_v4; mod xml; pub mod header; pub mod auth; pub mod checksum; pub mod dto; pub mod header; pub mod host; pub mod path; pub mod service; pub mod stream; pub mod checksum; pub use self::error::*; pub use self::http::Body; pub use self::request::S3Request; Loading Loading
crates/s3s-fs/src/main.rs +2 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ use s3s_fs::FileSystem; use s3s_fs::Result; use s3s::auth::SimpleAuth; use s3s::host::SingleDomain; use s3s::service::S3ServiceBuilder; use std::io::IsTerminal; Loading Loading @@ -103,7 +104,7 @@ async fn run(opt: Opt) -> Result { // Enable parsing virtual-hosted-style requests if let Some(domain_name) = opt.domain_name { b.set_base_domain(domain_name); b.set_host(SingleDomain::new(domain_name)); info!("virtual-hosted-style requests are enabled"); } Loading
crates/s3s-fs/tests/it_aws.rs +2 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ )] use s3s::auth::SimpleAuth; use s3s::host::SingleDomain; use s3s::service::S3ServiceBuilder; use s3s_fs::FileSystem; Loading Loading @@ -64,7 +65,7 @@ fn config() -> &'static SdkConfig { let service = { let mut b = S3ServiceBuilder::new(fs); b.set_auth(SimpleAuth::from_single(cred.access_key_id(), cred.secret_access_key())); b.set_base_domain(DOMAIN_NAME); b.set_host(SingleDomain::new(DOMAIN_NAME)); b.build() }; Loading
crates/s3s-proxy/src/main.rs +2 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ #![deny(clippy::all, clippy::pedantic)] use s3s::auth::SimpleAuth; use s3s::host::SingleDomain; use s3s::service::S3ServiceBuilder; use tokio::net::TcpListener; Loading Loading @@ -66,7 +67,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> { // Enable parsing virtual-hosted-style requests if let Some(domain_name) = opt.domain_name { b.set_base_domain(domain_name); b.set_host(SingleDomain::new(domain_name)); } b.build() Loading
crates/s3s/src/host.rs 0 → 100644 +76 −0 Original line number Diff line number Diff line use crate::error::S3Result; use std::borrow::Cow; #[derive(Debug, Clone)] pub struct VirtualHost<'a> { domain: Cow<'a, str>, bucket: Option<Cow<'a, str>>, // pub(crate) region: Option<Cow<'a, str>>, } impl<'a> VirtualHost<'a> { pub fn new(domain: impl Into<Cow<'a, str>>) -> Self { Self { domain: domain.into(), bucket: None, } } pub fn with_bucket(domain: impl Into<Cow<'a, str>>, bucket: impl Into<Cow<'a, str>>) -> Self { Self { domain: domain.into(), bucket: Some(bucket.into()), } } #[inline] #[must_use] pub fn domain(&self) -> &str { self.domain.as_ref() } #[inline] #[must_use] pub fn bucket(&self) -> Option<&str> { self.bucket.as_deref() } } pub trait S3Host: Send + Sync + 'static { /// Parses the `Host` header of the HTTP request. /// /// # Errors /// Returns an error if the `Host` is invalid for this service. fn parse_host_header<'a>(&'a self, host: &'a str) -> S3Result<VirtualHost<'a>>; } pub struct SingleDomain { base_domain: String, } impl SingleDomain { #[must_use] pub fn new(base_domain: impl Into<String>) -> Self { Self { base_domain: base_domain.into(), } } } impl S3Host for SingleDomain { fn parse_host_header<'a>(&'a self, host: &'a str) -> S3Result<VirtualHost<'a>> { let base_domain = self.base_domain.as_str(); if host == base_domain { return Ok(VirtualHost::new(base_domain)); } if let Some(bucket) = host.strip_suffix(&self.base_domain).and_then(|h| h.strip_suffix('.')) { return Ok(VirtualHost::with_bucket(base_domain, bucket)); }; let bucket = host.to_ascii_lowercase(); Ok(VirtualHost::with_bucket(host, bucket)) } }
crates/s3s/src/lib.rs +3 −4 Original line number Diff line number Diff line Loading @@ -35,16 +35,15 @@ mod sig_v2; mod sig_v4; mod xml; pub mod header; pub mod auth; pub mod checksum; pub mod dto; pub mod header; pub mod host; pub mod path; pub mod service; pub mod stream; pub mod checksum; pub use self::error::*; pub use self::http::Body; pub use self::request::S3Request; Loading