fix: fixes error handling for unsigned streaming upload malformed encoding

Fixes #1666
Fixes #1660

Unsigned streaming payload trailers have strict encoding rules for the request body. If the body isn’t encoded correctly, the expected `IncompleteBody` API error is now returned. Incorrect encoding includes things like invalid chunk sizes, missing delimiters, or malformed `\r\n` sequences.
This commit is contained in:
niksis02
2025-12-03 22:07:16 -08:00
committed by Ben McClelland
parent f4c848009e
commit f631cd0364
4 changed files with 66 additions and 22 deletions
+2
View File
@@ -1100,6 +1100,7 @@ func TestUnsignedStreaminPayloadTrailer(ts *TestState) {
ts.Run(UnsignedStreamingPayloadTrailer_incorrect_trailing_checksum)
ts.Run(UnsignedStreamingPayloadTrailer_multiple_checksum_headers)
ts.Run(UnsignedStreamingPayloadTrailer_sdk_algo_and_trailer_mismatch)
ts.Run(UnsignedStreamingPayloadTrailer_incomplete_body)
ts.Run(UnsignedStreamingPayloadTrailer_no_trailer_should_calculate_crc64nvme)
ts.Run(UnsignedStreamingPayloadTrailer_no_payload_trailer_only_headers)
ts.Run(UnsignedStreamingPayloadTrailer_success_both_sdk_algo_and_trailer)
@@ -1752,6 +1753,7 @@ func GetIntTests() IntTests {
"UnsignedStreamingPayloadTrailer_incorrect_trailing_checksum": UnsignedStreamingPayloadTrailer_incorrect_trailing_checksum,
"UnsignedStreamingPayloadTrailer_multiple_checksum_headers": UnsignedStreamingPayloadTrailer_multiple_checksum_headers,
"UnsignedStreamingPayloadTrailer_sdk_algo_and_trailer_mismatch": UnsignedStreamingPayloadTrailer_sdk_algo_and_trailer_mismatch,
"UnsignedStreamingPayloadTrailer_incomplete_body": UnsignedStreamingPayloadTrailer_incomplete_body,
"UnsignedStreamingPayloadTrailer_no_trailer_should_calculate_crc64nvme": UnsignedStreamingPayloadTrailer_no_trailer_should_calculate_crc64nvme,
"UnsignedStreamingPayloadTrailer_no_payload_trailer_only_headers": UnsignedStreamingPayloadTrailer_no_payload_trailer_only_headers,
"UnsignedStreamingPayloadTrailer_success_both_sdk_algo_and_trailer": UnsignedStreamingPayloadTrailer_success_both_sdk_algo_and_trailer,
@@ -175,6 +175,42 @@ func UnsignedStreamingPayloadTrailer_sdk_algo_and_trailer_mismatch(s *S3Conf) er
})
}
func UnsignedStreamingPayloadTrailer_incomplete_body(s *S3Conf) error {
testName := "UnsignedStreamingPayloadTrailer_incomplete_body"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
object := "my-object"
for i, body := range [][]byte{
[]byte("A\ndummy data\r\n0\r\n\r\n"),
[]byte("A\r\ndummy data0\r\n\r\n"),
[]byte("A\r\nXYZ\r\ndummy data\r\n0\r\n\r\n"),
[]byte("B\r\ndummy data\r\n0\r\n\r\n"),
[]byte("A\r\ndummy data\r\n0\r\n"),
[]byte("A\r\ndummy data\r\n0\r\nx-amz-checksum-crc64nvme:dPVWc2vU1+Q=\r\n"),
[]byte("A\r\n"),
[]byte("A\r\nA\r\ndummy data\r\n0\r\n\r\n"),
// invalid chunk size
[]byte("invalid_chunk_size\r\ndummy data\r\n0\r\nx-amz-checksum-crc64nvme:dPVWc2vU1+Q=\r\n\r\n"),
[]byte("A\r\ndummy data\r\nJ\r\nx-amz-checksum-crc64nvme:dPVWc2vU1+Q=\r\n\r\n"),
} {
reqHeaders := map[string]string{
"x-amz-decoded-content-length": "10",
"x-amz-trailer": "x-amz-checksum-crc64nvme",
}
_, apiErr, err := testUnsignedStreamingPayloadTrailerObjectPut(s, bucket, object, body, reqHeaders)
if err != nil {
return fmt.Errorf("test %v failed: %w", i+1, err)
}
if err := compareS3ApiError(s3err.GetAPIError(s3err.ErrIncompleteBody), apiErr); err != nil {
return fmt.Errorf("test %v failed: %w", i+1, err)
}
}
return nil
})
}
func UnsignedStreamingPayloadTrailer_no_trailer_should_calculate_crc64nvme(s *S3Conf) error {
testName := "UnsignedStreamingPayloadTrailer_no_trailer_should_calculate_crc64nvme"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {