mirror of
https://github.com/versity/versitygw.git
synced 2026-09-22 16:04:15 +00:00
Merge pull request #2372 from versity/ben/storage-class
feat: add storage class to put object input
This commit is contained in:
@@ -127,6 +127,7 @@ func (c S3ApiController) POSTObject(ctx fiber.Ctx) (*Response, error) {
|
||||
cacheControl := parsed.Fields["cache-control"]
|
||||
expires := parsed.Fields["expires"]
|
||||
websiteRedirectLocation := parsed.Fields["x-amz-website-redirect-location"]
|
||||
storageClass := parsed.Fields["x-amz-storage-class"]
|
||||
|
||||
key := parsed.Fields["key"]
|
||||
|
||||
@@ -233,6 +234,7 @@ func (c S3ApiController) POSTObject(ctx fiber.Ctx) (*Response, error) {
|
||||
ContentLength: &parsed.ContentLength,
|
||||
Tagging: &tagging,
|
||||
Metadata: metadata,
|
||||
StorageClass: types.StorageClass(storageClass),
|
||||
ChecksumCRC32: utils.GetStringPtr(checksums[types.ChecksumAlgorithmCrc32]),
|
||||
ChecksumCRC32C: utils.GetStringPtr(checksums[types.ChecksumAlgorithmCrc32c]),
|
||||
ChecksumSHA1: utils.GetStringPtr(checksums[types.ChecksumAlgorithmSha1]),
|
||||
|
||||
@@ -567,6 +567,7 @@ func TestS3ApiController_POSTObject(t *testing.T) {
|
||||
[]any{"eq", "$content-encoding", "gzip"},
|
||||
[]any{"eq", "$content-language", "en-US"},
|
||||
[]any{"eq", "$expires", "Fri, 21 Mar 2026 00:00:00 GMT"},
|
||||
[]any{"eq", "$x-amz-storage-class", string(types.StorageClassGlacier)},
|
||||
}),
|
||||
"file": "ignored",
|
||||
"x-amz-signature": "ignored",
|
||||
@@ -580,6 +581,7 @@ func TestS3ApiController_POSTObject(t *testing.T) {
|
||||
"content-encoding": "gzip",
|
||||
"content-language": "en-US",
|
||||
"expires": "Fri, 21 Mar 2026 00:00:00 GMT",
|
||||
"x-amz-storage-class": string(types.StorageClassGlacier),
|
||||
},
|
||||
FileRdr: newMockFileReader("payload"),
|
||||
ContentLength: int64(len("payload")),
|
||||
@@ -719,6 +721,7 @@ func TestS3ApiController_POSTObject(t *testing.T) {
|
||||
assert.Equal(t, "en-US", *putObjectInput.ContentLanguage)
|
||||
assert.Equal(t, "max-age=60", *putObjectInput.CacheControl)
|
||||
assert.Equal(t, "Fri, 21 Mar 2026 00:00:00 GMT", *putObjectInput.Expires)
|
||||
assert.Equal(t, types.StorageClassGlacier, putObjectInput.StorageClass)
|
||||
assert.Equal(t, int64(len("payload")), *putObjectInput.ContentLength)
|
||||
assert.Equal(t, "project=alpha+team", *putObjectInput.Tagging)
|
||||
assert.Equal(t, map[string]string{"owner": "alice"}, putObjectInput.Metadata)
|
||||
|
||||
@@ -151,6 +151,7 @@ func (c S3ApiController) CreateMultipartUpload(ctx fiber.Ctx) (*Response, error)
|
||||
tagging := ctx.Get("X-Amz-Tagging")
|
||||
expires := ctx.Get("Expires")
|
||||
websiteRedirectLocation := ctx.Get("X-Amz-Website-Redirect-Location")
|
||||
storageClass := ctx.Get("X-Amz-Storage-Class")
|
||||
legalHoldHdr := ctx.Get("X-Amz-Object-Lock-Legal-Hold")
|
||||
lockModeHdr := ctx.Get("X-Amz-Object-Lock-Mode")
|
||||
objLockDate := ctx.Get("X-Amz-Object-Lock-Retain-Until-Date")
|
||||
@@ -241,6 +242,7 @@ func (c S3ApiController) CreateMultipartUpload(ctx fiber.Ctx) (*Response, error)
|
||||
ObjectLockMode: objLockState.ObjectLockMode,
|
||||
ObjectLockLegalHoldStatus: objLockState.LegalHoldStatus,
|
||||
Metadata: metadata,
|
||||
StorageClass: types.StorageClass(storageClass),
|
||||
ChecksumAlgorithm: checksumAlgorithm,
|
||||
ChecksumType: checksumType,
|
||||
})
|
||||
|
||||
@@ -312,6 +312,7 @@ func TestS3ApiController_CreateMultipartUpload(t *testing.T) {
|
||||
headers: map[string]string{
|
||||
"x-amz-checksum-algorithm": string(types.ChecksumAlgorithmCrc32),
|
||||
"x-amz-checksum-type": string(types.ChecksumTypeComposite),
|
||||
"X-Amz-Storage-Class": string(types.StorageClassGlacier),
|
||||
},
|
||||
},
|
||||
output: testOutput{
|
||||
@@ -332,6 +333,9 @@ func TestS3ApiController_CreateMultipartUpload(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
be := &BackendMock{
|
||||
CreateMultipartUploadFunc: func(contextMoqParam context.Context, createMultipartUploadInput s3response.CreateMultipartUploadInput) (s3response.InitiateMultipartUploadResult, error) {
|
||||
if tt.name == "successful response" && createMultipartUploadInput.StorageClass != types.StorageClassGlacier {
|
||||
t.Fatalf("expected storage class %q, got %q", types.StorageClassGlacier, createMultipartUploadInput.StorageClass)
|
||||
}
|
||||
return tt.input.beRes.(s3response.InitiateMultipartUploadResult), tt.input.beErr
|
||||
},
|
||||
GetBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) {
|
||||
|
||||
@@ -668,6 +668,7 @@ func (c S3ApiController) PutObject(ctx fiber.Ctx) (*Response, error) {
|
||||
expires := ctx.Get("Expires")
|
||||
websiteRedirectLocation := ctx.Get("X-Amz-Website-Redirect-Location")
|
||||
tagging := ctx.Get("x-amz-tagging")
|
||||
storageClass := ctx.Get("X-Amz-Storage-Class")
|
||||
legalHoldHdr := ctx.Get("X-Amz-Object-Lock-Legal-Hold")
|
||||
lockModeHdr := ctx.Get("X-Amz-Object-Lock-Mode")
|
||||
objLockDate := ctx.Get("X-Amz-Object-Lock-Retain-Until-Date")
|
||||
@@ -803,6 +804,7 @@ func (c S3ApiController) PutObject(ctx fiber.Ctx) (*Response, error) {
|
||||
ObjectLockRetainUntilDate: &objLock.RetainUntilDate,
|
||||
ObjectLockMode: objLock.ObjectLockMode,
|
||||
ObjectLockLegalHoldStatus: objLock.LegalHoldStatus,
|
||||
StorageClass: types.StorageClass(storageClass),
|
||||
ChecksumAlgorithm: algorithm,
|
||||
ChecksumCRC32: utils.GetStringPtr(checksums[types.ChecksumAlgorithmCrc32]),
|
||||
ChecksumCRC32C: utils.GetStringPtr(checksums[types.ChecksumAlgorithmCrc32c]),
|
||||
|
||||
@@ -1169,6 +1169,58 @@ func TestS3ApiController_PutObject(t *testing.T) {
|
||||
emptyStringPtr := &str
|
||||
objSize := int64(120)
|
||||
|
||||
t.Run("forwards storage class", func(t *testing.T) {
|
||||
be := &BackendMock{
|
||||
PutObjectFunc: func(_ context.Context, input s3response.PutObjectInput) (s3response.PutObjectOutput, error) {
|
||||
if input.StorageClass != types.StorageClassGlacier {
|
||||
t.Fatalf("expected storage class %q, got %q", types.StorageClassGlacier, input.StorageClass)
|
||||
}
|
||||
return s3response.PutObjectOutput{ETag: "etag", VersionID: "version-id"}, nil
|
||||
},
|
||||
GetBucketPolicyFunc: func(_ context.Context, _ string) ([]byte, error) {
|
||||
return nil, s3err.GetAPIError(s3err.ErrAccessDenied)
|
||||
},
|
||||
GetObjectLockConfigurationFunc: func(_ context.Context, _ string) ([]byte, error) {
|
||||
return nil, s3err.GetAPIError(s3err.ErrObjectLockConfigurationNotFound)
|
||||
},
|
||||
GetBucketVersioningFunc: func(_ context.Context, _ string) (s3response.GetBucketVersioningOutput, error) {
|
||||
return s3response.GetBucketVersioningOutput{}, s3err.GetAPIError(s3err.ErrNotImplemented)
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := S3ApiController{be: be}
|
||||
testController(t, ctrl.PutObject, &Response{
|
||||
Headers: map[string]*string{
|
||||
"ETag": utils.GetStringPtr("etag"),
|
||||
"x-amz-checksum-crc32": nil,
|
||||
"x-amz-checksum-crc32c": nil,
|
||||
"x-amz-checksum-crc64nvme": nil,
|
||||
"x-amz-checksum-sha1": nil,
|
||||
"x-amz-checksum-sha256": nil,
|
||||
"x-amz-checksum-sha512": nil,
|
||||
"x-amz-checksum-md5": nil,
|
||||
"x-amz-checksum-xxhash64": nil,
|
||||
"x-amz-checksum-xxhash3": nil,
|
||||
"x-amz-checksum-xxhash128": nil,
|
||||
"x-amz-checksum-type": nil,
|
||||
"x-amz-version-id": utils.GetStringPtr("version-id"),
|
||||
"x-amz-object-size": nil,
|
||||
},
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: "root",
|
||||
ObjectETag: utils.GetStringPtr("etag"),
|
||||
ContentLength: 0,
|
||||
ObjectSize: 0,
|
||||
EventName: s3event.EventObjectCreatedPut,
|
||||
},
|
||||
}, nil, ctxInputs{
|
||||
locals: defaultLocals,
|
||||
headers: map[string]string{
|
||||
"X-Amz-Storage-Class": string(types.StorageClassGlacier),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input testInput
|
||||
|
||||
@@ -608,6 +608,7 @@ type PutObjectInput struct {
|
||||
ObjectLockMode types.ObjectLockMode
|
||||
ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus
|
||||
ChecksumAlgorithm types.ChecksumAlgorithm
|
||||
StorageClass types.StorageClass
|
||||
|
||||
Metadata map[string]string
|
||||
Body io.Reader
|
||||
|
||||
Reference in New Issue
Block a user