diff options
Diffstat (limited to 'src/api/s3')
-rw-r--r-- | src/api/s3/multipart.rs | 9 | ||||
-rw-r--r-- | src/api/s3/put.rs | 5 |
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(); } |