forked from TrueCloudLab/frostfs-s3-gw
[#377] Reuse BucketInfo in layer
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
46e4b28489
commit
f0914b8a43
23 changed files with 341 additions and 521 deletions
|
@ -127,19 +127,21 @@ type astOperation struct {
|
|||
func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = api.EncodeToResponse(w, h.encodeBucketACL(bucketACL)); err != nil {
|
||||
h.logAndSendError(w, "something went wrong", reqInfo, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,27 +185,29 @@ func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.updateBucketACL(r, astBucket, reqInfo.BucketName); err != nil {
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = h.updateBucketACL(r, astBucket, bktInfo); err != nil {
|
||||
h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bkt string) error {
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), bkt)
|
||||
func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bktInfo *data.BucketInfo) error {
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get bucket eacl: %w", err)
|
||||
}
|
||||
|
||||
if err = checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
return fmt.Errorf("expected owner doesn't match: %w", err)
|
||||
}
|
||||
|
||||
parentAst := tableToAst(bucketACL.EACL, bkt)
|
||||
parentAst := tableToAst(bucketACL.EACL, bktInfo.Name)
|
||||
for _, resource := range parentAst.Resources {
|
||||
if resource.Bucket == bucketACL.Info.CID.String() {
|
||||
resource.Bucket = bkt
|
||||
resource.Bucket = bktInfo.Name
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,8 +222,8 @@ func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bkt string) er
|
|||
}
|
||||
|
||||
p := &layer.PutBucketACLParams{
|
||||
Name: bkt,
|
||||
EACL: table,
|
||||
BktInfo: bktInfo,
|
||||
EACL: table,
|
||||
}
|
||||
|
||||
if err = h.obj.PutBucketACL(r.Context(), p); err != nil {
|
||||
|
@ -231,14 +235,16 @@ func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bkt string) er
|
|||
|
||||
func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), reqInfo.BucketName)
|
||||
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -280,8 +286,14 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: versionID,
|
||||
}
|
||||
|
@ -291,7 +303,7 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.updateBucketACL(r, astObject, reqInfo.BucketName); err != nil {
|
||||
if err = h.updateBucketACL(r, astObject, bktInfo); err != nil {
|
||||
h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
@ -300,14 +312,16 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), reqInfo.BucketName)
|
||||
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -336,6 +350,13 @@ func checkOwner(info *data.BucketInfo, owner string) error {
|
|||
|
||||
func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
bktPolicy := &bucketPolicy{Bucket: reqInfo.BucketName}
|
||||
if err := json.NewDecoder(r.Body).Decode(bktPolicy); err != nil {
|
||||
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err)
|
||||
|
@ -348,11 +369,10 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.updateBucketACL(r, astPolicy, reqInfo.BucketName); err != nil {
|
||||
if err = h.updateBucketACL(r, astPolicy, bktInfo); err != nil {
|
||||
h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func parseACLHeaders(header http.Header, gateKey *keys.PublicKey) (*AccessControlPolicy, error) {
|
||||
|
|
|
@ -59,7 +59,6 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: srcBucket,
|
||||
Object: srcObject,
|
||||
VersionID: versionID,
|
||||
}
|
||||
|
@ -71,12 +70,14 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, srcBucket, r.Header.Get(api.AmzSourceExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "source expected owner doesn't match", reqInfo, err)
|
||||
if p.BktInfo, err = h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner); err != nil {
|
||||
h.logAndSendError(w, "couldn't get source bucket", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
|
||||
dstBktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "couldn't get target bucket", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -100,26 +101,20 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
params := &layer.CopyObjectParams{
|
||||
SrcObject: info,
|
||||
DstBucket: reqInfo.BucketName,
|
||||
DstObject: reqInfo.ObjectName,
|
||||
SrcSize: info.Size,
|
||||
Header: metadata,
|
||||
SrcObject: info,
|
||||
DstBktInfo: dstBktInfo,
|
||||
DstObject: reqInfo.ObjectName,
|
||||
SrcSize: info.Size,
|
||||
Header: metadata,
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
|
||||
settings, err := h.obj.GetBucketSettings(r.Context(), dstBktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket settings", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
params.Lock, err = formObjectLock(bktInfo, settings.LockConfiguration, r.Header)
|
||||
params.Lock, err = formObjectLock(dstBktInfo, settings.LockConfiguration, r.Header)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not form object lock", reqInfo, err)
|
||||
return
|
||||
|
|
|
@ -19,17 +19,12 @@ const (
|
|||
func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
cors, err := h.obj.GetBucketCORS(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get cors", reqInfo, err)
|
||||
|
@ -45,17 +40,12 @@ func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.PutCORSParams{
|
||||
BktInfo: bktInfo,
|
||||
Reader: r.Body,
|
||||
|
@ -72,18 +62,13 @@ func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.obj.DeleteBucketCORS(r.Context(), bktInfo); err != nil {
|
||||
if err = h.obj.DeleteBucketCORS(r.Context(), bktInfo); err != nil {
|
||||
h.logAndSendError(w, "could not delete cors", reqInfo, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -60,12 +60,13 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}}
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
deletedObjects, err := h.obj.DeleteObjects(r.Context(), reqInfo.BucketName, versionedObject)
|
||||
deletedObjects, err := h.obj.DeleteObjects(r.Context(), bktInfo, versionedObject)
|
||||
deletedObject := deletedObjects[0]
|
||||
if err == nil {
|
||||
err = deletedObject.Error
|
||||
|
@ -131,8 +132,9 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
|||
DeletedObjects: make([]DeletedObject, 0, len(toRemove)),
|
||||
}
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -143,7 +145,7 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
|||
return nil
|
||||
})
|
||||
|
||||
deletedObjects, err := h.obj.DeleteObjects(r.Context(), reqInfo.BucketName, toRemove)
|
||||
deletedObjects, err := h.obj.DeleteObjects(r.Context(), bktInfo, toRemove)
|
||||
if !requested.Quiet && err != nil {
|
||||
h.logAndSendError(w, "couldn't delete objects", reqInfo, err)
|
||||
return
|
||||
|
@ -194,11 +196,13 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
|||
|
||||
func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err := h.obj.DeleteBucket(r.Context(), &layer.DeleteBucketParams{Name: reqInfo.BucketName}); err != nil {
|
||||
|
||||
if err = h.obj.DeleteBucket(r.Context(), &layer.DeleteBucketParams{BktInfo: bktInfo}); err != nil {
|
||||
h.logAndSendError(w, "couldn't delete bucket", reqInfo, err)
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
|
|
@ -115,18 +115,14 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
|
|
|
@ -77,20 +77,22 @@ func createTestBucket(ctx context.Context, t *testing.T, h *handlerContext, bktN
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerContext, bktName string, conf *data.ObjectLockConfiguration) {
|
||||
func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerContext, bktName string, conf *data.ObjectLockConfiguration) *data.BucketInfo {
|
||||
cnrID, err := h.MockedPool().CreateContainer(ctx, neofs.PrmContainerCreate{
|
||||
Name: bktName,
|
||||
AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
bktInfo := &data.BucketInfo{
|
||||
CID: cnrID,
|
||||
Name: bktName,
|
||||
ObjectLockEnabled: true,
|
||||
Owner: owner.NewID(),
|
||||
}
|
||||
|
||||
sp := &layer.PutSettingsParams{
|
||||
BktInfo: &data.BucketInfo{
|
||||
CID: cnrID,
|
||||
Name: bktName,
|
||||
ObjectLockEnabled: true,
|
||||
Owner: owner.NewID(),
|
||||
},
|
||||
BktInfo: bktInfo,
|
||||
Settings: &data.BucketSettings{
|
||||
VersioningEnabled: true,
|
||||
LockConfiguration: conf,
|
||||
|
@ -99,19 +101,21 @@ func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerConte
|
|||
|
||||
err = h.Layer().PutBucketSettings(ctx, sp)
|
||||
require.NoError(t, err)
|
||||
|
||||
return bktInfo
|
||||
}
|
||||
|
||||
func createTestObject(ctx context.Context, t *testing.T, h *handlerContext, bktName, objName string) {
|
||||
func createTestObject(ctx context.Context, t *testing.T, h *handlerContext, bktInfo *data.BucketInfo, objName string) {
|
||||
content := make([]byte, 1024)
|
||||
_, err := rand.Read(content)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = h.Layer().PutObject(ctx, &layer.PutObjectParams{
|
||||
Bucket: bktName,
|
||||
Object: objName,
|
||||
Size: int64(len(content)),
|
||||
Reader: bytes.NewReader(content),
|
||||
Header: make(map[string]string),
|
||||
BktInfo: bktInfo,
|
||||
Object: objName,
|
||||
Size: int64(len(content)),
|
||||
Reader: bytes.NewReader(content),
|
||||
Header: make(map[string]string),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
|
|
@ -34,18 +34,14 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
reqInfo = api.GetReqInfo(r.Context())
|
||||
)
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
|
@ -87,15 +83,11 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set(api.ContainerID, bktInfo.CID.String())
|
||||
api.WriteResponse(w, http.StatusOK, nil, api.MimeNone)
|
||||
|
|
|
@ -9,17 +9,12 @@ import (
|
|||
func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = api.EncodeToResponse(w, LocationResponse{Location: bktInfo.LocationConstraint}); err != nil {
|
||||
h.logAndSendError(w, "couldn't encode bucket location response", reqInfo, err)
|
||||
}
|
||||
|
|
|
@ -28,15 +28,11 @@ const (
|
|||
func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bktInfo.ObjectLockEnabled {
|
||||
h.logAndSendError(w, "couldn't put object locking configuration", reqInfo,
|
||||
|
@ -77,15 +73,11 @@ func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
|
|||
func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bktInfo.ObjectLockEnabled {
|
||||
h.logAndSendError(w, "object lock disabled", reqInfo,
|
||||
|
@ -114,15 +106,11 @@ func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
|
|||
func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bktInfo.ObjectLockEnabled {
|
||||
h.logAndSendError(w, "object lock disabled", reqInfo,
|
||||
|
@ -143,7 +131,7 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
|
@ -187,15 +175,11 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
|
|||
func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bktInfo.ObjectLockEnabled {
|
||||
h.logAndSendError(w, "object lock disabled", reqInfo,
|
||||
|
@ -204,7 +188,7 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
|
@ -234,16 +218,11 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
|
|||
func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bktInfo.ObjectLockEnabled {
|
||||
h.logAndSendError(w, "object lock disabled", reqInfo,
|
||||
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound))
|
||||
|
@ -263,7 +242,7 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
|
@ -317,15 +296,11 @@ func checkLockInfo(lock *data.ObjectInfo, header http.Header) error {
|
|||
func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bktInfo.ObjectLockEnabled {
|
||||
h.logAndSendError(w, "object lock disabled", reqInfo,
|
||||
|
@ -334,7 +309,7 @@ func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
|
|
|
@ -463,10 +463,10 @@ func TestObjectLegalHold(t *testing.T) {
|
|||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-lock-enabled"
|
||||
createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
||||
bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
||||
|
||||
objName := "obj-for-legal-hold"
|
||||
createTestObject(ctx, t, hc, bktName, objName)
|
||||
createTestObject(ctx, t, hc, bktInfo, objName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||
|
@ -512,10 +512,10 @@ func TestObjectRetention(t *testing.T) {
|
|||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-lock-enabled"
|
||||
createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
||||
bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
||||
|
||||
objName := "obj-for-retention"
|
||||
createTestObject(ctx, t, hc, bktName, objName)
|
||||
createTestObject(ctx, t, hc, bktInfo, objName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||
|
|
|
@ -103,17 +103,12 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
|
|||
(min value of partNumber of a common part is 1) and holding data: metadata, acl, tagging */
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
hasData bool
|
||||
b []byte
|
||||
|
@ -195,16 +190,12 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
|
|||
func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
var (
|
||||
queryValues = r.URL.Query()
|
||||
uploadID = queryValues.Get(uploadIDHeaderName)
|
||||
|
@ -239,22 +230,9 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
versionID string
|
||||
|
||||
versionID string
|
||||
reqInfo = api.GetReqInfo(r.Context())
|
||||
queryValues = reqInfo.URL.Query()
|
||||
uploadID = queryValues.Get(uploadIDHeaderName)
|
||||
additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("Key", reqInfo.ObjectName)}
|
||||
|
@ -280,8 +258,20 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
srcBktInfo, err := h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get source bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get target bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
srcInfo, err := h.obj.GetObjectInfo(r.Context(), &layer.HeadObjectParams{
|
||||
Bucket: srcBucket,
|
||||
BktInfo: srcBktInfo,
|
||||
Object: srcObject,
|
||||
VersionID: versionID,
|
||||
})
|
||||
|
@ -318,11 +308,6 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, srcBucket, r.Header.Get(api.AmzSourceExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "source expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.UploadCopyParams{
|
||||
Info: &layer.UploadInfoParams{
|
||||
UploadID: uploadID,
|
||||
|
@ -353,17 +338,12 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
uploadID = r.URL.Query().Get(uploadIDHeaderName)
|
||||
uploadInfo = &layer.UploadInfoParams{
|
||||
|
@ -439,15 +419,14 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
|
|||
h.logAndSendError(w, "could not translate acl of completed multipart upload to ast", reqInfo, err, additional...)
|
||||
return
|
||||
}
|
||||
if err = h.updateBucketACL(r, astObject, reqInfo.BucketName); err != nil {
|
||||
if err = h.updateBucketACL(r, astObject, bktInfo); err != nil {
|
||||
h.logAndSendError(w, "could not update bucket acl while completing multipart upload", reqInfo, err, additional...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err = h.obj.DeleteObjects(r.Context(), bktInfo.Name, []*layer.VersionedObject{{Name: initPart.Name}})
|
||||
if err != nil {
|
||||
if _, err = h.obj.DeleteObjects(r.Context(), bktInfo, []*layer.VersionedObject{{Name: initPart.Name}}); err != nil {
|
||||
h.logAndSendError(w, "could not delete init file of multipart upload", reqInfo, err, additional...)
|
||||
return
|
||||
}
|
||||
|
@ -472,17 +451,12 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
|
|||
func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
queryValues = reqInfo.URL.Query()
|
||||
delimiter = queryValues.Get("delimiter")
|
||||
|
@ -525,17 +499,12 @@ func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Req
|
|||
func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
partNumberMarker int
|
||||
|
||||
|
@ -587,17 +556,12 @@ func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
queryValues = reqInfo.URL.Query()
|
||||
uploadID = queryValues.Get(uploadIDHeaderName)
|
||||
|
|
|
@ -16,15 +16,11 @@ type NotificationConfiguration struct {
|
|||
|
||||
func (h *handler) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.PutBucketNotificationConfigurationParams{
|
||||
BktInfo: bktInfo,
|
||||
|
@ -40,16 +36,12 @@ func (h *handler) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Re
|
|||
func (h *handler) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
conf, err := h.obj.GetBucketNotificationConfiguration(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket notification configuration", reqInfo, err)
|
||||
|
|
|
@ -22,8 +22,8 @@ func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func encodeV1(p *layer.ListObjectsParamsV1, list *layer.ListObjectsInfoV1) *ListObjectsV1Response {
|
||||
res := &ListObjectsV1Response{
|
||||
Name: p.Bucket,
|
||||
Name: p.BktInfo.Name,
|
||||
EncodingType: p.Encode,
|
||||
Marker: p.Marker,
|
||||
Prefix: p.Prefix,
|
||||
|
@ -66,8 +66,8 @@ func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func encodeV2(p *layer.ListObjectsParamsV2, list *layer.ListObjectsInfoV2) *ListObjectsV2Response {
|
||||
res := &ListObjectsV2Response{
|
||||
Name: p.Bucket,
|
||||
Name: p.BktInfo.Name,
|
||||
EncodingType: p.Encode,
|
||||
Prefix: s3PathEncode(p.Prefix, p.Encode),
|
||||
KeyCount: len(list.Objects) + len(list.Prefixes),
|
||||
|
@ -149,7 +149,6 @@ func parseListObjectArgs(reqInfo *api.ReqInfo) (*layer.ListObjectsParamsCommon,
|
|||
queryValues = reqInfo.URL.Query()
|
||||
)
|
||||
|
||||
res.Bucket = reqInfo.BucketName
|
||||
res.Delimiter = queryValues.Get("delimiter")
|
||||
res.Encode = queryValues.Get("encoding-type")
|
||||
|
||||
|
@ -218,15 +217,10 @@ func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http
|
|||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
if p.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
info, err := h.obj.ListObjectVersions(r.Context(), p)
|
||||
if err != nil {
|
||||
|
@ -234,7 +228,7 @@ func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http
|
|||
return
|
||||
}
|
||||
|
||||
response := encodeListObjectVersionsToResponse(info, p.Bucket)
|
||||
response := encodeListObjectVersionsToResponse(info, p.BktInfo.Name)
|
||||
if err = api.EncodeToResponse(w, response); err != nil {
|
||||
h.logAndSendError(w, "something went wrong", reqInfo, err)
|
||||
}
|
||||
|
@ -258,7 +252,6 @@ func parseListObjectVersionsRequest(reqInfo *api.ReqInfo) (*layer.ListObjectVers
|
|||
res.Delimiter = queryValues.Get("delimiter")
|
||||
res.Encode = queryValues.Get("encoding-type")
|
||||
res.VersionIDMarker = queryValues.Get("version-id-marker")
|
||||
res.Bucket = reqInfo.BucketName
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
|
|
@ -180,13 +180,9 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -202,11 +198,11 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
params := &layer.PutObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
Object: reqInfo.ObjectName,
|
||||
Reader: r.Body,
|
||||
Size: r.ContentLength,
|
||||
Header: metadata,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
Reader: r.Body,
|
||||
Size: r.ContentLength,
|
||||
Header: metadata,
|
||||
}
|
||||
|
||||
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
|
||||
|
@ -228,7 +224,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if containsACLHeaders(r) {
|
||||
if newEaclTable, err = h.getNewEAclTable(r, info); err != nil {
|
||||
if newEaclTable, err = h.getNewEAclTable(r, bktInfo, info); err != nil {
|
||||
h.logAndSendError(w, "could not get new eacl table", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
@ -243,8 +239,8 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if newEaclTable != nil {
|
||||
p := &layer.PutBucketACLParams{
|
||||
Name: reqInfo.BucketName,
|
||||
EACL: newEaclTable,
|
||||
BktInfo: bktInfo,
|
||||
EACL: newEaclTable,
|
||||
}
|
||||
|
||||
if err = h.obj.PutBucketACL(r.Context(), p); err != nil {
|
||||
|
@ -253,7 +249,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
if settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo); err != nil {
|
||||
if settings, err = h.obj.GetBucketSettings(r.Context(), bktInfo); err != nil {
|
||||
h.log.Warn("couldn't get bucket versioning", zap.String("bucket name", reqInfo.BucketName), zap.Error(err))
|
||||
} else if settings.VersioningEnabled {
|
||||
w.Header().Set(api.AmzVersionID, info.Version())
|
||||
|
@ -306,12 +302,18 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
params := &layer.PutObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
Object: reqInfo.ObjectName,
|
||||
Reader: contentReader,
|
||||
Size: size,
|
||||
Header: metadata,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
Reader: contentReader,
|
||||
Size: size,
|
||||
Header: metadata,
|
||||
}
|
||||
|
||||
info, err := h.obj.PutObject(r.Context(), params)
|
||||
|
@ -326,7 +328,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
|
|||
r.Header.Set(api.AmzGrantWrite, "")
|
||||
r.Header.Set(api.AmzGrantRead, "")
|
||||
|
||||
if newEaclTable, err = h.getNewEAclTable(r, info); err != nil {
|
||||
if newEaclTable, err = h.getNewEAclTable(r, bktInfo, info); err != nil {
|
||||
h.logAndSendError(w, "could not get new eacl table", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
@ -341,8 +343,8 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if newEaclTable != nil {
|
||||
p := &layer.PutBucketACLParams{
|
||||
Name: reqInfo.BucketName,
|
||||
EACL: newEaclTable,
|
||||
BktInfo: bktInfo,
|
||||
EACL: newEaclTable,
|
||||
}
|
||||
|
||||
if err = h.obj.PutBucketACL(r.Context(), p); err != nil {
|
||||
|
@ -351,12 +353,6 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo); err != nil {
|
||||
h.log.Warn("couldn't get bucket versioning", zap.String("bucket name", reqInfo.BucketName), zap.Error(err))
|
||||
} else if settings.VersioningEnabled {
|
||||
|
@ -446,7 +442,7 @@ func containsACLHeaders(r *http.Request) bool {
|
|||
r.Header.Get(api.AmzGrantFullControl) != "" || r.Header.Get(api.AmzGrantWrite) != ""
|
||||
}
|
||||
|
||||
func (h *handler) getNewEAclTable(r *http.Request, objInfo *data.ObjectInfo) (*eacl.Table, error) {
|
||||
func (h *handler) getNewEAclTable(r *http.Request, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) (*eacl.Table, error) {
|
||||
var newEaclTable *eacl.Table
|
||||
gateKey, err := h.gateKey(r.Context())
|
||||
if err != nil {
|
||||
|
@ -473,7 +469,7 @@ func (h *handler) getNewEAclTable(r *http.Request, objInfo *data.ObjectInfo) (*e
|
|||
return nil, fmt.Errorf("could not translate policy to ast: %w", err)
|
||||
}
|
||||
|
||||
bacl, err := h.obj.GetBucketACL(r.Context(), objInfo.Bucket)
|
||||
bacl, err := h.obj.GetBucketACL(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get bucket eacl: %w", err)
|
||||
}
|
||||
|
@ -585,32 +581,25 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
p.ObjectLockEnabled = isLockEnabled(r.Header)
|
||||
|
||||
cid, err := h.obj.CreateBucket(r.Context(), &p)
|
||||
bktInfo, err := h.obj.CreateBucket(r.Context(), &p)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not create bucket", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if p.ObjectLockEnabled {
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
sp := &layer.PutSettingsParams{
|
||||
BktInfo: bktInfo,
|
||||
Settings: &data.BucketSettings{VersioningEnabled: true},
|
||||
}
|
||||
if err = h.obj.PutBucketSettings(r.Context(), sp); err != nil {
|
||||
h.logAndSendError(w, "couldn't enable bucket versioning", reqInfo, err,
|
||||
zap.Stringer("container_id", cid))
|
||||
zap.Stringer("container_id", bktInfo.CID))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
h.log.Info("bucket is created",
|
||||
zap.String("container_id", cid.String()))
|
||||
h.log.Info("bucket is created", zap.Stringer("container_id", bktInfo.CID))
|
||||
|
||||
api.WriteSuccessResponseHeadersOnly(w)
|
||||
}
|
||||
|
|
|
@ -30,13 +30,14 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get("versionId"),
|
||||
}
|
||||
|
@ -62,13 +63,14 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
|
|||
func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get("versionId"),
|
||||
}
|
||||
|
@ -94,15 +96,16 @@ func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request
|
|||
func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
p := &layer.HeadObjectParams{
|
||||
Bucket: reqInfo.BucketName,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get("versionId"),
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
p := &layer.HeadObjectParams{
|
||||
BktInfo: bktInfo,
|
||||
Object: reqInfo.ObjectName,
|
||||
VersionID: reqInfo.URL.Query().Get("versionId"),
|
||||
}
|
||||
|
||||
objInfo, err := h.obj.GetObjectInfo(r.Context(), p)
|
||||
|
@ -111,7 +114,7 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.obj.DeleteObjectTagging(r.Context(), objInfo); err != nil {
|
||||
if err = h.obj.DeleteObjectTagging(r.Context(), bktInfo, objInfo); err != nil {
|
||||
h.logAndSendError(w, "could not delete object tagging", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
@ -127,26 +130,28 @@ func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.obj.PutBucketTagging(r.Context(), reqInfo.BucketName, tagSet); err != nil {
|
||||
if err = h.obj.PutBucketTagging(r.Context(), bktInfo, tagSet); err != nil {
|
||||
h.logAndSendError(w, "could not put object tagging", reqInfo, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
tagSet, err := h.obj.GetBucketTagging(r.Context(), reqInfo.BucketName)
|
||||
tagSet, err := h.obj.GetBucketTagging(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get object tagging", reqInfo, err)
|
||||
return
|
||||
|
@ -154,17 +159,22 @@ func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request
|
|||
|
||||
if err = api.EncodeToResponse(w, encodeTagging(tagSet)); err != nil {
|
||||
h.logAndSendError(w, "something went wrong", reqInfo, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err := h.obj.DeleteBucketTagging(r.Context(), reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "could not delete object tagging", reqInfo, err)
|
||||
|
||||
if err = h.obj.DeleteBucketTagging(r.Context(), bktInfo); err != nil {
|
||||
h.logAndSendError(w, "could not delete bucket tagging", reqInfo, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
||||
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
||||
|
@ -23,24 +25,24 @@ func (h *handler) logAndSendError(w http.ResponseWriter, logText string, reqInfo
|
|||
api.WriteErrorResponse(w, reqInfo, err)
|
||||
}
|
||||
|
||||
func (h *handler) checkBucketOwner(r *http.Request, bucket string, header ...string) error {
|
||||
func (h *handler) getBucketAndCheckOwner(r *http.Request, bucket string, header ...string) (*data.BucketInfo, error) {
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), bucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var expected string
|
||||
if len(header) == 0 {
|
||||
expected = r.Header.Get(api.AmzExpectedBucketOwner)
|
||||
} else {
|
||||
expected = header[0]
|
||||
expected = r.Header.Get(header[0])
|
||||
}
|
||||
|
||||
if len(expected) == 0 {
|
||||
return nil
|
||||
return bktInfo, nil
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkOwner(bktInfo, expected)
|
||||
return bktInfo, checkOwner(bktInfo, expected)
|
||||
}
|
||||
|
||||
func parseRange(s string) (*layer.RangeParams, error) {
|
||||
|
|
|
@ -21,15 +21,11 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
|
|||
return
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
|
@ -51,24 +47,18 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
|
|||
|
||||
if err = h.obj.PutBucketSettings(r.Context(), p); err != nil {
|
||||
h.logAndSendError(w, "couldn't put update versioning settings", reqInfo, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// GetBucketVersioningHandler implements bucket versioning getter handler.
|
||||
func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
|
||||
if err != nil {
|
||||
|
|
|
@ -122,7 +122,7 @@ func (n *layer) containerList(ctx context.Context) ([]*data.BucketInfo, error) {
|
|||
return list, nil
|
||||
}
|
||||
|
||||
func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*cid.ID, error) {
|
||||
func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error) {
|
||||
var err error
|
||||
bktInfo := &data.BucketInfo{
|
||||
Name: p.Name,
|
||||
|
@ -130,6 +130,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
|
|||
Created: time.Now(),
|
||||
BasicACL: p.ACL,
|
||||
LocationConstraint: p.LocationConstraint,
|
||||
ObjectLockEnabled: p.ObjectLockEnabled,
|
||||
}
|
||||
|
||||
var attributes [][2]string
|
||||
|
@ -169,7 +170,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
|
|||
zap.Error(err))
|
||||
}
|
||||
|
||||
return bktInfo.CID, nil
|
||||
return bktInfo, nil
|
||||
}
|
||||
|
||||
func (n *layer) setContainerEACLTable(ctx context.Context, idCnr *cid.ID, table *eacl.Table) error {
|
||||
|
|
|
@ -84,7 +84,7 @@ type (
|
|||
|
||||
// HeadObjectParams stores object head request parameters.
|
||||
HeadObjectParams struct {
|
||||
Bucket string
|
||||
BktInfo *data.BucketInfo
|
||||
Object string
|
||||
VersionID string
|
||||
}
|
||||
|
@ -97,12 +97,12 @@ type (
|
|||
|
||||
// PutObjectParams stores object put request parameters.
|
||||
PutObjectParams struct {
|
||||
Bucket string
|
||||
Object string
|
||||
Size int64
|
||||
Reader io.Reader
|
||||
Header map[string]string
|
||||
Lock *data.ObjectLock
|
||||
BktInfo *data.BucketInfo
|
||||
Object string
|
||||
Size int64
|
||||
Reader io.Reader
|
||||
Header map[string]string
|
||||
Lock *data.ObjectLock
|
||||
}
|
||||
|
||||
// PutSettingsParams stores object copy request parameters.
|
||||
|
@ -119,13 +119,13 @@ type (
|
|||
|
||||
// CopyObjectParams stores object copy request parameters.
|
||||
CopyObjectParams struct {
|
||||
SrcObject *data.ObjectInfo
|
||||
DstBucket string
|
||||
DstObject string
|
||||
SrcSize int64
|
||||
Header map[string]string
|
||||
Range *RangeParams
|
||||
Lock *data.ObjectLock
|
||||
SrcObject *data.ObjectInfo
|
||||
DstBktInfo *data.BucketInfo
|
||||
DstObject string
|
||||
SrcSize int64
|
||||
Header map[string]string
|
||||
Range *RangeParams
|
||||
Lock *data.ObjectLock
|
||||
}
|
||||
// CreateBucketParams stores bucket create request parameters.
|
||||
CreateBucketParams struct {
|
||||
|
@ -139,12 +139,12 @@ type (
|
|||
}
|
||||
// PutBucketACLParams stores put bucket acl request parameters.
|
||||
PutBucketACLParams struct {
|
||||
Name string
|
||||
EACL *eacl.Table
|
||||
BktInfo *data.BucketInfo
|
||||
EACL *eacl.Table
|
||||
}
|
||||
// DeleteBucketParams stores delete bucket request parameters.
|
||||
DeleteBucketParams struct {
|
||||
Name string
|
||||
BktInfo *data.BucketInfo
|
||||
}
|
||||
|
||||
// PutSystemObjectParams stores putSystemObject parameters.
|
||||
|
@ -159,7 +159,7 @@ type (
|
|||
|
||||
// ListObjectVersionsParams stores list objects versions parameters.
|
||||
ListObjectVersionsParams struct {
|
||||
Bucket string
|
||||
BktInfo *data.BucketInfo
|
||||
Delimiter string
|
||||
KeyMarker string
|
||||
MaxKeys int
|
||||
|
@ -196,21 +196,21 @@ type (
|
|||
|
||||
ListBuckets(ctx context.Context) ([]*data.BucketInfo, error)
|
||||
GetBucketInfo(ctx context.Context, name string) (*data.BucketInfo, error)
|
||||
GetBucketACL(ctx context.Context, name string) (*BucketACL, error)
|
||||
GetBucketACL(ctx context.Context, bktInfo *data.BucketInfo) (*BucketACL, error)
|
||||
PutBucketACL(ctx context.Context, p *PutBucketACLParams) error
|
||||
CreateBucket(ctx context.Context, p *CreateBucketParams) (*cid.ID, error)
|
||||
CreateBucket(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error)
|
||||
DeleteBucket(ctx context.Context, p *DeleteBucketParams) error
|
||||
|
||||
GetObject(ctx context.Context, p *GetObjectParams) error
|
||||
HeadSystemObject(ctx context.Context, bktInfo *data.BucketInfo, name string) (*data.ObjectInfo, error)
|
||||
GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error)
|
||||
GetObjectTagging(ctx context.Context, p *data.ObjectInfo) (map[string]string, error)
|
||||
GetBucketTagging(ctx context.Context, bucket string) (map[string]string, error)
|
||||
GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error)
|
||||
|
||||
PutObject(ctx context.Context, p *PutObjectParams) (*data.ObjectInfo, error)
|
||||
PutSystemObject(ctx context.Context, p *PutSystemObjectParams) (*data.ObjectInfo, error)
|
||||
PutObjectTagging(ctx context.Context, p *PutTaggingParams) error
|
||||
PutBucketTagging(ctx context.Context, bucket string, tagSet map[string]string) error
|
||||
PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error
|
||||
|
||||
CopyObject(ctx context.Context, p *CopyObjectParams) (*data.ObjectInfo, error)
|
||||
|
||||
|
@ -218,10 +218,10 @@ type (
|
|||
ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*ListObjectsInfoV2, error)
|
||||
ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error)
|
||||
|
||||
DeleteObjects(ctx context.Context, bucket string, objects []*VersionedObject) ([]*VersionedObject, error)
|
||||
DeleteObjects(ctx context.Context, bktInfo *data.BucketInfo, objects []*VersionedObject) ([]*VersionedObject, error)
|
||||
DeleteSystemObject(ctx context.Context, bktInfo *data.BucketInfo, name string) error
|
||||
DeleteObjectTagging(ctx context.Context, p *data.ObjectInfo) error
|
||||
DeleteBucketTagging(ctx context.Context, bucket string) error
|
||||
DeleteObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) error
|
||||
DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error
|
||||
|
||||
CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*data.ObjectInfo, error)
|
||||
UploadPart(ctx context.Context, p *UploadPartParams) (*data.ObjectInfo, error)
|
||||
|
@ -355,31 +355,21 @@ func (n *layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInf
|
|||
}
|
||||
|
||||
// GetBucketACL returns bucket acl info by name.
|
||||
func (n *layer) GetBucketACL(ctx context.Context, name string) (*BucketACL, error) {
|
||||
inf, err := n.GetBucketInfo(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eACL, err := n.GetContainerEACL(ctx, inf.CID)
|
||||
func (n *layer) GetBucketACL(ctx context.Context, bktInfo *data.BucketInfo) (*BucketACL, error) {
|
||||
eACL, err := n.GetContainerEACL(ctx, bktInfo.CID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BucketACL{
|
||||
Info: inf,
|
||||
Info: bktInfo,
|
||||
EACL: eACL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PutBucketACL put bucket acl by name.
|
||||
func (n *layer) PutBucketACL(ctx context.Context, param *PutBucketACLParams) error {
|
||||
inf, err := n.GetBucketInfo(ctx, param.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return n.setContainerEACLTable(ctx, inf.CID, param.EACL)
|
||||
return n.setContainerEACLTable(ctx, param.BktInfo.CID, param.EACL)
|
||||
}
|
||||
|
||||
// ListBuckets returns all user containers. Name of the bucket is a container
|
||||
|
@ -427,27 +417,11 @@ func (n *layer) GetObject(ctx context.Context, p *GetObjectParams) error {
|
|||
|
||||
// GetObjectInfo returns meta information about the object.
|
||||
func (n *layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error) {
|
||||
bkt, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
n.log.Error("could not fetch bucket info", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(p.VersionID) == 0 {
|
||||
return n.headLastVersionIfNotDeleted(ctx, bkt, p.Object)
|
||||
return n.headLastVersionIfNotDeleted(ctx, p.BktInfo, p.Object)
|
||||
}
|
||||
|
||||
return n.headVersion(ctx, bkt, p)
|
||||
}
|
||||
|
||||
// PutObject into storage.
|
||||
func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ObjectInfo, error) {
|
||||
bkt, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return n.objectPut(ctx, bkt, p)
|
||||
return n.headVersion(ctx, p.BktInfo, p)
|
||||
}
|
||||
|
||||
// GetObjectTagging from storage.
|
||||
|
@ -467,13 +441,8 @@ func (n *layer) GetObjectTagging(ctx context.Context, oi *data.ObjectInfo) (map[
|
|||
}
|
||||
|
||||
// GetBucketTagging from storage.
|
||||
func (n *layer) GetBucketTagging(ctx context.Context, bucketName string) (map[string]string, error) {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, bucketName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objInfo, err := n.HeadSystemObject(ctx, bktInfo, formBucketTagObjectName(bucketName))
|
||||
func (n *layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) {
|
||||
objInfo, err := n.HeadSystemObject(ctx, bktInfo, formBucketTagObjectName(bktInfo.Name))
|
||||
if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -518,41 +487,27 @@ func (n *layer) PutObjectTagging(ctx context.Context, p *PutTaggingParams) error
|
|||
}
|
||||
|
||||
// PutBucketTagging into storage.
|
||||
func (n *layer) PutBucketTagging(ctx context.Context, bucketName string, tagSet map[string]string) error {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, bucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (n *layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error {
|
||||
s := &PutSystemObjectParams{
|
||||
BktInfo: bktInfo,
|
||||
ObjName: formBucketTagObjectName(bucketName),
|
||||
ObjName: formBucketTagObjectName(bktInfo.Name),
|
||||
Metadata: tagSet,
|
||||
Prefix: tagPrefix,
|
||||
Reader: nil,
|
||||
}
|
||||
|
||||
_, err = n.PutSystemObject(ctx, s)
|
||||
_, err := n.PutSystemObject(ctx, s)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteObjectTagging from storage.
|
||||
func (n *layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectInfo) error {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n.DeleteSystemObject(ctx, bktInfo, p.TagsObject())
|
||||
func (n *layer) DeleteObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) error {
|
||||
return n.DeleteSystemObject(ctx, bktInfo, objInfo.TagsObject())
|
||||
}
|
||||
|
||||
// DeleteBucketTagging from storage.
|
||||
func (n *layer) DeleteBucketTagging(ctx context.Context, bucketName string) error {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, bucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return n.DeleteSystemObject(ctx, bktInfo, formBucketTagObjectName(bucketName))
|
||||
func (n *layer) DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error {
|
||||
return n.DeleteSystemObject(ctx, bktInfo, formBucketTagObjectName(bktInfo.Name))
|
||||
}
|
||||
|
||||
// CopyObject from one bucket into another bucket.
|
||||
|
@ -572,11 +527,11 @@ func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*data.Obje
|
|||
}()
|
||||
|
||||
return n.PutObject(ctx, &PutObjectParams{
|
||||
Bucket: p.DstBucket,
|
||||
Object: p.DstObject,
|
||||
Size: p.SrcSize,
|
||||
Reader: pr,
|
||||
Header: p.Header,
|
||||
BktInfo: p.DstBktInfo,
|
||||
Object: p.DstObject,
|
||||
Size: p.SrcSize,
|
||||
Reader: pr,
|
||||
Header: p.Header,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -588,9 +543,10 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, obj *Ver
|
|||
)
|
||||
|
||||
p := &PutObjectParams{
|
||||
Object: obj.Name,
|
||||
Reader: bytes.NewReader(nil),
|
||||
Header: map[string]string{},
|
||||
BktInfo: bkt,
|
||||
Object: obj.Name,
|
||||
Reader: bytes.NewReader(nil),
|
||||
Header: map[string]string{},
|
||||
}
|
||||
|
||||
versioningEnabled := n.isVersioningEnabled(ctx, bkt)
|
||||
|
@ -637,14 +593,14 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, obj *Ver
|
|||
obj.Error = err
|
||||
return obj
|
||||
}
|
||||
if err = n.DeleteObjectTagging(ctx, &data.ObjectInfo{ID: id, Bucket: bkt.Name, Name: obj.Name}); err != nil {
|
||||
if err = n.DeleteObjectTagging(ctx, bkt, &data.ObjectInfo{ID: id, Bucket: bkt.Name, Name: obj.Name}); err != nil {
|
||||
obj.Error = err
|
||||
return obj
|
||||
}
|
||||
}
|
||||
n.listsCache.CleanCacheEntriesContainingObject(obj.Name, bkt.CID)
|
||||
|
||||
objInfo, err := n.objectPut(ctx, bkt, p)
|
||||
objInfo, err := n.PutObject(ctx, p)
|
||||
if err != nil {
|
||||
obj.Error = err
|
||||
return obj
|
||||
|
@ -657,20 +613,15 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, obj *Ver
|
|||
}
|
||||
|
||||
// DeleteObjects from the storage.
|
||||
func (n *layer) DeleteObjects(ctx context.Context, bucket string, objects []*VersionedObject) ([]*VersionedObject, error) {
|
||||
bkt, err := n.GetBucketInfo(ctx, bucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (n *layer) DeleteObjects(ctx context.Context, bktInfo *data.BucketInfo, objects []*VersionedObject) ([]*VersionedObject, error) {
|
||||
for i, obj := range objects {
|
||||
objects[i] = n.deleteObject(ctx, bkt, obj)
|
||||
objects[i] = n.deleteObject(ctx, bktInfo, obj)
|
||||
}
|
||||
|
||||
return objects, nil
|
||||
}
|
||||
|
||||
func (n *layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*cid.ID, error) {
|
||||
func (n *layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error) {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, p.Name)
|
||||
if err != nil {
|
||||
if errors.IsS3Error(err, errors.ErrNoSuchBucket) {
|
||||
|
@ -696,12 +647,7 @@ func (n *layer) ResolveBucket(ctx context.Context, name string) (*cid.ID, error)
|
|||
}
|
||||
|
||||
func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
|
||||
bucketInfo, err := n.GetBucketInfo(ctx, p.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
objects, err := n.listSortedObjects(ctx, allObjectParams{Bucket: bucketInfo})
|
||||
objects, err := n.listSortedObjects(ctx, allObjectParams{Bucket: p.BktInfo})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -709,9 +655,6 @@ func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
|
|||
return errors.GetAPIError(errors.ErrBucketNotEmpty)
|
||||
}
|
||||
|
||||
n.bucketCache.Delete(bucketInfo.Name)
|
||||
if err = n.deleteContainer(ctx, bucketInfo.CID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
n.bucketCache.Delete(p.BktInfo.Name)
|
||||
return n.deleteContainer(ctx, p.BktInfo.CID)
|
||||
}
|
||||
|
|
|
@ -128,14 +128,14 @@ func (n *layer) UploadPart(ctx context.Context, p *UploadPartParams) (*data.Obje
|
|||
appendUploadHeaders(p.Header, p.Info.UploadID, p.Info.Key, p.PartNumber)
|
||||
|
||||
params := &PutObjectParams{
|
||||
Bucket: p.Info.Bkt.Name,
|
||||
Object: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber),
|
||||
Size: p.Size,
|
||||
Reader: p.Reader,
|
||||
Header: p.Header,
|
||||
BktInfo: p.Info.Bkt,
|
||||
Object: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber),
|
||||
Size: p.Size,
|
||||
Reader: p.Reader,
|
||||
Header: p.Header,
|
||||
}
|
||||
|
||||
return n.objectPut(ctx, p.Info.Bkt, params)
|
||||
return n.PutObject(ctx, params)
|
||||
}
|
||||
|
||||
func (n *layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.ObjectInfo, error) {
|
||||
|
@ -160,12 +160,12 @@ func (n *layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.
|
|||
appendUploadHeaders(metadata, p.Info.UploadID, p.Info.Key, p.PartNumber)
|
||||
|
||||
c := &CopyObjectParams{
|
||||
SrcObject: p.SrcObjInfo,
|
||||
DstBucket: p.Info.Bkt.Name,
|
||||
DstObject: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber),
|
||||
SrcSize: p.SrcObjInfo.Size,
|
||||
Header: metadata,
|
||||
Range: p.Range,
|
||||
SrcObject: p.SrcObjInfo,
|
||||
DstBktInfo: p.Info.Bkt,
|
||||
DstObject: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber),
|
||||
SrcSize: p.SrcObjInfo.Size,
|
||||
Header: metadata,
|
||||
Range: p.Range,
|
||||
}
|
||||
|
||||
return n.CopyObject(ctx, c)
|
||||
|
@ -287,11 +287,11 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
|
|||
|
||||
r.prm.cid = p.Info.Bkt.CID
|
||||
|
||||
obj, err = n.objectPut(ctx, p.Info.Bkt, &PutObjectParams{
|
||||
Bucket: p.Info.Bkt.Name,
|
||||
Object: p.Info.Key,
|
||||
Reader: r,
|
||||
Header: initMetadata,
|
||||
obj, err = n.PutObject(ctx, &PutObjectParams{
|
||||
BktInfo: p.Info.Bkt,
|
||||
Object: p.Info.Key,
|
||||
Reader: r,
|
||||
Header: initMetadata,
|
||||
})
|
||||
if err != nil {
|
||||
n.log.Error("could not put a completed object (multipart upload)",
|
||||
|
|
|
@ -38,7 +38,7 @@ type (
|
|||
|
||||
// ListObjectsParamsCommon contains common parameters for ListObjectsV1 and ListObjectsV2.
|
||||
ListObjectsParamsCommon struct {
|
||||
Bucket string
|
||||
BktInfo *data.BucketInfo
|
||||
Delimiter string
|
||||
Encode string
|
||||
MaxKeys int
|
||||
|
@ -153,12 +153,12 @@ func (n *layer) objectGet(ctx context.Context, addr *address.Address) (*object.O
|
|||
return res.Head, nil
|
||||
}
|
||||
|
||||
// objectPut into NeoFS, took payload from io.Reader.
|
||||
func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjectParams) (*data.ObjectInfo, error) {
|
||||
// PutObject stores object into NeoFS, took payload from io.Reader.
|
||||
func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ObjectInfo, error) {
|
||||
own := n.Owner(ctx)
|
||||
|
||||
versioningEnabled := n.isVersioningEnabled(ctx, bkt)
|
||||
versions, err := n.headVersions(ctx, bkt, p.Object)
|
||||
versioningEnabled := n.isVersioningEnabled(ctx, p.BktInfo)
|
||||
versions, err := n.headVersions(ctx, p.BktInfo, p.Object)
|
||||
if err != nil && !apiErrors.IsS3Error(err, apiErrors.ErrNoSuchKey) {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjec
|
|||
}
|
||||
|
||||
prm := neofs.PrmObjectCreate{
|
||||
Container: *bkt.CID,
|
||||
Container: *p.BktInfo.CID,
|
||||
Creator: *own,
|
||||
PayloadSize: uint64(p.Size),
|
||||
Filename: p.Object,
|
||||
|
@ -206,18 +206,18 @@ func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjec
|
|||
objInfo := &data.ObjectInfo{ID: id, Name: p.Object}
|
||||
p.Lock.Objects = append(p.Lock.Objects, *id)
|
||||
if p.Lock.LegalHold {
|
||||
if err = n.putLockObject(ctx, bkt, objInfo.LegalHoldObject(), p.Lock); err != nil {
|
||||
if err = n.putLockObject(ctx, p.BktInfo, objInfo.LegalHoldObject(), p.Lock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if !p.Lock.Until.IsZero() {
|
||||
if err = n.putLockObject(ctx, bkt, objInfo.RetentionObject(), p.Lock); err != nil {
|
||||
if err = n.putLockObject(ctx, p.BktInfo, objInfo.RetentionObject(), p.Lock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meta, err := n.objectHead(ctx, bkt.CID, id)
|
||||
meta, err := n.objectHead(ctx, p.BktInfo.CID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -226,17 +226,17 @@ func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjec
|
|||
n.log.Error("couldn't cache an object", zap.Error(err))
|
||||
}
|
||||
|
||||
n.listsCache.CleanCacheEntriesContainingObject(p.Object, bkt.CID)
|
||||
n.listsCache.CleanCacheEntriesContainingObject(p.Object, p.BktInfo.CID)
|
||||
|
||||
for _, id := range idsToDeleteArr {
|
||||
if err = n.objectDelete(ctx, bkt.CID, id); err != nil {
|
||||
if err = n.objectDelete(ctx, p.BktInfo.CID, id); err != nil {
|
||||
n.log.Warn("couldn't delete object",
|
||||
zap.Stringer("version id", id),
|
||||
zap.Error(err))
|
||||
}
|
||||
if !versioningEnabled {
|
||||
if objVersion := versions.getVersion(id); objVersion != nil {
|
||||
if err = n.DeleteObjectTagging(ctx, objVersion); err != nil {
|
||||
if err = n.DeleteObjectTagging(ctx, p.BktInfo, objVersion); err != nil {
|
||||
n.log.Warn("couldn't delete object tagging",
|
||||
zap.Stringer("version id", id),
|
||||
zap.Error(err))
|
||||
|
@ -247,10 +247,10 @@ func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjec
|
|||
|
||||
return &data.ObjectInfo{
|
||||
ID: id,
|
||||
CID: bkt.CID,
|
||||
CID: p.BktInfo.CID,
|
||||
|
||||
Owner: own,
|
||||
Bucket: p.Bucket,
|
||||
Bucket: p.BktInfo.Name,
|
||||
Name: p.Object,
|
||||
Size: p.Size,
|
||||
Created: time.Now(),
|
||||
|
@ -644,16 +644,11 @@ func triageObjects(allObjects []*data.ObjectInfo) (prefixes []string, objects []
|
|||
func (n *layer) listAllObjects(ctx context.Context, p ListObjectsParamsCommon) ([]*data.ObjectInfo, error) {
|
||||
var (
|
||||
err error
|
||||
bkt *data.BucketInfo
|
||||
allObjects []*data.ObjectInfo
|
||||
)
|
||||
|
||||
if bkt, err = n.GetBucketInfo(ctx, p.Bucket); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
allObjects, err = n.listSortedObjects(ctx, allObjectParams{
|
||||
Bucket: bkt,
|
||||
Bucket: p.BktInfo,
|
||||
Prefix: p.Prefix,
|
||||
Delimiter: p.Delimiter,
|
||||
})
|
||||
|
|
|
@ -283,18 +283,13 @@ func (v *objectVersions) getVersion(oid *oid.ID) *data.ObjectInfo {
|
|||
return nil
|
||||
}
|
||||
func (n *layer) PutBucketVersioning(ctx context.Context, p *PutSettingsParams) (*data.ObjectInfo, error) {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, p.BktInfo.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metadata := map[string]string{
|
||||
attrSettingsVersioningEnabled: strconv.FormatBool(p.Settings.VersioningEnabled),
|
||||
}
|
||||
|
||||
s := &PutSystemObjectParams{
|
||||
BktInfo: bktInfo,
|
||||
ObjName: bktInfo.SettingsObjectName(),
|
||||
BktInfo: p.BktInfo,
|
||||
ObjName: p.BktInfo.SettingsObjectName(),
|
||||
Metadata: metadata,
|
||||
Prefix: "",
|
||||
Reader: nil,
|
||||
|
@ -303,32 +298,22 @@ func (n *layer) PutBucketVersioning(ctx context.Context, p *PutSettingsParams) (
|
|||
return n.PutSystemObject(ctx, s)
|
||||
}
|
||||
|
||||
func (n *layer) GetBucketVersioning(ctx context.Context, bucketName string) (*data.BucketSettings, error) {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, bucketName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (n *layer) GetBucketVersioning(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) {
|
||||
return n.GetBucketSettings(ctx, bktInfo)
|
||||
}
|
||||
|
||||
func (n *layer) ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error) {
|
||||
var (
|
||||
versions map[string]*objectVersions
|
||||
allObjects = make([]*data.ObjectInfo, 0, p.MaxKeys)
|
||||
res = &ListObjectVersionsInfo{}
|
||||
reverse = true
|
||||
)
|
||||
|
||||
bkt, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
versions, err := n.getAllObjectsVersions(ctx, p.BktInfo, p.Prefix, p.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if versions, err = n.getAllObjectsVersions(ctx, bkt, p.Prefix, p.Delimiter); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sortedNames := make([]string, 0, len(versions))
|
||||
for k := range versions {
|
||||
sortedNames = append(sortedNames, k)
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/nspcc-dev/neofs-s3-gw/api/layer/neofs"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/internal/neofstest"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/logger"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||
|
@ -25,11 +24,11 @@ import (
|
|||
|
||||
func (tc *testContext) putObject(content []byte) *data.ObjectInfo {
|
||||
objInfo, err := tc.layer.PutObject(tc.ctx, &PutObjectParams{
|
||||
Bucket: tc.bktID.String(),
|
||||
Object: tc.obj,
|
||||
Size: int64(len(content)),
|
||||
Reader: bytes.NewReader(content),
|
||||
Header: make(map[string]string),
|
||||
BktInfo: tc.bktInfo,
|
||||
Object: tc.obj,
|
||||
Size: int64(len(content)),
|
||||
Reader: bytes.NewReader(content),
|
||||
Header: make(map[string]string),
|
||||
})
|
||||
require.NoError(tc.t, err)
|
||||
|
||||
|
@ -38,7 +37,7 @@ func (tc *testContext) putObject(content []byte) *data.ObjectInfo {
|
|||
|
||||
func (tc *testContext) getObject(objectName, versionID string, needError bool) (*data.ObjectInfo, []byte) {
|
||||
objInfo, err := tc.layer.GetObjectInfo(tc.ctx, &HeadObjectParams{
|
||||
Bucket: tc.bkt,
|
||||
BktInfo: tc.bktInfo,
|
||||
Object: objectName,
|
||||
VersionID: versionID,
|
||||
})
|
||||
|
@ -60,7 +59,7 @@ func (tc *testContext) getObject(objectName, versionID string, needError bool) (
|
|||
}
|
||||
|
||||
func (tc *testContext) deleteObject(objectName, versionID string) {
|
||||
deletedObjects, err := tc.layer.DeleteObjects(tc.ctx, tc.bkt, []*VersionedObject{
|
||||
deletedObjects, err := tc.layer.DeleteObjects(tc.ctx, tc.bktInfo, []*VersionedObject{
|
||||
{Name: objectName, VersionID: versionID},
|
||||
})
|
||||
require.NoError(tc.t, err)
|
||||
|
@ -72,7 +71,7 @@ func (tc *testContext) deleteObject(objectName, versionID string) {
|
|||
func (tc *testContext) listObjectsV1() []*data.ObjectInfo {
|
||||
res, err := tc.layer.ListObjectsV1(tc.ctx, &ListObjectsParamsV1{
|
||||
ListObjectsParamsCommon: ListObjectsParamsCommon{
|
||||
Bucket: tc.bkt,
|
||||
BktInfo: tc.bktInfo,
|
||||
MaxKeys: 1000,
|
||||
},
|
||||
})
|
||||
|
@ -83,7 +82,7 @@ func (tc *testContext) listObjectsV1() []*data.ObjectInfo {
|
|||
func (tc *testContext) listObjectsV2() []*data.ObjectInfo {
|
||||
res, err := tc.layer.ListObjectsV2(tc.ctx, &ListObjectsParamsV2{
|
||||
ListObjectsParamsCommon: ListObjectsParamsCommon{
|
||||
Bucket: tc.bkt,
|
||||
BktInfo: tc.bktInfo,
|
||||
MaxKeys: 1000,
|
||||
},
|
||||
})
|
||||
|
@ -93,7 +92,7 @@ func (tc *testContext) listObjectsV2() []*data.ObjectInfo {
|
|||
|
||||
func (tc *testContext) listVersions() *ListObjectVersionsInfo {
|
||||
res, err := tc.layer.ListObjectVersions(tc.ctx, &ListObjectVersionsParams{
|
||||
Bucket: tc.bkt,
|
||||
BktInfo: tc.bktInfo,
|
||||
MaxKeys: 1000,
|
||||
})
|
||||
require.NoError(tc.t, err)
|
||||
|
@ -129,8 +128,6 @@ type testContext struct {
|
|||
t *testing.T
|
||||
ctx context.Context
|
||||
layer Client
|
||||
bkt string
|
||||
bktID *cid.ID
|
||||
bktInfo *data.BucketInfo
|
||||
obj string
|
||||
testNeoFS *neofstest.TestNeoFS
|
||||
|
@ -172,12 +169,10 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
|||
return &testContext{
|
||||
ctx: ctx,
|
||||
layer: NewLayer(l, tp, layerCfg),
|
||||
bkt: bktName,
|
||||
bktID: bktID,
|
||||
bktInfo: &data.BucketInfo{
|
||||
Name: bktName,
|
||||
CID: bktID,
|
||||
Owner: owner.NewID(),
|
||||
CID: bktID,
|
||||
},
|
||||
obj: "obj1",
|
||||
t: t,
|
||||
|
@ -632,12 +627,7 @@ func TestSystemObjectsVersioning(t *testing.T) {
|
|||
// simulate failed deletion
|
||||
tc.testNeoFS.AddObject(addr.String(), objMeta)
|
||||
|
||||
bktInfo := &data.BucketInfo{
|
||||
Name: tc.bkt,
|
||||
CID: tc.bktID,
|
||||
}
|
||||
|
||||
versioning, err := tc.layer.GetBucketSettings(tc.ctx, bktInfo)
|
||||
versioning, err := tc.layer.GetBucketSettings(tc.ctx, tc.bktInfo)
|
||||
require.NoError(t, err)
|
||||
require.True(t, versioning.VersioningEnabled)
|
||||
}
|
||||
|
@ -652,19 +642,19 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
|
|||
"tag1": "val1",
|
||||
}
|
||||
|
||||
err := tc.layer.PutBucketTagging(tc.ctx, tc.bktID.String(), tagSet)
|
||||
err := tc.layer.PutBucketTagging(tc.ctx, tc.bktInfo, tagSet)
|
||||
require.NoError(t, err)
|
||||
|
||||
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktID.String()))
|
||||
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktInfo.CID.String()))
|
||||
|
||||
tagSet["tag2"] = "val2"
|
||||
err = tc.layer.PutBucketTagging(tc.ctx, tc.bkt, tagSet)
|
||||
err = tc.layer.PutBucketTagging(tc.ctx, tc.bktInfo, tagSet)
|
||||
require.NoError(t, err)
|
||||
|
||||
// simulate failed deletion
|
||||
tc.testNeoFS.AddObject(newAddress(objMeta.ContainerID(), objMeta.ID()).String(), objMeta)
|
||||
|
||||
tagging, err := tc.layer.GetBucketTagging(tc.ctx, tc.bkt)
|
||||
tagging, err := tc.layer.GetBucketTagging(tc.ctx, tc.bktInfo)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedTagSet := map[string]string{
|
||||
|
@ -673,8 +663,8 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
|
|||
}
|
||||
require.Equal(t, expectedTagSet, tagging)
|
||||
|
||||
err = tc.layer.DeleteBucketTagging(tc.ctx, tc.bkt)
|
||||
err = tc.layer.DeleteBucketTagging(tc.ctx, tc.bktInfo)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Nil(t, tc.getSystemObject(formBucketTagObjectName(tc.bkt)))
|
||||
require.Nil(t, tc.getSystemObject(formBucketTagObjectName(tc.bktInfo.Name)))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue