diff --git a/src/api/common/signature/checksum.rs b/src/api/common/signature/checksum.rs index 464fdc75..d223175f 100644 --- a/src/api/common/signature/checksum.rs +++ b/src/api/common/signature/checksum.rs @@ -28,8 +28,8 @@ pub const X_AMZ_CHECKSUM_SHA1: HeaderName = HeaderName::from_static("x-amz-check pub const X_AMZ_CHECKSUM_SHA256: HeaderName = HeaderName::from_static("x-amz-checksum-sha256"); // Values for x-amz-checksum-type -pub const COMPOSITE: &[u8] = b"COMPOSITE"; -pub const FULL_OBJECT: &[u8] = b"FULL_OBJECT"; +pub const COMPOSITE: &str = "COMPOSITE"; +pub const FULL_OBJECT: &str = "FULL_OBJECT"; pub type Crc32Checksum = [u8; 4]; pub type Crc32cChecksum = [u8; 4]; diff --git a/src/api/s3/multipart.rs b/src/api/s3/multipart.rs index 4fea1c44..bb00f066 100644 --- a/src/api/s3/multipart.rs +++ b/src/api/s3/multipart.rs @@ -518,6 +518,11 @@ pub async fn handle_complete_multipart_upload( Some(ChecksumValue::Sha256(x)) => Some(s3_xml::Value(BASE64_STANDARD.encode(&x))), _ => None, }, + checksum_type: match checksum_algorithm { + Some((_, ChecksumType::Composite)) => Some(s3_xml::Value(COMPOSITE.into())), + Some((_, ChecksumType::FullObject)) => Some(s3_xml::Value(FULL_OBJECT.into())), + None => None, + }, }; let xml = s3_xml::to_xml_with_header(&result)?; @@ -691,8 +696,8 @@ pub fn request_checksum_algorithm_and_type( )), (Some(x), Some(algo)) => { let checksum_type = match x.as_bytes() { - COMPOSITE => ChecksumType::Composite, - FULL_OBJECT => ChecksumType::FullObject, + x if x == COMPOSITE.as_bytes() => ChecksumType::Composite, + x if x == FULL_OBJECT.as_bytes() => ChecksumType::FullObject, _ => return Err(Error::bad_request("Invalid x-amz-checksum-type value")), }; match (checksum_type, algo) { diff --git a/src/api/s3/xml.rs b/src/api/s3/xml.rs index 7dea3d1c..6c1d8f88 100644 --- a/src/api/s3/xml.rs +++ b/src/api/s3/xml.rs @@ -141,6 +141,8 @@ pub struct CompleteMultipartUploadResult { pub checksum_sha1: Option, #[serde(rename = "ChecksumSHA256")] pub checksum_sha256: Option, + #[serde(rename = "ChecksumType")] + pub checksum_type: Option, } #[derive(Debug, Serialize, PartialEq, Eq)] @@ -514,6 +516,7 @@ mod tests { #[test] fn complete_multipart_upload_result() -> Result<(), ApiError> { + use garage_api_common::signature::checksum::COMPOSITE; let result = CompleteMultipartUploadResult { xmlns: (), location: Some(Value("https://garage.tld/mybucket/a/plop".to_string())), @@ -525,6 +528,7 @@ mod tests { checksum_crc64nvme: None, checksum_sha1: Some(Value("ZJAnHyG8PeKz9tI8UTcHrJos39A=".into())), checksum_sha256: None, + checksum_type: Some(Value(COMPOSITE.into())), }; assert_eq!( to_xml_with_header(&result)?, @@ -535,6 +539,7 @@ mod tests { a/plop\ "3858f62230ac3c915f300c664312c11f-9"\ ZJAnHyG8PeKz9tI8UTcHrJos39A=\ + COMPOSITE\ " ); Ok(())