Merge pull request #261 from versity/fix/tag-actions-cleanup

This commit is contained in:
Ben McClelland
2023-09-23 21:03:42 -07:00
committed by GitHub
6 changed files with 125 additions and 125 deletions

View File

@@ -64,9 +64,9 @@ type Backend interface {
SelectObjectContent(context.Context, *s3.SelectObjectContentInput) (s3response.SelectObjectContentResult, error)
// object tags operations
GetTags(_ context.Context, bucket, object string) (map[string]string, error)
SetTags(_ context.Context, bucket, object string, tags map[string]string) error
RemoveTags(_ context.Context, bucket, object string) error
GetObjectTagging(_ context.Context, bucket, object string) (map[string]string, error)
PutObjectTagging(_ context.Context, bucket, object string, tags map[string]string) error
DeleteObjectTagging(_ context.Context, bucket, object string) error
// non AWS actions
ChangeBucketOwner(_ context.Context, bucket, newOwner string) error
@@ -166,13 +166,13 @@ func (BackendUnsupported) SelectObjectContent(context.Context, *s3.SelectObjectC
return s3response.SelectObjectContentResult{}, s3err.GetAPIError(s3err.ErrNotImplemented)
}
func (BackendUnsupported) GetTags(_ context.Context, bucket, object string) (map[string]string, error) {
func (BackendUnsupported) GetObjectTagging(_ context.Context, bucket, object string) (map[string]string, error) {
return nil, s3err.GetAPIError(s3err.ErrNotImplemented)
}
func (BackendUnsupported) SetTags(_ context.Context, bucket, object string, tags map[string]string) error {
func (BackendUnsupported) PutObjectTagging(_ context.Context, bucket, object string, tags map[string]string) error {
return s3err.GetAPIError(s3err.ErrNotImplemented)
}
func (BackendUnsupported) RemoveTags(_ context.Context, bucket, object string) error {
func (BackendUnsupported) DeleteObjectTagging(_ context.Context, bucket, object string) error {
return s3err.GetAPIError(s3err.ErrNotImplemented)
}

View File

@@ -1006,7 +1006,7 @@ func (p *Posix) PutObject(ctx context.Context, po *s3.PutObjectInput) (string, e
}
if tagsStr != "" {
err := p.SetTags(ctx, *po.Bucket, *po.Key, tags)
err := p.PutObjectTagging(ctx, *po.Bucket, *po.Key, tags)
if err != nil {
return "", err
}
@@ -1479,7 +1479,7 @@ func (p *Posix) GetBucketAcl(_ context.Context, input *s3.GetBucketAclInput) ([]
return b, nil
}
func (p *Posix) GetTags(_ context.Context, bucket, object string) (map[string]string, error) {
func (p *Posix) GetObjectTagging(_ context.Context, bucket, object string) (map[string]string, error) {
_, err := os.Stat(bucket)
if errors.Is(err, fs.ErrNotExist) {
return nil, s3err.GetAPIError(s3err.ErrNoSuchBucket)
@@ -1512,7 +1512,7 @@ func (p *Posix) getXattrTags(bucket, object string) (map[string]string, error) {
return tags, nil
}
func (p *Posix) SetTags(_ context.Context, bucket, object string, tags map[string]string) error {
func (p *Posix) PutObjectTagging(_ context.Context, bucket, object string, tags map[string]string) error {
_, err := os.Stat(bucket)
if errors.Is(err, fs.ErrNotExist) {
return s3err.GetAPIError(s3err.ErrNoSuchBucket)
@@ -1548,8 +1548,8 @@ func (p *Posix) SetTags(_ context.Context, bucket, object string, tags map[strin
return nil
}
func (p *Posix) RemoveTags(ctx context.Context, bucket, object string) error {
return p.SetTags(ctx, bucket, object, nil)
func (p *Posix) DeleteObjectTagging(ctx context.Context, bucket, object string) error {
return p.PutObjectTagging(ctx, bucket, object, nil)
}
func (p *Posix) ChangeBucketOwner(ctx context.Context, bucket, newOwner string) error {

View File

@@ -46,6 +46,9 @@ var _ backend.Backend = &BackendMock{}
// DeleteObjectFunc: func(contextMoqParam context.Context, deleteObjectInput *s3.DeleteObjectInput) error {
// panic("mock out the DeleteObject method")
// },
// DeleteObjectTaggingFunc: func(contextMoqParam context.Context, bucket string, object string) error {
// panic("mock out the DeleteObjectTagging method")
// },
// DeleteObjectsFunc: func(contextMoqParam context.Context, deleteObjectsInput *s3.DeleteObjectsInput) (s3response.DeleteObjectsResult, error) {
// panic("mock out the DeleteObjects method")
// },
@@ -61,8 +64,8 @@ var _ backend.Backend = &BackendMock{}
// GetObjectAttributesFunc: func(contextMoqParam context.Context, getObjectAttributesInput *s3.GetObjectAttributesInput) (*s3.GetObjectAttributesOutput, error) {
// panic("mock out the GetObjectAttributes method")
// },
// GetTagsFunc: func(contextMoqParam context.Context, bucket string, object string) (map[string]string, error) {
// panic("mock out the GetTags method")
// GetObjectTaggingFunc: func(contextMoqParam context.Context, bucket string, object string) (map[string]string, error) {
// panic("mock out the GetObjectTagging method")
// },
// HeadBucketFunc: func(contextMoqParam context.Context, headBucketInput *s3.HeadBucketInput) (*s3.HeadBucketOutput, error) {
// panic("mock out the HeadBucket method")
@@ -97,8 +100,8 @@ var _ backend.Backend = &BackendMock{}
// PutObjectAclFunc: func(contextMoqParam context.Context, putObjectAclInput *s3.PutObjectAclInput) error {
// panic("mock out the PutObjectAcl method")
// },
// RemoveTagsFunc: func(contextMoqParam context.Context, bucket string, object string) error {
// panic("mock out the RemoveTags method")
// PutObjectTaggingFunc: func(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error {
// panic("mock out the PutObjectTagging method")
// },
// RestoreObjectFunc: func(contextMoqParam context.Context, restoreObjectInput *s3.RestoreObjectInput) error {
// panic("mock out the RestoreObject method")
@@ -106,9 +109,6 @@ var _ backend.Backend = &BackendMock{}
// SelectObjectContentFunc: func(contextMoqParam context.Context, selectObjectContentInput *s3.SelectObjectContentInput) (s3response.SelectObjectContentResult, error) {
// panic("mock out the SelectObjectContent method")
// },
// SetTagsFunc: func(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error {
// panic("mock out the SetTags method")
// },
// ShutdownFunc: func() {
// panic("mock out the Shutdown method")
// },
@@ -152,6 +152,9 @@ type BackendMock struct {
// DeleteObjectFunc mocks the DeleteObject method.
DeleteObjectFunc func(contextMoqParam context.Context, deleteObjectInput *s3.DeleteObjectInput) error
// DeleteObjectTaggingFunc mocks the DeleteObjectTagging method.
DeleteObjectTaggingFunc func(contextMoqParam context.Context, bucket string, object string) error
// DeleteObjectsFunc mocks the DeleteObjects method.
DeleteObjectsFunc func(contextMoqParam context.Context, deleteObjectsInput *s3.DeleteObjectsInput) (s3response.DeleteObjectsResult, error)
@@ -167,8 +170,8 @@ type BackendMock struct {
// GetObjectAttributesFunc mocks the GetObjectAttributes method.
GetObjectAttributesFunc func(contextMoqParam context.Context, getObjectAttributesInput *s3.GetObjectAttributesInput) (*s3.GetObjectAttributesOutput, error)
// GetTagsFunc mocks the GetTags method.
GetTagsFunc func(contextMoqParam context.Context, bucket string, object string) (map[string]string, error)
// GetObjectTaggingFunc mocks the GetObjectTagging method.
GetObjectTaggingFunc func(contextMoqParam context.Context, bucket string, object string) (map[string]string, error)
// HeadBucketFunc mocks the HeadBucket method.
HeadBucketFunc func(contextMoqParam context.Context, headBucketInput *s3.HeadBucketInput) (*s3.HeadBucketOutput, error)
@@ -203,8 +206,8 @@ type BackendMock struct {
// PutObjectAclFunc mocks the PutObjectAcl method.
PutObjectAclFunc func(contextMoqParam context.Context, putObjectAclInput *s3.PutObjectAclInput) error
// RemoveTagsFunc mocks the RemoveTags method.
RemoveTagsFunc func(contextMoqParam context.Context, bucket string, object string) error
// PutObjectTaggingFunc mocks the PutObjectTagging method.
PutObjectTaggingFunc func(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error
// RestoreObjectFunc mocks the RestoreObject method.
RestoreObjectFunc func(contextMoqParam context.Context, restoreObjectInput *s3.RestoreObjectInput) error
@@ -212,9 +215,6 @@ type BackendMock struct {
// SelectObjectContentFunc mocks the SelectObjectContent method.
SelectObjectContentFunc func(contextMoqParam context.Context, selectObjectContentInput *s3.SelectObjectContentInput) (s3response.SelectObjectContentResult, error)
// SetTagsFunc mocks the SetTags method.
SetTagsFunc func(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error
// ShutdownFunc mocks the Shutdown method.
ShutdownFunc func()
@@ -287,6 +287,15 @@ type BackendMock struct {
// DeleteObjectInput is the deleteObjectInput argument value.
DeleteObjectInput *s3.DeleteObjectInput
}
// DeleteObjectTagging holds details about calls to the DeleteObjectTagging method.
DeleteObjectTagging []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
}
// DeleteObjects holds details about calls to the DeleteObjects method.
DeleteObjects []struct {
// ContextMoqParam is the contextMoqParam argument value.
@@ -324,8 +333,8 @@ type BackendMock struct {
// GetObjectAttributesInput is the getObjectAttributesInput argument value.
GetObjectAttributesInput *s3.GetObjectAttributesInput
}
// GetTags holds details about calls to the GetTags method.
GetTags []struct {
// GetObjectTagging holds details about calls to the GetObjectTagging method.
GetObjectTagging []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// Bucket is the bucket argument value.
@@ -412,14 +421,16 @@ type BackendMock struct {
// PutObjectAclInput is the putObjectAclInput argument value.
PutObjectAclInput *s3.PutObjectAclInput
}
// RemoveTags holds details about calls to the RemoveTags method.
RemoveTags []struct {
// PutObjectTagging holds details about calls to the PutObjectTagging method.
PutObjectTagging []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
// Tags is the tags argument value.
Tags map[string]string
}
// RestoreObject holds details about calls to the RestoreObject method.
RestoreObject []struct {
@@ -435,17 +446,6 @@ type BackendMock struct {
// SelectObjectContentInput is the selectObjectContentInput argument value.
SelectObjectContentInput *s3.SelectObjectContentInput
}
// SetTags holds details about calls to the SetTags method.
SetTags []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
// Tags is the tags argument value.
Tags map[string]string
}
// Shutdown holds details about calls to the Shutdown method.
Shutdown []struct {
}
@@ -475,12 +475,13 @@ type BackendMock struct {
lockCreateMultipartUpload sync.RWMutex
lockDeleteBucket sync.RWMutex
lockDeleteObject sync.RWMutex
lockDeleteObjectTagging sync.RWMutex
lockDeleteObjects sync.RWMutex
lockGetBucketAcl sync.RWMutex
lockGetObject sync.RWMutex
lockGetObjectAcl sync.RWMutex
lockGetObjectAttributes sync.RWMutex
lockGetTags sync.RWMutex
lockGetObjectTagging sync.RWMutex
lockHeadBucket sync.RWMutex
lockHeadObject sync.RWMutex
lockListBuckets sync.RWMutex
@@ -492,10 +493,9 @@ type BackendMock struct {
lockPutBucketAcl sync.RWMutex
lockPutObject sync.RWMutex
lockPutObjectAcl sync.RWMutex
lockRemoveTags sync.RWMutex
lockPutObjectTagging sync.RWMutex
lockRestoreObject sync.RWMutex
lockSelectObjectContent sync.RWMutex
lockSetTags sync.RWMutex
lockShutdown sync.RWMutex
lockString sync.RWMutex
lockUploadPart sync.RWMutex
@@ -794,6 +794,46 @@ func (mock *BackendMock) DeleteObjectCalls() []struct {
return calls
}
// DeleteObjectTagging calls DeleteObjectTaggingFunc.
func (mock *BackendMock) DeleteObjectTagging(contextMoqParam context.Context, bucket string, object string) error {
if mock.DeleteObjectTaggingFunc == nil {
panic("BackendMock.DeleteObjectTaggingFunc: method is nil but Backend.DeleteObjectTagging was just called")
}
callInfo := struct {
ContextMoqParam context.Context
Bucket string
Object string
}{
ContextMoqParam: contextMoqParam,
Bucket: bucket,
Object: object,
}
mock.lockDeleteObjectTagging.Lock()
mock.calls.DeleteObjectTagging = append(mock.calls.DeleteObjectTagging, callInfo)
mock.lockDeleteObjectTagging.Unlock()
return mock.DeleteObjectTaggingFunc(contextMoqParam, bucket, object)
}
// DeleteObjectTaggingCalls gets all the calls that were made to DeleteObjectTagging.
// Check the length with:
//
// len(mockedBackend.DeleteObjectTaggingCalls())
func (mock *BackendMock) DeleteObjectTaggingCalls() []struct {
ContextMoqParam context.Context
Bucket string
Object string
} {
var calls []struct {
ContextMoqParam context.Context
Bucket string
Object string
}
mock.lockDeleteObjectTagging.RLock()
calls = mock.calls.DeleteObjectTagging
mock.lockDeleteObjectTagging.RUnlock()
return calls
}
// DeleteObjects calls DeleteObjectsFunc.
func (mock *BackendMock) DeleteObjects(contextMoqParam context.Context, deleteObjectsInput *s3.DeleteObjectsInput) (s3response.DeleteObjectsResult, error) {
if mock.DeleteObjectsFunc == nil {
@@ -978,10 +1018,10 @@ func (mock *BackendMock) GetObjectAttributesCalls() []struct {
return calls
}
// GetTags calls GetTagsFunc.
func (mock *BackendMock) GetTags(contextMoqParam context.Context, bucket string, object string) (map[string]string, error) {
if mock.GetTagsFunc == nil {
panic("BackendMock.GetTagsFunc: method is nil but Backend.GetTags was just called")
// GetObjectTagging calls GetObjectTaggingFunc.
func (mock *BackendMock) GetObjectTagging(contextMoqParam context.Context, bucket string, object string) (map[string]string, error) {
if mock.GetObjectTaggingFunc == nil {
panic("BackendMock.GetObjectTaggingFunc: method is nil but Backend.GetObjectTagging was just called")
}
callInfo := struct {
ContextMoqParam context.Context
@@ -992,17 +1032,17 @@ func (mock *BackendMock) GetTags(contextMoqParam context.Context, bucket string,
Bucket: bucket,
Object: object,
}
mock.lockGetTags.Lock()
mock.calls.GetTags = append(mock.calls.GetTags, callInfo)
mock.lockGetTags.Unlock()
return mock.GetTagsFunc(contextMoqParam, bucket, object)
mock.lockGetObjectTagging.Lock()
mock.calls.GetObjectTagging = append(mock.calls.GetObjectTagging, callInfo)
mock.lockGetObjectTagging.Unlock()
return mock.GetObjectTaggingFunc(contextMoqParam, bucket, object)
}
// GetTagsCalls gets all the calls that were made to GetTags.
// GetObjectTaggingCalls gets all the calls that were made to GetObjectTagging.
// Check the length with:
//
// len(mockedBackend.GetTagsCalls())
func (mock *BackendMock) GetTagsCalls() []struct {
// len(mockedBackend.GetObjectTaggingCalls())
func (mock *BackendMock) GetObjectTaggingCalls() []struct {
ContextMoqParam context.Context
Bucket string
Object string
@@ -1012,9 +1052,9 @@ func (mock *BackendMock) GetTagsCalls() []struct {
Bucket string
Object string
}
mock.lockGetTags.RLock()
calls = mock.calls.GetTags
mock.lockGetTags.RUnlock()
mock.lockGetObjectTagging.RLock()
calls = mock.calls.GetObjectTagging
mock.lockGetObjectTagging.RUnlock()
return calls
}
@@ -1418,43 +1458,47 @@ func (mock *BackendMock) PutObjectAclCalls() []struct {
return calls
}
// RemoveTags calls RemoveTagsFunc.
func (mock *BackendMock) RemoveTags(contextMoqParam context.Context, bucket string, object string) error {
if mock.RemoveTagsFunc == nil {
panic("BackendMock.RemoveTagsFunc: method is nil but Backend.RemoveTags was just called")
// PutObjectTagging calls PutObjectTaggingFunc.
func (mock *BackendMock) PutObjectTagging(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error {
if mock.PutObjectTaggingFunc == nil {
panic("BackendMock.PutObjectTaggingFunc: method is nil but Backend.PutObjectTagging was just called")
}
callInfo := struct {
ContextMoqParam context.Context
Bucket string
Object string
Tags map[string]string
}{
ContextMoqParam: contextMoqParam,
Bucket: bucket,
Object: object,
Tags: tags,
}
mock.lockRemoveTags.Lock()
mock.calls.RemoveTags = append(mock.calls.RemoveTags, callInfo)
mock.lockRemoveTags.Unlock()
return mock.RemoveTagsFunc(contextMoqParam, bucket, object)
mock.lockPutObjectTagging.Lock()
mock.calls.PutObjectTagging = append(mock.calls.PutObjectTagging, callInfo)
mock.lockPutObjectTagging.Unlock()
return mock.PutObjectTaggingFunc(contextMoqParam, bucket, object, tags)
}
// RemoveTagsCalls gets all the calls that were made to RemoveTags.
// PutObjectTaggingCalls gets all the calls that were made to PutObjectTagging.
// Check the length with:
//
// len(mockedBackend.RemoveTagsCalls())
func (mock *BackendMock) RemoveTagsCalls() []struct {
// len(mockedBackend.PutObjectTaggingCalls())
func (mock *BackendMock) PutObjectTaggingCalls() []struct {
ContextMoqParam context.Context
Bucket string
Object string
Tags map[string]string
} {
var calls []struct {
ContextMoqParam context.Context
Bucket string
Object string
Tags map[string]string
}
mock.lockRemoveTags.RLock()
calls = mock.calls.RemoveTags
mock.lockRemoveTags.RUnlock()
mock.lockPutObjectTagging.RLock()
calls = mock.calls.PutObjectTagging
mock.lockPutObjectTagging.RUnlock()
return calls
}
@@ -1530,50 +1574,6 @@ func (mock *BackendMock) SelectObjectContentCalls() []struct {
return calls
}
// SetTags calls SetTagsFunc.
func (mock *BackendMock) SetTags(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error {
if mock.SetTagsFunc == nil {
panic("BackendMock.SetTagsFunc: method is nil but Backend.SetTags was just called")
}
callInfo := struct {
ContextMoqParam context.Context
Bucket string
Object string
Tags map[string]string
}{
ContextMoqParam: contextMoqParam,
Bucket: bucket,
Object: object,
Tags: tags,
}
mock.lockSetTags.Lock()
mock.calls.SetTags = append(mock.calls.SetTags, callInfo)
mock.lockSetTags.Unlock()
return mock.SetTagsFunc(contextMoqParam, bucket, object, tags)
}
// SetTagsCalls gets all the calls that were made to SetTags.
// Check the length with:
//
// len(mockedBackend.SetTagsCalls())
func (mock *BackendMock) SetTagsCalls() []struct {
ContextMoqParam context.Context
Bucket string
Object string
Tags map[string]string
} {
var calls []struct {
ContextMoqParam context.Context
Bucket string
Object string
Tags map[string]string
}
mock.lockSetTags.RLock()
calls = mock.calls.SetTags
mock.lockSetTags.RUnlock()
return calls
}
// Shutdown calls ShutdownFunc.
func (mock *BackendMock) Shutdown() {
if mock.ShutdownFunc == nil {

View File

@@ -78,7 +78,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetObjectTagging", BucketOwner: parsedAcl.Owner})
}
tags, err := c.be.GetTags(ctx.Context(), bucket, key)
tags, err := c.be.GetObjectTagging(ctx.Context(), bucket, key)
if err != nil {
return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetObjectTagging", BucketOwner: parsedAcl.Owner})
}
@@ -456,7 +456,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutObjectTagging", BucketOwner: parsedAcl.Owner})
}
err = c.be.SetTags(ctx.Context(), bucket, keyStart, tags)
err = c.be.PutObjectTagging(ctx.Context(), bucket, keyStart, tags)
return SendResponse(ctx, err, &MetaOpts{
Logger: c.logger,
EvSender: c.evSender,
@@ -706,12 +706,12 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error {
return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "RemoveObjectTagging", BucketOwner: parsedAcl.Owner})
}
err := c.be.RemoveTags(ctx.Context(), bucket, key)
err := c.be.DeleteObjectTagging(ctx.Context(), bucket, key)
return SendResponse(ctx, err, &MetaOpts{
Status: http.StatusNoContent,
Logger: c.logger,
EvSender: c.evSender,
Action: "RemoveObjectTagging",
Action: "DeleteObjectTagging",
BucketOwner: parsedAcl.Owner,
EventName: s3event.EventObjectTaggingDelete,
})

View File

@@ -201,7 +201,7 @@ func TestS3ApiController_GetActions(t *testing.T) {
StorageClass: "storage class",
}, nil
},
GetTagsFunc: func(_ context.Context, bucket, object string) (map[string]string, error) {
GetObjectTaggingFunc: func(_ context.Context, bucket, object string) (map[string]string, error) {
return map[string]string{"hello": "world"}, nil
},
},
@@ -671,7 +671,7 @@ func TestS3ApiController_PutActions(t *testing.T) {
UploadPartFunc: func(context.Context, *s3.UploadPartInput) (string, error) {
return "hello", nil
},
SetTagsFunc: func(_ context.Context, bucket, object string, tags map[string]string) error {
PutObjectTaggingFunc: func(_ context.Context, bucket, object string, tags map[string]string) error {
return nil
},
UploadPartCopyFunc: func(context.Context, *s3.UploadPartCopyInput) (s3response.CopyObjectResult, error) {
@@ -1006,7 +1006,7 @@ func TestS3ApiController_DeleteActions(t *testing.T) {
AbortMultipartUploadFunc: func(context.Context, *s3.AbortMultipartUploadInput) error {
return nil
},
RemoveTagsFunc: func(_ context.Context, bucket, object string) error {
DeleteObjectTaggingFunc: func(_ context.Context, bucket, object string) error {
return nil
},
},

View File

@@ -74,14 +74,14 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
// GetObjectAcl action
// GetObject action
// ListObjectParts action
// GetTags action
// GetObjectTagging action
// ListParts action
// GetObjectAttributes action
app.Get("/:bucket/:key/*", s3ApiController.GetActions)
// DeleteObject action
// AbortMultipartUpload action
// RemoveTags action
// DeleteObjectTagging action
app.Delete("/:bucket/:key/*", s3ApiController.DeleteActions)
// DeleteObjects action
@@ -97,7 +97,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
// PutObject action
// UploadPart action
// UploadPartCopy action
// SetTags action
// PutObjectTagging action
// PutObjectAcl action
app.Put("/:bucket/:key/*", s3ApiController.PutActions)
}