-
Notifications
You must be signed in to change notification settings - Fork 921
Add validations for upload in s3 mulitpart client #6282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds validation gaps in the S3 multipart client by implementing additional safety checks for multipart upload operations. The changes enhance error handling and prevent potential issues with malformed uploads by validating content lengths, part sizes, and part counts before attempting uploads.
- Add content length and part size validation for AsyncRequestBody objects in multipart uploads
- Implement checks to ensure the number of parts matches expected values
- Add isDone guards to prevent processing after completion in subscriber implementations
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
File | Description |
---|---|
UploadWithUnknownContentLengthHelper.java |
Adds validation for content length presence, part size limits, and expected part count matching |
UploadWithKnownContentLengthHelper.java |
Updates multipart request context to include expected number of parts |
KnownContentLengthAsyncRequestBodySubscriber.java |
Implements comprehensive part validation including content length, part size, and last part size checks |
MpuRequestContext.java |
Adds expectedNumParts field with validation to the multipart request context |
MultipartUploadHelper.java |
Enhances error handling with better exception wrapping |
Test files | Add comprehensive test coverage for the new validation scenarios |
.changes/next-release/bugfix-AmazonS3-6522f77.json |
Documents the bug fix in the changelog |
.../awssdk/services/s3/internal/multipart/KnownContentLengthAsyncRequestBodySubscriberTest.java
Outdated
Show resolved
Hide resolved
.../awssdk/services/s3/internal/multipart/KnownContentLengthAsyncRequestBodySubscriberTest.java
Outdated
Show resolved
Hide resolved
.../awssdk/services/s3/internal/multipart/KnownContentLengthAsyncRequestBodySubscriberTest.java
Outdated
Show resolved
Hide resolved
.../awssdk/services/s3/internal/multipart/KnownContentLengthAsyncRequestBodySubscriberTest.java
Outdated
Show resolved
Hide resolved
.../awssdk/services/s3/internal/multipart/KnownContentLengthAsyncRequestBodySubscriberTest.java
Outdated
Show resolved
Hide resolved
int expectedNumPart = genericMultipartHelper.determinePartCount(totalLength, partSizeInBytes); | ||
if (parts.length != expectedNumPart) { | ||
SdkClientException exception = SdkClientException.create( | ||
String.format("The number of UploadParts requests is not equal to the expected number of parts. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message uses 'UploadParts requests' which should be 'upload part requests' for consistency with other error messages in the codebase.
String.format("The number of UploadParts requests is not equal to the expected number of parts. " | |
String.format("The number of upload part requests is not equal to the expected number of parts. " |
Copilot uses AI. Check for mistakes.
e843444
to
0144760
Compare
|
return; | ||
} | ||
|
||
if (existingParts.containsKey(partNumber.get())) { | ||
partNumber.getAndIncrement(); | ||
int currentPartNum = partNumber.getAndIncrement(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please help me to understand why earlier we used to do contains on get, now we first increment and then do containsKey check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why we did that earlier, but the reason I changed is to avoid another atomic integer get call (micro perf optimization)
@@ -179,6 +178,49 @@ public void onNext(AsyncRequestBody asyncRequestBody) { | |||
subscription.request(1); | |||
} | |||
|
|||
private void validatePart(AsyncRequestBody asyncRequestBody, int currentPartNum) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see we already have JUnit tests for each class. However, I was wondering how we end up with the validation failures below from an external API perspective, such as when users pass invalid AsyncRequestBody or files get corrupted in transit. Is it possible to write end-to-end test cases for these scenarios so that we can test them with UnknownContentLength publisher or with S3CrtClient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, good point, added
CRT team is working on adding the same validations on CRT side. I'm not sure if we want to add tests on our side for CRT-based S3 client since I'd expect tests to be added on their side. |
e1ad65a
to
c64fc4c
Compare
|
Motivation and Context
The S3 multipart upload client lacked proper validation of upload parameters, which could lead to runtime failures or incorrect behavior when publishers provide malformed data. This addresses potential issues where:
• AsyncRequestBody parts lack content length information
• Individual parts exceed the configured part size
• The actual number of parts doesn't match expected calculations
• Publisher implementations continue sending data after completion
Changes Made
Validation Enhancements
• Content Length Validation: Ensure all AsyncRequestBody parts have content length present
• Part Size Validation: Verify each part (except the last) matches the expected part size exactly
• Last Part Size Validation: Validate the final part size matches the calculated remainder or full part size
• Part Count Validation: Ensure the total number of parts received matches the expected count
• Publisher State Guards: Add isDone checks in onNext to prevent processing after completion
Code Structure Improvements
• Enhanced MpuRequestContext: Added expectedNumParts field to track anticipated part count
• Improved Error Handling: Better exception chaining in MultipartUploadHelper.failRequestsElegantly
• Consistent Naming: Renamed variables for clarity (contentLength → totalSize, partCount → expectedNumParts)
Testing
Added tests
Screenshots (if appropriate)
Types of changes
Checklist
mvn install
succeedsscripts/new-change
script and following the instructions. Commit the new file created by the script in.changes/next-release
with your changes.License