mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 13:30:46 +02:00
s3: reject UploadPart checksum algorithms conflicting with the upload
An UploadPart that explicitly selects a different checksum algorithm than the one declared at CreateMultipartUpload would store a checksum CompleteMultipartUpload could never accept. Reject the conflict up front with InvalidRequest, matching AWS.
This commit is contained in:
@@ -211,3 +211,33 @@ func TestCompleteMultipartUploadValidatesPartChecksums(t *testing.T) {
|
||||
|
||||
require.NoError(t, complete(part.ChecksumSHA256))
|
||||
}
|
||||
|
||||
// UploadPart with a checksum algorithm that conflicts with the one declared at
|
||||
// CreateMultipartUpload is rejected, as on AWS.
|
||||
func TestMultipartPartConflictingAlgorithm(t *testing.T) {
|
||||
client := newWhenRequiredChecksumClient(t)
|
||||
|
||||
bucket := uniqueBucket()
|
||||
createBucket(t, client, bucket)
|
||||
defer cleanupBucket(t, client, bucket)
|
||||
|
||||
create, err := client.CreateMultipartUpload(context.Background(), &s3.CreateMultipartUploadInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String("conflict"),
|
||||
ChecksumAlgorithm: types.ChecksumAlgorithmSha256,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = client.UploadPart(context.Background(), &s3.UploadPartInput{
|
||||
Bucket: aws.String(bucket),
|
||||
Key: aws.String("conflict"),
|
||||
UploadId: create.UploadId,
|
||||
PartNumber: aws.Int32(1),
|
||||
Body: bytes.NewReader([]byte("data")),
|
||||
ChecksumAlgorithm: types.ChecksumAlgorithmCrc32,
|
||||
})
|
||||
var apiErr smithy.APIError
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.As(err, &apiErr))
|
||||
require.Equal(t, "InvalidRequest", apiErr.ErrorCode())
|
||||
}
|
||||
|
||||
@@ -446,11 +446,16 @@ func (s3a *S3ApiServer) PutObjectPartHandler(w http.ResponseWriter, r *http.Requ
|
||||
}
|
||||
|
||||
// Parts inherit the checksum algorithm declared at CreateMultipartUpload
|
||||
// when the request doesn't specify one (AWS behavior).
|
||||
// when the request doesn't specify one; a conflicting one is rejected.
|
||||
if headerName := string(uploadEntry.Extended[s3_constants.ExtChecksumAlgorithm]); headerName != "" {
|
||||
if algo, _, code := detectRequestedChecksumAlgorithm(r); code == s3err.ErrNone && algo == ChecksumAlgorithmNone {
|
||||
if name := checksumAlgorithmNameFromHeaderName(headerName); name != "" {
|
||||
r.Header.Set(s3_constants.AmzChecksumAlgorithm, name)
|
||||
if algo, reqHeaderName, code := detectRequestedChecksumAlgorithm(r); code == s3err.ErrNone {
|
||||
if algo == ChecksumAlgorithmNone {
|
||||
if name := checksumAlgorithmNameFromHeaderName(headerName); name != "" {
|
||||
r.Header.Set(s3_constants.AmzChecksumAlgorithm, name)
|
||||
}
|
||||
} else if reqHeaderName != headerName {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user