feat: Changed PutObject argument list, added used defined metadata and content length

This commit is contained in:
jonaustin09
2023-05-24 15:18:37 +04:00
parent 50b0e454e6
commit 09d42c92fd
6 changed files with 64 additions and 52 deletions

View File

@@ -30,7 +30,7 @@ type Backend interface {
CopyPart(srcBucket, srcObject, DstBucket, uploadID, rangeHeader string, part int) (*types.CopyPartResult, error)
PutObjectPart(bucket, object, uploadID string, part int, length int64, r io.Reader) (etag string, err error)
PutObject(bucket, object string, r io.Reader) (string, error)
PutObject(*s3.PutObjectInput) (*s3.PutObjectOutput, error)
HeadObject(bucket, object string, etag string) (*s3.HeadObjectOutput, error)
GetObject(bucket, object string, startOffset, length int64, writer io.Writer, etag string) (*s3.GetObjectOutput, error)
GetObjectAcl(bucket, object string) (*s3.GetObjectAclOutput, error)
@@ -120,8 +120,8 @@ func (BackendUnsupported) PutObjectPart(bucket, object, uploadID string, part in
return "", s3err.GetAPIError(s3err.ErrNotImplemented)
}
func (BackendUnsupported) PutObject(bucket, object string, r io.Reader) (string, error) {
return "", s3err.GetAPIError(s3err.ErrNotImplemented)
func (BackendUnsupported) PutObject(*s3.PutObjectInput) (*s3.PutObjectOutput, error) {
return nil, s3err.GetAPIError(s3err.ErrNotImplemented)
}
func (BackendUnsupported) DeleteObject(bucket, object string) error {
return s3err.GetAPIError(s3err.ErrNotImplemented)

View File

@@ -92,7 +92,7 @@ var _ Backend = &BackendMock{}
// PutBucketAclFunc: func(putBucketAclInput *s3.PutBucketAclInput) error {
// panic("mock out the PutBucketAcl method")
// },
// PutObjectFunc: func(bucket string, object string, r io.Reader) (string, error) {
// PutObjectFunc: func(putObjectInput *s3.PutObjectInput) (*s3.PutObjectOutput, error) {
// panic("mock out the PutObject method")
// },
// PutObjectAclFunc: func(putObjectAclInput *s3.PutObjectAclInput) error {
@@ -202,7 +202,7 @@ type BackendMock struct {
PutBucketAclFunc func(putBucketAclInput *s3.PutBucketAclInput) error
// PutObjectFunc mocks the PutObject method.
PutObjectFunc func(bucket string, object string, r io.Reader) (string, error)
PutObjectFunc func(putObjectInput *s3.PutObjectInput) (*s3.PutObjectOutput, error)
// PutObjectAclFunc mocks the PutObjectAcl method.
PutObjectAclFunc func(putObjectAclInput *s3.PutObjectAclInput) error
@@ -421,12 +421,8 @@ type BackendMock struct {
}
// PutObject holds details about calls to the PutObject method.
PutObject []struct {
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
// R is the r argument value.
R io.Reader
// PutObjectInput is the putObjectInput argument value.
PutObjectInput *s3.PutObjectInput
}
// PutObjectAcl holds details about calls to the PutObjectAcl method.
PutObjectAcl []struct {
@@ -1430,23 +1426,19 @@ func (mock *BackendMock) PutBucketAclCalls() []struct {
}
// PutObject calls PutObjectFunc.
func (mock *BackendMock) PutObject(bucket string, object string, r io.Reader) (string, error) {
func (mock *BackendMock) PutObject(putObjectInput *s3.PutObjectInput) (*s3.PutObjectOutput, error) {
if mock.PutObjectFunc == nil {
panic("BackendMock.PutObjectFunc: method is nil but Backend.PutObject was just called")
}
callInfo := struct {
Bucket string
Object string
R io.Reader
PutObjectInput *s3.PutObjectInput
}{
Bucket: bucket,
Object: object,
R: r,
PutObjectInput: putObjectInput,
}
mock.lockPutObject.Lock()
mock.calls.PutObject = append(mock.calls.PutObject, callInfo)
mock.lockPutObject.Unlock()
return mock.PutObjectFunc(bucket, object, r)
return mock.PutObjectFunc(putObjectInput)
}
// PutObjectCalls gets all the calls that were made to PutObject.
@@ -1454,14 +1446,10 @@ func (mock *BackendMock) PutObject(bucket string, object string, r io.Reader) (s
//
// len(mockedBackend.PutObjectCalls())
func (mock *BackendMock) PutObjectCalls() []struct {
Bucket string
Object string
R io.Reader
PutObjectInput *s3.PutObjectInput
} {
var calls []struct {
Bucket string
Object string
R io.Reader
PutObjectInput *s3.PutObjectInput
}
mock.lockPutObject.RLock()
calls = mock.calls.PutObject

View File

@@ -93,7 +93,7 @@ var _ backend.Backend = &BackendMock{}
// PutBucketAclFunc: func(putBucketAclInput *s3.PutBucketAclInput) error {
// panic("mock out the PutBucketAcl method")
// },
// PutObjectFunc: func(bucket string, object string, r io.Reader) (string, error) {
// PutObjectFunc: func(putObjectInput *s3.PutObjectInput) (*s3.PutObjectOutput, error) {
// panic("mock out the PutObject method")
// },
// PutObjectAclFunc: func(putObjectAclInput *s3.PutObjectAclInput) error {
@@ -203,7 +203,7 @@ type BackendMock struct {
PutBucketAclFunc func(putBucketAclInput *s3.PutBucketAclInput) error
// PutObjectFunc mocks the PutObject method.
PutObjectFunc func(bucket string, object string, r io.Reader) (string, error)
PutObjectFunc func(putObjectInput *s3.PutObjectInput) (*s3.PutObjectOutput, error)
// PutObjectAclFunc mocks the PutObjectAcl method.
PutObjectAclFunc func(putObjectAclInput *s3.PutObjectAclInput) error
@@ -422,12 +422,8 @@ type BackendMock struct {
}
// PutObject holds details about calls to the PutObject method.
PutObject []struct {
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
// R is the r argument value.
R io.Reader
// PutObjectInput is the putObjectInput argument value.
PutObjectInput *s3.PutObjectInput
}
// PutObjectAcl holds details about calls to the PutObjectAcl method.
PutObjectAcl []struct {
@@ -1431,23 +1427,19 @@ func (mock *BackendMock) PutBucketAclCalls() []struct {
}
// PutObject calls PutObjectFunc.
func (mock *BackendMock) PutObject(bucket string, object string, r io.Reader) (string, error) {
func (mock *BackendMock) PutObject(putObjectInput *s3.PutObjectInput) (*s3.PutObjectOutput, error) {
if mock.PutObjectFunc == nil {
panic("BackendMock.PutObjectFunc: method is nil but Backend.PutObject was just called")
}
callInfo := struct {
Bucket string
Object string
R io.Reader
PutObjectInput *s3.PutObjectInput
}{
Bucket: bucket,
Object: object,
R: r,
PutObjectInput: putObjectInput,
}
mock.lockPutObject.Lock()
mock.calls.PutObject = append(mock.calls.PutObject, callInfo)
mock.lockPutObject.Unlock()
return mock.PutObjectFunc(bucket, object, r)
return mock.PutObjectFunc(putObjectInput)
}
// PutObjectCalls gets all the calls that were made to PutObject.
@@ -1455,14 +1447,10 @@ func (mock *BackendMock) PutObject(bucket string, object string, r io.Reader) (s
//
// len(mockedBackend.PutObjectCalls())
func (mock *BackendMock) PutObjectCalls() []struct {
Bucket string
Object string
R io.Reader
PutObjectInput *s3.PutObjectInput
} {
var calls []struct {
Bucket string
Object string
R io.Reader
PutObjectInput *s3.PutObjectInput
}
mock.lockPutObject.RLock()
calls = mock.calls.PutObject

View File

@@ -14,6 +14,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/gofiber/fiber/v2"
"github.com/versity/scoutgw/backend"
"github.com/versity/scoutgw/s3api/utils"
"github.com/versity/scoutgw/s3err"
)
@@ -143,7 +144,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
copySource, copySrcIfMatch, copySrcIfNoneMatch,
copySrcModifSince, copySrcUnmodifSince, acl,
grantFullControl, grantRead, grantReadACP,
granWrite, grantWriteACP :=
granWrite, grantWriteACP, contentLengthStr :=
// Copy source headers
ctx.Get("X-Amz-Copy-Source"),
ctx.Get("X-Amz-Copy-Source-If-Match"),
@@ -156,7 +157,9 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
ctx.Get("X-Amz-Grant-Read"),
ctx.Get("X-Amz-Grant-Read-Acp"),
ctx.Get("X-Amz-Grant-Write"),
ctx.Get("X-Amz-Grant-Write-Acp")
ctx.Get("X-Amz-Grant-Write-Acp"),
// Other headers
ctx.Get("Content-Length")
grants := grantFullControl + grantRead + grantReadACP + granWrite + grantWriteACP
@@ -227,7 +230,20 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
return responce(ctx, res, err)
}
res, err := c.be.PutObject(dstBucket, dstKeyStart, bytes.NewReader(ctx.Request().Body()))
contentLength, err := strconv.ParseInt(contentLengthStr, 10, 64)
if err != nil {
return errors.New("wrong api call")
}
metadata := utils.GetUserMetaData(&ctx.Request().Header)
res, err := c.be.PutObject(&s3.PutObjectInput{
Bucket: &dstBucket,
Key: &dstKeyStart,
ContentLength: contentLength,
Metadata: metadata,
Body: bytes.NewReader(ctx.Request().Body()),
})
return responce(ctx, res, err)
}

View File

@@ -406,8 +406,8 @@ func TestS3ApiController_PutActions(t *testing.T) {
CopyObjectFunc: func(srcBucket, srcObject, DstBucket, dstObject string) (*s3.CopyObjectOutput, error) {
return &s3.CopyObjectOutput{}, nil
},
PutObjectFunc: func(bucket, object string, r io.Reader) (string, error) {
return "hello", nil
PutObjectFunc: func(*s3.PutObjectInput) (*s3.PutObjectOutput, error) {
return &s3.PutObjectOutput{}, nil
},
}}
app.Put("/:bucket/:key/*", s3ApiController.PutActions)

20
s3api/utils/utils.go Normal file
View File

@@ -0,0 +1,20 @@
package utils
import (
"strings"
"github.com/valyala/fasthttp"
)
func GetUserMetaData(headers *fasthttp.RequestHeader) (metadata map[string]string) {
metadata = make(map[string]string)
headers.VisitAll(func(key, value []byte) {
if strings.HasPrefix(string(key), "X-Amz-Meta-") {
trimmedKey := strings.TrimPrefix(string(key), "X-Amz-Meta-")
headerValue := string(value)
metadata[trimmedKey] = headerValue
}
})
return
}