Skip to content

Commit 84df01d

Browse files
committed
WIP: report checksum validation level
1 parent 3e6906e commit 84df01d

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

aws-s3-transfer-manager/src/operation/download.rs

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ pub mod builders;
1616
mod body;
1717
pub use body::{Body, ChunkOutput};
1818

19+
/// Abstractions for checksum validation
20+
mod checksums;
21+
pub use checksums::ChecksumValidationLevel;
22+
1923
mod discovery;
2024

2125
mod handle;
@@ -31,6 +35,10 @@ pub use object_meta::ObjectMetadata;
3135

3236
mod service;
3337

38+
/// Provides metadata that isn't known until the download completes
39+
mod trailing_meta;
40+
pub use trailing_meta::TrailingMetadata;
41+
3442
use crate::error;
3543
use crate::io::AggregatedBytes;
3644
use crate::runtime::scheduler::OwnedWorkPermit;
@@ -91,6 +99,7 @@ impl Download {
9199
discovery,
92100
object_meta_rx: Mutex::new(Some(object_meta_rx)),
93101
object_meta: OnceCell::new(),
102+
trailing_meta: OnceCell::new(),
94103
})
95104
}
96105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
/// The level of checksum validation performed on a download
7+
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
8+
pub enum ChecksumValidationLevel {
9+
/// Checksum validation was not performed on all downloaded data.
10+
///
11+
/// Note this DOES NOT mean the checksum didn't match. That would have failed the download with a
12+
/// [ChecksumMismatch] error.
13+
///
14+
/// There are many reasons for `NotValidated`, including:
15+
/// - The object had no checksum.
16+
/// - Objects uploaded before 2025 are unlikely to have a checksum.
17+
/// In late-2024/early-2025 Amazon S3 began automatically calculating and storing checksums ([blog post]).
18+
/// The exact date for this varies by region.
19+
/// - Third parties that mimic the Amazon S3 API may not provide a checksum.
20+
/// - The object was downloaded in chunks, and one or more chunks had no checksum.
21+
/// - This happens when a large object with a [FullObject checksum][ChecksumTypes]
22+
/// is downloaded in multiple chunks.
23+
/// - This happens when an object with a [Composite checksum][ChecksumTypes]
24+
/// is downloaded in chunks that don't align with the [PartSize] it was uploaded with.
25+
/// - Checksum validation was disabled in the underlying The S3 client,
26+
/// by configuring it with the non-default
27+
/// [`aws_sdk_s3::config::ResponseChecksumValidation::WhenRequired`].
28+
///
29+
/// [ChecksumMismatch]: https://docs.rs/aws-smithy-checksums/latest/aws_smithy_checksums/body/validate/enum.Error.html#variant.ChecksumMismatch
30+
/// [ChecksumTypes]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#ChecksumTypes
31+
/// [blog post]: https://aws.amazon.com/blogs/aws/introducing-default-data-integrity-protections-for-new-objects-in-amazon-s3/
32+
/// [PartSize]: crate::types::PartSize
33+
#[default]
34+
NotValidated,
35+
/// The checksum of each downloaded chunk was validated, but the
36+
/// [FullObject or Composite checksum][ChecksumTypes] for the whole object
37+
/// was not validated.
38+
///
39+
/// This can happen if:
40+
/// - A large object is downloaded in multiple chunks.
41+
/// - You requested a range of the object to download, not the full object.
42+
///
43+
/// [ChecksumTypes]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#ChecksumTypes
44+
AllChunks,
45+
/// The full object was downloaded, and its checksum was validated.
46+
FullObject,
47+
}

aws-s3-transfer-manager/src/operation/download/handle.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
15
use std::sync::Arc;
26

37
use crate::error::{self, ErrorKind};
@@ -6,13 +10,9 @@ use tokio::{
610
task,
711
};
812

9-
/*
10-
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
11-
* SPDX-License-Identifier: Apache-2.0
12-
*/
1313
use crate::operation::download::body::Body;
1414

15-
use super::object_meta::ObjectMetadata;
15+
use super::{ObjectMetadata, TrailingMetadata};
1616

1717
/// Response type for a single download object request.
1818
#[derive(Debug)]
@@ -23,6 +23,9 @@ pub struct DownloadHandle {
2323
/// Object metadata.
2424
pub(crate) object_meta: OnceCell<ObjectMetadata>,
2525

26+
/// Metadata that isn't available until the download completes.
27+
pub(crate) trailing_meta: OnceCell<TrailingMetadata>,
28+
2629
/// The object content, in chunks, and the metadata for each chunk
2730
pub(crate) body: Body,
2831

@@ -74,6 +77,14 @@ impl DownloadHandle {
7477
tasks.abort_all();
7578
while (tasks.join_next().await).is_some() {}
7679
}
80+
81+
/// Get metadata about the completed download.
82+
/// This won't return `Some` until all [`body`] chunks have been successfully received.
83+
///
84+
/// [`body`]: method@Self::body
85+
pub fn trailing_meta(&self) -> Option<&TrailingMetadata> {
86+
self.trailing_meta.get()
87+
}
7788
}
7889

7990
#[cfg(test)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
use super::ChecksumValidationLevel;
6+
7+
#[derive(Debug)]
8+
/// Metadata that isn't available until the download completes.
9+
pub struct TrailingMetadata {
10+
/// The level of checksum validation performed on this download.
11+
pub checksum_validation_level: ChecksumValidationLevel,
12+
}

0 commit comments

Comments
 (0)