diff options
author | Alex Auvolat <lx@deuxfleurs.fr> | 2025-01-29 19:14:34 +0100 |
---|---|---|
committer | Alex Auvolat <lx@deuxfleurs.fr> | 2025-01-29 19:14:34 +0100 |
commit | 9f3c7c3720d323bc9df3892197e6da5d89d1b84a (patch) | |
tree | 8e1abf81071116f71a3c969a7d5dfcf43d8c1703 /src/api/s3 | |
parent | a1d081ee840b1727ba1b3f430638a1296738283e (diff) | |
download | garage-9f3c7c3720d323bc9df3892197e6da5d89d1b84a.tar.gz garage-9f3c7c3720d323bc9df3892197e6da5d89d1b84a.zip |
api: better handling of helper errors to distinguish error codes
Diffstat (limited to 'src/api/s3')
-rw-r--r-- | src/api/s3/api_server.rs | 3 | ||||
-rw-r--r-- | src/api/s3/copy.rs | 3 | ||||
-rw-r--r-- | src/api/s3/cors.rs | 16 | ||||
-rw-r--r-- | src/api/s3/error.rs | 13 | ||||
-rw-r--r-- | src/api/s3/post_object.rs | 3 |
5 files changed, 30 insertions, 8 deletions
diff --git a/src/api/s3/api_server.rs b/src/api/s3/api_server.rs index 1737af33..f9dafa10 100644 --- a/src/api/s3/api_server.rs +++ b/src/api/s3/api_server.rs @@ -150,7 +150,8 @@ impl ApiHandler for S3ApiServer { let bucket_id = garage .bucket_helper() .resolve_bucket(&bucket_name, &api_key) - .await?; + .await + .map_err(pass_helper_error)?; let bucket = garage .bucket_helper() .get_existing_bucket(bucket_id) diff --git a/src/api/s3/copy.rs b/src/api/s3/copy.rs index e375a714..b67ace88 100644 --- a/src/api/s3/copy.rs +++ b/src/api/s3/copy.rs @@ -655,7 +655,8 @@ async fn get_copy_source(ctx: &ReqCtx, req: &Request<ReqBody>) -> Result<Object, let source_bucket_id = garage .bucket_helper() .resolve_bucket(&source_bucket.to_string(), api_key) - .await?; + .await + .map_err(pass_helper_error)?; if !api_key.allow_read(&source_bucket_id) { return Err(Error::forbidden(format!( diff --git a/src/api/s3/cors.rs b/src/api/s3/cors.rs index 173b7ffe..32dcc0d5 100644 --- a/src/api/s3/cors.rs +++ b/src/api/s3/cors.rs @@ -1,6 +1,7 @@ -use quick_xml::de::from_reader; use std::sync::Arc; +use quick_xml::de::from_reader; + use http::header::{ ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, @@ -14,7 +15,7 @@ use http_body_util::BodyExt; use serde::{Deserialize, Serialize}; -use crate::common_error::CommonError; +use crate::common_error::{helper_error_as_internal, CommonError}; use crate::helpers::*; use crate::s3::api_server::{ReqBody, ResBody}; use crate::s3::error::*; @@ -116,9 +117,16 @@ pub async fn handle_options_api( // OPTIONS calls are not auhtenticated). if let Some(bn) = bucket_name { let helper = garage.bucket_helper(); - let bucket_id = helper.resolve_global_bucket_name(&bn).await?; + let bucket_id = helper + .resolve_global_bucket_name(&bn) + .await + .map_err(helper_error_as_internal)?; if let Some(id) = bucket_id { - let bucket = garage.bucket_helper().get_existing_bucket(id).await?; + let bucket = garage + .bucket_helper() + .get_existing_bucket(id) + .await + .map_err(helper_error_as_internal)?; let bucket_params = bucket.state.into_option().unwrap(); handle_options_for_bucket(req, &bucket_params) } else { diff --git a/src/api/s3/error.rs b/src/api/s3/error.rs index 2855e0b3..22d2fe14 100644 --- a/src/api/s3/error.rs +++ b/src/api/s3/error.rs @@ -4,7 +4,10 @@ use err_derive::Error; use hyper::header::HeaderValue; use hyper::{HeaderMap, StatusCode}; -use crate::common_error::CommonError; +use garage_model::helper::error::Error as HelperError; + +pub(crate) use crate::common_error::pass_helper_error; +use crate::common_error::{helper_error_as_internal, CommonError}; pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError}; use crate::generic_server::ApiError; use crate::helpers::*; @@ -87,6 +90,14 @@ where } } +// Helper errors are always passed as internal errors by default. +// To pass the specific error code back to the client, use `pass_helper_error`. +impl From<HelperError> for Error { + fn from(err: HelperError) -> Error { + Error::Common(helper_error_as_internal(err)) + } +} + impl CommonErrorDerivative for Error {} impl From<roxmltree::Error> for Error { diff --git a/src/api/s3/post_object.rs b/src/api/s3/post_object.rs index 725f3847..5279ec6a 100644 --- a/src/api/s3/post_object.rs +++ b/src/api/s3/post_object.rs @@ -107,7 +107,8 @@ pub async fn handle_post_object( let bucket_id = garage .bucket_helper() .resolve_bucket(&bucket_name, &api_key) - .await?; + .await + .map_err(pass_helper_error)?; if !api_key.allow_write(&bucket_id) { return Err(Error::forbidden("Operation is not allowed for this key.")); |