Skip to content

Make the S3Client GetObject API with ChecksumMode.ENABLED flag interpret the checksum field in the GetObjectResponse correctly #5421

Description

@tonychenr

Describe the feature

Make the S3Client GetObject API with ChecksumMode.ENABLED flag interpret the checksum field in the GetObjectResponse correctly.

Use Case

Currently, when we use GetObjectRequest.builder().range(...).checksumMode(ChecksumMode.ENABLED), the behavior is confusing.

Suppose we have an object uploaded via Multipart Upload, using S3 Part Level Additional Checksums. The S3Client treats the checksum returned from S3 as if it were checksum(object). In reality, that checksum is a checksum(checksum of each part). Using a get without the range() field set, the checksum returned will be of the format <checksum(checksum of each part)>-<partCount>. When using range(), the checksum from S3 is <checksum(checksum of each part)>. ChecksumValidatingInputStream compares checksum(object) against checksum(checksum of each part), which will not match. This can be confusing for users who then think either the checksum is stored incorrectly in S3 or the object bytes are wrong, when actually the problem is in how the SDK is interpreting checksums.

Proposed Solution

Prevent the SDK from attempting validations in cases where the object wasn't uploaded via the single part PutObject API. We can tell whether the object is multipart by looking at the etag or additional checksum returned from S3. The format of the etag or additional checksum will be suffixed with -<partCount>, so it should be possible to figure out the cases where it cannot treat the checksum as if it were a checksum(object). The main drawback to this is it may trick users into thinking the SDK did built-in validation when it actually didn't. I don't think it's possible to do the checksum(checksum of each part) validation without knowing the part size.

Other Information

Alternative 1: Don't allow the range() argument to be used alongside ChecksumMode.ENABLED. Similar to proposal, but explicitly notifies that validation won't happen and disallows the call altogether. I suppose it should be possible to validate single part uploaded objects in that case as long as we can tell the full object size. Maybe a worse user experience to do it this way and may break some implementations that already have these two parameters used together.

Alternative 2: We could make the SDK able to understand the different checksum cases and validate accordingly. This may be trickier (or impossible) to implement as there are more cases of validation to consider and the client wouldn't be able to tell part sizes. It would be nicer for users to get validation for free in as many cases as possible.

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

AWS Java SDK version used

2.26.23

JDK version used

17

Operating System and version

Amazon Linux 2

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

feature-requestA feature should be added or improved.p2This is a standard priority issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions