aboutsummaryrefslogtreecommitdiff
path: root/src/api/s3
diff options
context:
space:
mode:
authorAlex Auvolat <lx@deuxfleurs.fr>2025-01-29 19:14:34 +0100
committerAlex Auvolat <lx@deuxfleurs.fr>2025-01-29 19:14:34 +0100
commit9f3c7c3720d323bc9df3892197e6da5d89d1b84a (patch)
tree8e1abf81071116f71a3c969a7d5dfcf43d8c1703 /src/api/s3
parenta1d081ee840b1727ba1b3f430638a1296738283e (diff)
downloadgarage-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.rs3
-rw-r--r--src/api/s3/copy.rs3
-rw-r--r--src/api/s3/cors.rs16
-rw-r--r--src/api/s3/error.rs13
-rw-r--r--src/api/s3/post_object.rs3
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."));