aboutsummaryrefslogtreecommitdiff
path: root/src/api/s3
diff options
context:
space:
mode:
authorAlex Auvolat <lx@deuxfleurs.fr>2025-02-18 18:57:50 +0100
committerAlex Auvolat <lx@deuxfleurs.fr>2025-02-18 21:47:53 +0100
commitf6e805e7db7b35e9fc6baaad6ec953e30a443437 (patch)
tree904b5b61d02deb24c20b37c993b080c335d155c5 /src/api/s3
parent45e10e55f9761d79aa8d5b7dbaeb56d4d535629e (diff)
downloadgarage-f6e805e7db7b35e9fc6baaad6ec953e30a443437.tar.gz
garage-f6e805e7db7b35e9fc6baaad6ec953e30a443437.zip
api: various fixes
Diffstat (limited to 'src/api/s3')
-rw-r--r--src/api/s3/multipart.rs9
-rw-r--r--src/api/s3/put.rs5
2 files changed, 11 insertions, 3 deletions
diff --git a/src/api/s3/multipart.rs b/src/api/s3/multipart.rs
index 53eff6ad..1ee04bc1 100644
--- a/src/api/s3/multipart.rs
+++ b/src/api/s3/multipart.rs
@@ -114,14 +114,17 @@ pub async fn handle_put_part(
extra: request_checksum_value(req.headers())?,
};
- // Read first chuck, and at the same time try to get object to see if it exists
let key = key.to_string();
let (req_head, mut req_body) = req.into_parts();
+ // Before we stream the body, configure the needed checksums.
req_body.add_expected_checksums(expected_checksums.clone());
// TODO: avoid parsing encryption headers twice...
if !EncryptionParams::new_from_headers(&garage, &req_head.headers)?.is_encrypted() {
+ // For non-encrypted objects, we need to compute the md5sum in all cases
+ // (even if content-md5 is not set), because it is used as an etag of the
+ // part, which is in turn used in the etag computation of the whole object
req_body.add_md5();
}
@@ -130,6 +133,7 @@ pub async fn handle_put_part(
let mut chunker = StreamChunker::new(stream, garage.config.block_size);
+ // Read first chuck, and at the same time try to get object to see if it exists
let ((_, object_version, mut mpu), first_block) =
futures::try_join!(get_upload(&ctx, &key, &upload_id), chunker.next(),)?;
@@ -186,7 +190,6 @@ pub async fn handle_put_part(
garage.version_table.insert(&version).await?;
// Copy data to version
- // TODO don't duplicate checksums
let (total_size, _, _) = read_and_put_blocks(
&ctx,
&version,
@@ -198,7 +201,7 @@ pub async fn handle_put_part(
)
.await?;
- // Verify that checksums map
+ // Verify that checksums match
let checksums = stream_checksums
.await
.ok_or_internal_error("checksum calculation")??;
diff --git a/src/api/s3/put.rs b/src/api/s3/put.rs
index 6fcf33cb..496d80f3 100644
--- a/src/api/s3/put.rs
+++ b/src/api/s3/put.rs
@@ -79,9 +79,14 @@ pub async fn handle_put(
// Determine whether object should be encrypted, and if so the key
let encryption = EncryptionParams::new_from_headers(&ctx.garage, req.headers())?;
+ // The request body is a special ReqBody object (see garage_api_common::signature::body)
+ // which supports calculating checksums while streaming the data.
+ // Before we start streaming, we configure it to calculate all the checksums we need.
let mut req_body = req.into_body();
req_body.add_expected_checksums(expected_checksums.clone());
if !encryption.is_encrypted() {
+ // For non-encrypted objects, we need to compute the md5sum in all cases
+ // (even if content-md5 is not set), because it is used as the object etag
req_body.add_md5();
}