fix(api): preserve typed upload digest errors (#6564)

This commit is contained in:
Zhengchao An
2026-08-25 21:20:13 +08:00
committed by GitHub
parent 02317dd36f
commit b4a78fc907
5 changed files with 162 additions and 24 deletions
+31 -1
View File
@@ -560,7 +560,13 @@ impl AsyncRead for HashReader {
let sha256 = hex_simd::encode_to_string(hasher.finalize(), hex_simd::AsciiCase::Lower);
if sha256 != *expected_sha256 {
error!("SHA256 mismatch, expected={:?}, actual={:?}", expected_sha256, sha256);
return Poll::Ready(Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "SHA256 mismatch")));
return Poll::Ready(Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
crate::errors::Sha256Mismatch {
expected_sha256: expected_sha256.clone(),
calculated_sha256: sha256,
},
)));
}
}
@@ -774,6 +780,30 @@ mod tests {
assert_eq!(buf, data);
}
#[tokio::test]
async fn sha256_mismatch_retains_typed_io_error_source() {
let data = b"tampered payload";
let expected_sha256 = "0".repeat(64);
let reader = BufReader::new(Cursor::new(&data[..]));
let mut hash_reader =
HashReader::from_stream(reader, data.len() as i64, data.len() as i64, None, Some(expected_sha256.clone()), false)
.expect("operation should succeed");
let error = hash_reader
.read_to_end(&mut Vec::new())
.await
.expect_err("SHA256 mismatch should fail");
let mismatch = error
.get_ref()
.and_then(|source| source.downcast_ref::<crate::Sha256Mismatch>())
.expect("SHA256 mismatch should remain typed");
assert_eq!(error.kind(), std::io::ErrorKind::InvalidData);
assert_eq!(mismatch.expected_sha256, expected_sha256);
assert_eq!(mismatch.calculated_sha256.len(), 64);
assert_ne!(mismatch.calculated_sha256, mismatch.expected_sha256);
}
#[tokio::test]
async fn test_add_calculated_checksum_records_checksum() {
let data = b"server-side copy checksum";