mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-01 17:58:22 +00:00
fix(s3): return BadDigest for Content-MD5 mismatch (#6842)
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use crate::compress_index::{Index, TryGetIndex};
|
use crate::compress_index::{Index, TryGetIndex};
|
||||||
use crate::{EtagResolvable, HashReaderDetector, HashReaderMut};
|
use crate::{BadDigest, EtagResolvable, HashReaderDetector, HashReaderMut};
|
||||||
use md5::{Digest, Md5};
|
use md5::{Digest, Md5};
|
||||||
use pin_project_lite::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
@@ -89,7 +89,13 @@ where
|
|||||||
&& *checksum != etag
|
&& *checksum != etag
|
||||||
{
|
{
|
||||||
error!("Checksum mismatch, expected={:?}, actual={:?}", checksum, etag);
|
error!("Checksum mismatch, expected={:?}, actual={:?}", checksum, etag);
|
||||||
return Poll::Ready(Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Checksum mismatch")));
|
return Poll::Ready(Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
BadDigest {
|
||||||
|
expected_md5: checksum.clone(),
|
||||||
|
calculated_md5: etag,
|
||||||
|
},
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,6 +261,7 @@ mod tests {
|
|||||||
async fn test_etag_reader_checksum_mismatch() {
|
async fn test_etag_reader_checksum_mismatch() {
|
||||||
let data = b"checksum test data";
|
let data = b"checksum test data";
|
||||||
let wrong_checksum = "deadbeefdeadbeefdeadbeefdeadbeef".to_string();
|
let wrong_checksum = "deadbeefdeadbeefdeadbeefdeadbeef".to_string();
|
||||||
|
let calculated_md5 = hex_simd::encode_to_string(Md5::digest(data), hex_simd::AsciiCase::Lower);
|
||||||
let reader = BufReader::new(&data[..]);
|
let reader = BufReader::new(&data[..]);
|
||||||
let mut etag_reader = EtagReader::new(reader, Some(wrong_checksum.clone()));
|
let mut etag_reader = EtagReader::new(reader, Some(wrong_checksum.clone()));
|
||||||
|
|
||||||
@@ -262,5 +269,11 @@ mod tests {
|
|||||||
// Verification failed, should return InvalidData error
|
// Verification failed, should return InvalidData error
|
||||||
let err = etag_reader.read_to_end(&mut buf).await.unwrap_err();
|
let err = etag_reader.read_to_end(&mut buf).await.unwrap_err();
|
||||||
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
|
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
|
||||||
|
let digest = err
|
||||||
|
.get_ref()
|
||||||
|
.and_then(|source| source.downcast_ref::<BadDigest>())
|
||||||
|
.expect("checksum mismatch should preserve the BadDigest type");
|
||||||
|
assert_eq!(digest.expected_md5, wrong_checksum);
|
||||||
|
assert_eq!(digest.calculated_md5, calculated_md5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -621,6 +621,21 @@ mod tests {
|
|||||||
assert_eq!(api_error.message, ApiError::error_code_to_message(&S3ErrorCode::BadDigest));
|
assert_eq!(api_error.message, ApiError::error_code_to_message(&S3ErrorCode::BadDigest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn content_md5_mismatch_io_errors_map_to_bad_digest() {
|
||||||
|
let bad_digest = || rustfs_rio::BadDigest {
|
||||||
|
expected_md5: "expected".to_string(),
|
||||||
|
calculated_md5: "calculated".to_string(),
|
||||||
|
};
|
||||||
|
let api_error = ApiError::from(IoError::new(ErrorKind::InvalidData, bad_digest()));
|
||||||
|
assert_eq!(api_error.code, S3ErrorCode::BadDigest);
|
||||||
|
assert_eq!(api_error.message, ApiError::error_code_to_message(&S3ErrorCode::BadDigest));
|
||||||
|
|
||||||
|
let api_error = ApiError::from(StorageError::Io(IoError::new(ErrorKind::InvalidData, bad_digest())));
|
||||||
|
assert_eq!(api_error.code, S3ErrorCode::BadDigest);
|
||||||
|
assert_eq!(api_error.message, ApiError::error_code_to_message(&S3ErrorCode::BadDigest));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn upload_stream_sha256_mismatch_maps_to_bad_digest() {
|
fn upload_stream_sha256_mismatch_maps_to_bad_digest() {
|
||||||
let api_error = ApiError::from(IoError::other(MockUploadStreamError::Sha256Mismatch));
|
let api_error = ApiError::from(IoError::other(MockUploadStreamError::Sha256Mismatch));
|
||||||
|
|||||||
Reference in New Issue
Block a user