diff --git a/src/store/object_store.rs b/src/store/object_store.rs index d9af3be..b29f908 100644 --- a/src/store/object_store.rs +++ b/src/store/object_store.rs @@ -29,6 +29,9 @@ pub(crate) enum ObjectError { #[error("Failed to build object store client")] BuildClient(#[source] object_store::Error), + #[error("Failed to set hostname for object storage")] + SetHost, + #[error("Task cancelled")] Canceled, } @@ -36,7 +39,9 @@ pub(crate) enum ObjectError { impl ObjectError { pub(super) const fn error_code(&self) -> ErrorCode { match self { - Self::BuildClient(_) | Self::Request(_) => ErrorCode::OBJECT_REQUEST_ERROR, + Self::SetHost | Self::BuildClient(_) | Self::Request(_) => { + ErrorCode::OBJECT_REQUEST_ERROR + } Self::IO(_) => ErrorCode::OBJECT_IO_ERROR, Self::Canceled => ErrorCode::PANIC, } @@ -305,7 +310,7 @@ impl ObjectStore { #[tracing::instrument(skip(endpoint, access_key, secret_key, session_token), fields(endpoint = %endpoint))] pub(crate) async fn new( crate::config::ObjectStorage { - endpoint, + mut endpoint, bucket_name, use_path_style, region, @@ -323,10 +328,23 @@ impl ObjectStore { .with_timeout(Duration::from_secs(client_timeout)) .with_allow_http(!https); + let use_vhost_style = !use_path_style; + + if use_vhost_style { + if let Some(host) = endpoint.host() { + if !host.to_string().starts_with(&bucket_name) { + let new_host = format!("{bucket_name}.{host}"); + endpoint + .set_host(Some(&new_host)) + .map_err(|_| ObjectError::SetHost)?; + } + } + } + let builder = AmazonS3Builder::new() .with_endpoint(endpoint.as_str().trim_end_matches('/')) .with_bucket_name(bucket_name) - .with_virtual_hosted_style_request(!use_path_style) + .with_virtual_hosted_style_request(use_vhost_style) .with_region(region) .with_access_key_id(access_key) .with_secret_access_key(secret_key)