mirror of
https://github.com/versity/versitygw.git
synced 2026-07-27 10:32:48 +00:00
fix: makes checksum type and algorithm case insensitive in CreateMultipartUpload
Fixes #1339 `x-amz-checksum-type` and `x-amz-checksum-algorithm` request headers should be case insensitive in `CreateMultipartUpload`. The changes include parsing the header values to upper case before validating and passing to back-end. `x-amz-checksum-type` response header was added in`CreateMultipartUpload`, which was missing before.
This commit is contained in:
@@ -217,6 +217,7 @@ func (c S3ApiController) CreateMultipartUpload(ctx *fiber.Ctx) (*Response, error
|
||||
if err == nil {
|
||||
headers = map[string]*string{
|
||||
"x-amz-checksum-algorithm": utils.ConvertToStringPtr(checksumAlgorithm),
|
||||
"x-amz-checksum-type": utils.ConvertToStringPtr(checksumType),
|
||||
}
|
||||
}
|
||||
return &Response{
|
||||
@@ -233,7 +234,7 @@ func (c S3ApiController) CompleteMultipartUpload(ctx *fiber.Ctx) (*Response, err
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
uploadId := ctx.Query("uploadId")
|
||||
mpuObjSizeHdr := ctx.Get("X-Amz-Mp-Object-Size")
|
||||
checksumType := types.ChecksumType(ctx.Get("x-amz-checksum-type"))
|
||||
checksumType := types.ChecksumType(strings.ToUpper(ctx.Get("x-amz-checksum-type")))
|
||||
// context locals
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
|
||||
@@ -293,6 +293,7 @@ func TestS3ApiController_CreateMultipartUpload(t *testing.T) {
|
||||
beRes: s3response.InitiateMultipartUploadResult{},
|
||||
headers: map[string]string{
|
||||
"x-amz-checksum-algorithm": string(types.ChecksumAlgorithmCrc32),
|
||||
"x-amz-checksum-type": string(types.ChecksumTypeComposite),
|
||||
},
|
||||
},
|
||||
output: testOutput{
|
||||
@@ -300,6 +301,7 @@ func TestS3ApiController_CreateMultipartUpload(t *testing.T) {
|
||||
Data: s3response.InitiateMultipartUploadResult{},
|
||||
Headers: map[string]*string{
|
||||
"x-amz-checksum-algorithm": utils.ConvertToStringPtr(types.ChecksumAlgorithmCrc32),
|
||||
"x-amz-checksum-type": utils.ConvertToStringPtr(types.ChecksumTypeComposite),
|
||||
},
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: "root",
|
||||
|
||||
@@ -569,12 +569,12 @@ func checkChecksumTypeAndAlgo(algo types.ChecksumAlgorithm, t types.ChecksumType
|
||||
|
||||
// Parses and validates the x-amz-checksum-algorithm and x-amz-checksum-type headers
|
||||
func ParseCreateMpChecksumHeaders(ctx *fiber.Ctx) (types.ChecksumAlgorithm, types.ChecksumType, error) {
|
||||
algo := types.ChecksumAlgorithm(ctx.Get("x-amz-checksum-algorithm"))
|
||||
algo := types.ChecksumAlgorithm(strings.ToUpper(ctx.Get("x-amz-checksum-algorithm")))
|
||||
if err := IsChecksumAlgorithmValid(algo); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
chType := types.ChecksumType(ctx.Get("x-amz-checksum-type"))
|
||||
chType := types.ChecksumType(strings.ToUpper(ctx.Get("x-amz-checksum-type")))
|
||||
if err := IsChecksumTypeValid(chType); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ func TestCreateMultipartUpload(s *S3Conf) {
|
||||
CreateMultipartUpload_invalid_checksum_algorithm(s)
|
||||
CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type(s)
|
||||
CreateMultipartUpload_invalid_checksum_type(s)
|
||||
CreateMultipartUpload_valid_checksum_algorithm(s)
|
||||
CreateMultipartUpload_valid_algo_type(s)
|
||||
}
|
||||
CreateMultipartUpload_success(s)
|
||||
}
|
||||
@@ -723,7 +723,7 @@ func TestScoutfs(s *S3Conf) {
|
||||
CreateMultipartUpload_invalid_checksum_algorithm(s)
|
||||
CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type(s)
|
||||
CreateMultipartUpload_invalid_checksum_type(s)
|
||||
CreateMultipartUpload_valid_checksum_algorithm(s)
|
||||
CreateMultipartUpload_valid_algo_type(s)
|
||||
CreateMultipartUpload_success(s)
|
||||
|
||||
CompletedMultipartUpload_non_existing_bucket(s)
|
||||
@@ -1104,7 +1104,7 @@ func GetIntTests() IntTests {
|
||||
"CreateMultipartUpload_invalid_checksum_algorithm": CreateMultipartUpload_invalid_checksum_algorithm,
|
||||
"CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type": CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type,
|
||||
"CreateMultipartUpload_invalid_checksum_type": CreateMultipartUpload_invalid_checksum_type,
|
||||
"CreateMultipartUpload_valid_checksum_algorithm": CreateMultipartUpload_valid_checksum_algorithm,
|
||||
"CreateMultipartUpload_valid_algo_type": CreateMultipartUpload_valid_algo_type,
|
||||
"CreateMultipartUpload_success": CreateMultipartUpload_success,
|
||||
"UploadPart_non_existing_bucket": UploadPart_non_existing_bucket,
|
||||
"UploadPart_invalid_part_number": UploadPart_invalid_part_number,
|
||||
|
||||
+29
-15
@@ -8043,23 +8043,37 @@ func CreateMultipartUpload_empty_checksum_algorithm_with_checksum_type(s *S3Conf
|
||||
})
|
||||
}
|
||||
|
||||
func CreateMultipartUpload_valid_checksum_algorithm(s *S3Conf) error {
|
||||
testName := "CreateMultipartUpload_valid_checksum_algorithm"
|
||||
func CreateMultipartUpload_valid_algo_type(s *S3Conf) error {
|
||||
testName := "CreateMultipartUpload_valid_algo_type"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
res, err := s3client.CreateMultipartUpload(ctx, &s3.CreateMultipartUploadInput{
|
||||
Bucket: &bucket,
|
||||
Key: getPtr("my-obj"),
|
||||
ChecksumAlgorithm: types.ChecksumAlgorithmCrc32c,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj := "my-obj"
|
||||
for _, test := range []struct {
|
||||
chType types.ChecksumType
|
||||
chAlgo types.ChecksumAlgorithm
|
||||
}{
|
||||
// composite type
|
||||
{types.ChecksumTypeComposite, types.ChecksumAlgorithmCrc32},
|
||||
{types.ChecksumTypeComposite, types.ChecksumAlgorithmCrc32c},
|
||||
{types.ChecksumTypeComposite, types.ChecksumAlgorithmSha1},
|
||||
{types.ChecksumTypeComposite, types.ChecksumAlgorithmSha256},
|
||||
// full object type
|
||||
{types.ChecksumTypeFullObject, types.ChecksumAlgorithmCrc64nvme},
|
||||
{types.ChecksumTypeFullObject, types.ChecksumAlgorithmCrc32},
|
||||
{types.ChecksumTypeFullObject, types.ChecksumAlgorithmCrc32c},
|
||||
} {
|
||||
randChType := types.ChecksumType(randomizeCase(string(test.chType)))
|
||||
randChAlgo := types.ChecksumAlgorithm(randomizeCase(string(test.chAlgo)))
|
||||
out, err := createMp(s3client, bucket, obj, withChecksum(randChAlgo), withChecksumType(randChType))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res.ChecksumAlgorithm != types.ChecksumAlgorithmCrc32c {
|
||||
return fmt.Errorf("expected the checksum algorithm to be %v, instead got %v",
|
||||
types.ChecksumAlgorithmCrc32c, res.ChecksumAlgorithm)
|
||||
if out.ChecksumAlgorithm != test.chAlgo {
|
||||
return fmt.Errorf("expected the checksum algorithm to be %v, instead got %v", test.chAlgo, out.ChecksumAlgorithm)
|
||||
}
|
||||
if out.ChecksumType != test.chType {
|
||||
return fmt.Errorf("expected the checksum type to be %v, instead got %v", test.chType, out.ChecksumType)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
||||
@@ -1436,3 +1437,18 @@ type PublicBucketTestCase struct {
|
||||
Call func(ctx context.Context) error
|
||||
ExpectedErr error
|
||||
}
|
||||
|
||||
// randomizeCase randomizes the provided string latters case
|
||||
func randomizeCase(s string) string {
|
||||
var b strings.Builder
|
||||
|
||||
for _, ch := range s {
|
||||
if rnd.Intn(2) == 0 {
|
||||
b.WriteRune(unicode.ToLower(ch))
|
||||
} else {
|
||||
b.WriteRune(unicode.ToUpper(ch))
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user