don't panic on missing checksum (fix #1387) (#1389)

fix https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/1387

Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1389
Reviewed-by: Alex <lx@deuxfleurs.fr>
Co-authored-by: trinity-1686a <trinity-1686a@noreply.localhost>
Co-committed-by: trinity-1686a <trinity-1686a@noreply.localhost>
This commit is contained in:
trinity-1686a
2026-03-17 18:16:37 +00:00
committed by Alex
parent 9848ec7f4e
commit 60244b60dd
4 changed files with 45 additions and 16 deletions
+38 -9
View File
@@ -11,6 +11,7 @@ use http::{HeaderMap, HeaderName, HeaderValue};
use garage_util::data::*;
use super::*;
use crate::common_error::CommonError;
pub use garage_model::s3::object_table::{ChecksumAlgorithm, ChecksumValue};
@@ -201,7 +202,7 @@ impl Checksums {
}
if let Some(extra) = expected.extra {
let algo = extra.algorithm();
let calculated = self.extract(Some(algo));
let calculated = self.extract(Some(algo))?;
if calculated != Some(extra) {
return Err(Error::InvalidDigest(format!(
"Failed to validate checksum for algorithm {:?}: calculated {:?}, expected {:?}",
@@ -212,17 +213,45 @@ impl Checksums {
Ok(())
}
pub fn extract(&self, algo: Option<ChecksumAlgorithm>) -> Option<ChecksumValue> {
match algo {
pub fn extract(&self, algo: Option<ChecksumAlgorithm>) -> Result<Option<ChecksumValue>, Error> {
Ok(match algo {
None => None,
Some(ChecksumAlgorithm::Crc32) => Some(ChecksumValue::Crc32(self.crc32.unwrap())),
Some(ChecksumAlgorithm::Crc32c) => Some(ChecksumValue::Crc32c(self.crc32c.unwrap())),
Some(ChecksumAlgorithm::Crc64Nvme) => {
Some(ChecksumValue::Crc64Nvme(self.crc64nvme.unwrap()))
Some(ChecksumAlgorithm::Crc32) => {
Some(ChecksumValue::Crc32(self.crc32.ok_or_else(|| {
CommonError::BadRequest(
"Requested checksum verification without providing checksum".to_string(),
)
})?))
}
Some(ChecksumAlgorithm::Sha1) => Some(ChecksumValue::Sha1(self.sha1.unwrap())),
Some(ChecksumAlgorithm::Sha256) => Some(ChecksumValue::Sha256(self.sha256.unwrap())),
Some(ChecksumAlgorithm::Crc32c) => {
Some(ChecksumValue::Crc32c(self.crc32c.ok_or_else(|| {
CommonError::BadRequest(
"Requested checksum verification without providing checksum".to_string(),
)
})?))
}
Some(ChecksumAlgorithm::Crc64Nvme) => Some(ChecksumValue::Crc64Nvme(
self.crc64nvme.ok_or_else(|| {
CommonError::BadRequest(
"Requested checksum verification without providing checksum".to_string(),
)
})?,
)),
Some(ChecksumAlgorithm::Sha1) => {
Some(ChecksumValue::Sha1(self.sha1.ok_or_else(|| {
CommonError::BadRequest(
"Requested checksum verification without providing checksum".to_string(),
)
})?))
}
Some(ChecksumAlgorithm::Sha256) => {
Some(ChecksumValue::Sha256(self.sha256.ok_or_else(|| {
CommonError::BadRequest(
"Requested checksum verification without providing checksum".to_string(),
)
})?))
}
})
}
}
+1 -1
View File
@@ -706,7 +706,7 @@ pub async fn handle_upload_part_copy(
let checksums = checksummer.finalize();
let etag = dest_encryption.etag_from_md5(&checksums.md5);
let checksum = checksums.extract(dest_object_checksum_algorithm.map(|(algo, _)| algo));
let checksum = checksums.extract(dest_object_checksum_algorithm.map(|(algo, _)| algo))?;
// Put the part's ETag in the Versiontable
dest_mpu.parts.put(
+1 -1
View File
@@ -225,7 +225,7 @@ pub async fn handle_put_part(
MpuPart {
version: version_uuid,
etag: Some(etag.clone()),
checksum: checksums.extract(checksum_algorithm.map(|(algo, _)| algo)),
checksum: checksums.extract(checksum_algorithm.map(|(algo, _)| algo))?,
size: Some(total_size),
},
);
+4 -4
View File
@@ -178,7 +178,7 @@ pub(crate) async fn save_stream<S: Stream<Item = Result<Bytes, Error>> + Unpin>(
checksums.verify(&expected)?;
}
ChecksumMode::Calculate(algo) => {
meta.checksum = checksums.extract(algo);
meta.checksum = checksums.extract(algo)?;
}
ChecksumMode::VerifyFrom {
checksummer,
@@ -189,7 +189,7 @@ pub(crate) async fn save_stream<S: Stream<Item = Result<Bytes, Error>> + Unpin>(
.await
.ok_or_internal_error("checksum calculation")??;
if let Some(algo) = trailer_algo {
meta.checksum = checksums.extract(Some(algo));
meta.checksum = checksums.extract(Some(algo))?;
}
}
}
@@ -280,7 +280,7 @@ pub(crate) async fn save_stream<S: Stream<Item = Result<Bytes, Error>> + Unpin>(
checksums.verify(&expected)?;
}
ChecksumMode::Calculate(algo) => {
meta.checksum = checksums.extract(algo);
meta.checksum = checksums.extract(algo)?;
}
ChecksumMode::VerifyFrom {
checksummer,
@@ -290,7 +290,7 @@ pub(crate) async fn save_stream<S: Stream<Item = Result<Bytes, Error>> + Unpin>(
.await
.ok_or_internal_error("checksum calculation")??;
if let Some(algo) = trailer_algo {
meta.checksum = checksums.extract(Some(algo));
meta.checksum = checksums.extract(Some(algo))?;
}
}
}