[#377] Reuse BucketInfo in layer

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-03-18 16:04:09 +03:00 committed by Angira Kekteeva
parent 46e4b28489
commit f0914b8a43
23 changed files with 341 additions and 521 deletions

View file

@ -127,19 +127,21 @@ type astOperation struct {
func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) 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 { if err != nil {
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err) h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
return 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 { if err = api.EncodeToResponse(w, h.encodeBucketACL(bucketACL)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(w, "something went wrong", reqInfo, err)
return
} }
} }
@ -183,27 +185,29 @@ func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
return 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) h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
return return
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bkt string) error { func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bktInfo *data.BucketInfo) error {
bucketACL, err := h.obj.GetBucketACL(r.Context(), bkt) bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
if err != nil { if err != nil {
return fmt.Errorf("could not get bucket eacl: %w", err) return fmt.Errorf("could not get bucket eacl: %w", err)
} }
if err = checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil { parentAst := tableToAst(bucketACL.EACL, bktInfo.Name)
return fmt.Errorf("expected owner doesn't match: %w", err)
}
parentAst := tableToAst(bucketACL.EACL, bkt)
for _, resource := range parentAst.Resources { for _, resource := range parentAst.Resources {
if resource.Bucket == bucketACL.Info.CID.String() { 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{ p := &layer.PutBucketACLParams{
Name: bkt, BktInfo: bktInfo,
EACL: table, EACL: table,
} }
if err = h.obj.PutBucketACL(r.Context(), p); err != nil { 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) { func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bucketACL, err := h.obj.GetBucketACL(r.Context(), reqInfo.BucketName)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil { bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
return return
} }
@ -280,8 +286,14 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
return 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{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: versionID, VersionID: versionID,
} }
@ -291,7 +303,7 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
return 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) h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
return 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) { func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bucketACL, err := h.obj.GetBucketACL(r.Context(), reqInfo.BucketName)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err = checkOwner(bucketACL.Info, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil { bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not fetch bucket acl", reqInfo, err)
return return
} }
@ -336,6 +350,13 @@ func checkOwner(info *data.BucketInfo, owner string) error {
func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) 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} bktPolicy := &bucketPolicy{Bucket: reqInfo.BucketName}
if err := json.NewDecoder(r.Body).Decode(bktPolicy); err != nil { if err := json.NewDecoder(r.Body).Decode(bktPolicy); err != nil {
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err) 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 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) h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
return return
} }
w.WriteHeader(http.StatusOK)
} }
func parseACLHeaders(header http.Header, gateKey *keys.PublicKey) (*AccessControlPolicy, error) { func parseACLHeaders(header http.Header, gateKey *keys.PublicKey) (*AccessControlPolicy, error) {

View file

@ -59,7 +59,6 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: srcBucket,
Object: srcObject, Object: srcObject,
VersionID: versionID, VersionID: versionID,
} }
@ -71,12 +70,14 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
if err = h.checkBucketOwner(r, srcBucket, r.Header.Get(api.AmzSourceExpectedBucketOwner)); err != nil { if p.BktInfo, err = h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner); err != nil {
h.logAndSendError(w, "source expected owner doesn't match", reqInfo, err) h.logAndSendError(w, "couldn't get source bucket", reqInfo, err)
return 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 return
} }
@ -100,26 +101,20 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
params := &layer.CopyObjectParams{ params := &layer.CopyObjectParams{
SrcObject: info, SrcObject: info,
DstBucket: reqInfo.BucketName, DstBktInfo: dstBktInfo,
DstObject: reqInfo.ObjectName, DstObject: reqInfo.ObjectName,
SrcSize: info.Size, SrcSize: info.Size,
Header: metadata, Header: metadata,
} }
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) settings, err := h.obj.GetBucketSettings(r.Context(), dstBktInfo)
if err != nil {
h.logAndSendError(w, "could not get bucket", reqInfo, err)
return
}
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(w, "could not get bucket settings", reqInfo, err)
return return
} }
params.Lock, err = formObjectLock(bktInfo, settings.LockConfiguration, r.Header) params.Lock, err = formObjectLock(dstBktInfo, settings.LockConfiguration, r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not form object lock", reqInfo, err) h.logAndSendError(w, "could not form object lock", reqInfo, err)
return return

View file

@ -19,17 +19,12 @@ const (
func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) cors, err := h.obj.GetBucketCORS(r.Context(), bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get cors", reqInfo, err) 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) { func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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{ p := &layer.PutCORSParams{
BktInfo: bktInfo, BktInfo: bktInfo,
Reader: r.Body, 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) { func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil { if err = h.obj.DeleteBucketCORS(r.Context(), bktInfo); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
if err := h.obj.DeleteBucketCORS(r.Context(), bktInfo); err != nil {
h.logAndSendError(w, "could not delete cors", reqInfo, err) h.logAndSendError(w, "could not delete cors", reqInfo, err)
} }

View file

@ -60,12 +60,13 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
}} }}
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
deletedObjects, err := h.obj.DeleteObjects(r.Context(), reqInfo.BucketName, versionedObject) deletedObjects, err := h.obj.DeleteObjects(r.Context(), bktInfo, versionedObject)
deletedObject := deletedObjects[0] deletedObject := deletedObjects[0]
if err == nil { if err == nil {
err = deletedObject.Error err = deletedObject.Error
@ -131,8 +132,9 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
DeletedObjects: make([]DeletedObject, 0, len(toRemove)), DeletedObjects: make([]DeletedObject, 0, len(toRemove)),
} }
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
@ -143,7 +145,7 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
return nil 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 { if !requested.Quiet && err != nil {
h.logAndSendError(w, "couldn't delete objects", reqInfo, err) h.logAndSendError(w, "couldn't delete objects", reqInfo, err)
return 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) { func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) h.logAndSendError(w, "couldn't delete bucket", reqInfo, err)
} }
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)

View file

@ -115,18 +115,14 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
} }

View file

@ -77,20 +77,22 @@ func createTestBucket(ctx context.Context, t *testing.T, h *handlerContext, bktN
require.NoError(t, err) 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{ cnrID, err := h.MockedPool().CreateContainer(ctx, neofs.PrmContainerCreate{
Name: bktName, Name: bktName,
AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}}, AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}},
}) })
require.NoError(t, err) require.NoError(t, err)
bktInfo := &data.BucketInfo{
CID: cnrID,
Name: bktName,
ObjectLockEnabled: true,
Owner: owner.NewID(),
}
sp := &layer.PutSettingsParams{ sp := &layer.PutSettingsParams{
BktInfo: &data.BucketInfo{ BktInfo: bktInfo,
CID: cnrID,
Name: bktName,
ObjectLockEnabled: true,
Owner: owner.NewID(),
},
Settings: &data.BucketSettings{ Settings: &data.BucketSettings{
VersioningEnabled: true, VersioningEnabled: true,
LockConfiguration: conf, LockConfiguration: conf,
@ -99,19 +101,21 @@ func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerConte
err = h.Layer().PutBucketSettings(ctx, sp) err = h.Layer().PutBucketSettings(ctx, sp)
require.NoError(t, err) 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) content := make([]byte, 1024)
_, err := rand.Read(content) _, err := rand.Read(content)
require.NoError(t, err) require.NoError(t, err)
_, err = h.Layer().PutObject(ctx, &layer.PutObjectParams{ _, err = h.Layer().PutObject(ctx, &layer.PutObjectParams{
Bucket: bktName, BktInfo: bktInfo,
Object: objName, Object: objName,
Size: int64(len(content)), Size: int64(len(content)),
Reader: bytes.NewReader(content), Reader: bytes.NewReader(content),
Header: make(map[string]string), Header: make(map[string]string),
}) })
require.NoError(t, err) require.NoError(t, err)
} }

View file

@ -34,18 +34,14 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
reqInfo = api.GetReqInfo(r.Context()) reqInfo = api.GetReqInfo(r.Context())
) )
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), 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) { func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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()) w.Header().Set(api.ContainerID, bktInfo.CID.String())
api.WriteResponse(w, http.StatusOK, nil, api.MimeNone) api.WriteResponse(w, http.StatusOK, nil, api.MimeNone)

View file

@ -9,17 +9,12 @@ import (
func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if err = api.EncodeToResponse(w, LocationResponse{Location: bktInfo.LocationConstraint}); err != nil {
h.logAndSendError(w, "couldn't encode bucket location response", reqInfo, err) h.logAndSendError(w, "couldn't encode bucket location response", reqInfo, err)
} }

View file

@ -28,15 +28,11 @@ const (
func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "couldn't put object locking configuration", reqInfo, 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) { func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, 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) { func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
@ -143,7 +131,7 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), 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) { func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
@ -204,7 +188,7 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), 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) { func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound)) apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound))
@ -263,7 +242,7 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), 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) { func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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 { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
@ -334,7 +309,7 @@ func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
} }

View file

@ -463,10 +463,10 @@ func TestObjectLegalHold(t *testing.T) {
hc := prepareHandlerContext(t) hc := prepareHandlerContext(t)
bktName := "bucket-lock-enabled" bktName := "bucket-lock-enabled"
createTestBucketWithLock(ctx, t, hc, bktName, nil) bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
objName := "obj-for-legal-hold" objName := "obj-for-legal-hold"
createTestObject(ctx, t, hc, bktName, objName) createTestObject(ctx, t, hc, bktInfo, objName)
w, r := prepareTestRequest(t, bktName, objName, nil) w, r := prepareTestRequest(t, bktName, objName, nil)
hc.Handler().GetObjectLegalHoldHandler(w, r) hc.Handler().GetObjectLegalHoldHandler(w, r)
@ -512,10 +512,10 @@ func TestObjectRetention(t *testing.T) {
hc := prepareHandlerContext(t) hc := prepareHandlerContext(t)
bktName := "bucket-lock-enabled" bktName := "bucket-lock-enabled"
createTestBucketWithLock(ctx, t, hc, bktName, nil) bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
objName := "obj-for-retention" objName := "obj-for-retention"
createTestObject(ctx, t, hc, bktName, objName) createTestObject(ctx, t, hc, bktInfo, objName)
w, r := prepareTestRequest(t, bktName, objName, nil) w, r := prepareTestRequest(t, bktName, objName, nil)
hc.Handler().GetObjectRetentionHandler(w, r) hc.Handler().GetObjectRetentionHandler(w, r)

View file

@ -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 */ (min value of partNumber of a common part is 1) and holding data: metadata, acl, tagging */
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
var ( var (
hasData bool hasData bool
b []byte 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) { func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
var ( var (
queryValues = r.URL.Query() queryValues = r.URL.Query()
uploadID = queryValues.Get(uploadIDHeaderName) 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) { 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 ( var (
versionID string versionID string
reqInfo = api.GetReqInfo(r.Context())
queryValues = reqInfo.URL.Query() queryValues = reqInfo.URL.Query()
uploadID = queryValues.Get(uploadIDHeaderName) uploadID = queryValues.Get(uploadIDHeaderName)
additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("Key", reqInfo.ObjectName)} 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 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{ srcInfo, err := h.obj.GetObjectInfo(r.Context(), &layer.HeadObjectParams{
Bucket: srcBucket, BktInfo: srcBktInfo,
Object: srcObject, Object: srcObject,
VersionID: versionID, VersionID: versionID,
}) })
@ -318,11 +308,6 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
return 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{ p := &layer.UploadCopyParams{
Info: &layer.UploadInfoParams{ Info: &layer.UploadInfoParams{
UploadID: uploadID, 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) { func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
var ( var (
uploadID = r.URL.Query().Get(uploadIDHeaderName) uploadID = r.URL.Query().Get(uploadIDHeaderName)
uploadInfo = &layer.UploadInfoParams{ 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...) h.logAndSendError(w, "could not translate acl of completed multipart upload to ast", reqInfo, err, additional...)
return 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...) h.logAndSendError(w, "could not update bucket acl while completing multipart upload", reqInfo, err, additional...)
return return
} }
} }
} }
_, err = h.obj.DeleteObjects(r.Context(), bktInfo.Name, []*layer.VersionedObject{{Name: initPart.Name}}) if _, err = h.obj.DeleteObjects(r.Context(), bktInfo, []*layer.VersionedObject{{Name: initPart.Name}}); err != nil {
if err != nil {
h.logAndSendError(w, "could not delete init file of multipart upload", reqInfo, err, additional...) h.logAndSendError(w, "could not delete init file of multipart upload", reqInfo, err, additional...)
return return
} }
@ -472,17 +451,12 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
var ( var (
queryValues = reqInfo.URL.Query() queryValues = reqInfo.URL.Query()
delimiter = queryValues.Get("delimiter") 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) { func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
var ( var (
partNumberMarker int 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) { func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
if err := checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
var ( var (
queryValues = reqInfo.URL.Query() queryValues = reqInfo.URL.Query()
uploadID = queryValues.Get(uploadIDHeaderName) uploadID = queryValues.Get(uploadIDHeaderName)

View file

@ -16,15 +16,11 @@ type NotificationConfiguration struct {
func (h *handler) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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{ p := &layer.PutBucketNotificationConfigurationParams{
BktInfo: bktInfo, 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) { func (h *handler) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) conf, err := h.obj.GetBucketNotificationConfiguration(r.Context(), bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket notification configuration", reqInfo, err) h.logAndSendError(w, "could not get bucket notification configuration", reqInfo, err)

View file

@ -22,8 +22,8 @@ func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
return return
} }
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil { if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
@ -40,7 +40,7 @@ func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
func encodeV1(p *layer.ListObjectsParamsV1, list *layer.ListObjectsInfoV1) *ListObjectsV1Response { func encodeV1(p *layer.ListObjectsParamsV1, list *layer.ListObjectsInfoV1) *ListObjectsV1Response {
res := &ListObjectsV1Response{ res := &ListObjectsV1Response{
Name: p.Bucket, Name: p.BktInfo.Name,
EncodingType: p.Encode, EncodingType: p.Encode,
Marker: p.Marker, Marker: p.Marker,
Prefix: p.Prefix, Prefix: p.Prefix,
@ -66,8 +66,8 @@ func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
return return
} }
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil { if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
@ -84,7 +84,7 @@ func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
func encodeV2(p *layer.ListObjectsParamsV2, list *layer.ListObjectsInfoV2) *ListObjectsV2Response { func encodeV2(p *layer.ListObjectsParamsV2, list *layer.ListObjectsInfoV2) *ListObjectsV2Response {
res := &ListObjectsV2Response{ res := &ListObjectsV2Response{
Name: p.Bucket, Name: p.BktInfo.Name,
EncodingType: p.Encode, EncodingType: p.Encode,
Prefix: s3PathEncode(p.Prefix, p.Encode), Prefix: s3PathEncode(p.Prefix, p.Encode),
KeyCount: len(list.Objects) + len(list.Prefixes), KeyCount: len(list.Objects) + len(list.Prefixes),
@ -149,7 +149,6 @@ func parseListObjectArgs(reqInfo *api.ReqInfo) (*layer.ListObjectsParamsCommon,
queryValues = reqInfo.URL.Query() queryValues = reqInfo.URL.Query()
) )
res.Bucket = reqInfo.BucketName
res.Delimiter = queryValues.Get("delimiter") res.Delimiter = queryValues.Get("delimiter")
res.Encode = queryValues.Get("encoding-type") res.Encode = queryValues.Get("encoding-type")
@ -218,15 +217,10 @@ func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http
return return
} }
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) if p.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) info, err := h.obj.ListObjectVersions(r.Context(), p)
if err != nil { if err != nil {
@ -234,7 +228,7 @@ func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http
return return
} }
response := encodeListObjectVersionsToResponse(info, p.Bucket) response := encodeListObjectVersionsToResponse(info, p.BktInfo.Name)
if err = api.EncodeToResponse(w, response); err != nil { if err = api.EncodeToResponse(w, response); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) 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.Delimiter = queryValues.Get("delimiter")
res.Encode = queryValues.Get("encoding-type") res.Encode = queryValues.Get("encoding-type")
res.VersionIDMarker = queryValues.Get("version-id-marker") res.VersionIDMarker = queryValues.Get("version-id-marker")
res.Bucket = reqInfo.BucketName
return &res, nil return &res, nil
} }

View file

@ -180,13 +180,9 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket", reqInfo, err) 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 return
} }
@ -202,11 +198,11 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
params := &layer.PutObjectParams{ params := &layer.PutObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
Reader: r.Body, Reader: r.Body,
Size: r.ContentLength, Size: r.ContentLength,
Header: metadata, Header: metadata,
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) 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 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) h.logAndSendError(w, "could not get new eacl table", reqInfo, err)
return return
} }
@ -243,8 +239,8 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
if newEaclTable != nil { if newEaclTable != nil {
p := &layer.PutBucketACLParams{ p := &layer.PutBucketACLParams{
Name: reqInfo.BucketName, BktInfo: bktInfo,
EACL: newEaclTable, EACL: newEaclTable,
} }
if err = h.obj.PutBucketACL(r.Context(), p); err != nil { 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)) h.log.Warn("couldn't get bucket versioning", zap.String("bucket name", reqInfo.BucketName), zap.Error(err))
} else if settings.VersioningEnabled { } else if settings.VersioningEnabled {
w.Header().Set(api.AmzVersionID, info.Version()) w.Header().Set(api.AmzVersionID, info.Version())
@ -306,12 +302,18 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
return 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{ params := &layer.PutObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
Reader: contentReader, Reader: contentReader,
Size: size, Size: size,
Header: metadata, Header: metadata,
} }
info, err := h.obj.PutObject(r.Context(), params) 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.AmzGrantWrite, "")
r.Header.Set(api.AmzGrantRead, "") 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) h.logAndSendError(w, "could not get new eacl table", reqInfo, err)
return return
} }
@ -341,8 +343,8 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
if newEaclTable != nil { if newEaclTable != nil {
p := &layer.PutBucketACLParams{ p := &layer.PutBucketACLParams{
Name: reqInfo.BucketName, BktInfo: bktInfo,
EACL: newEaclTable, EACL: newEaclTable,
} }
if err = h.obj.PutBucketACL(r.Context(), p); err != nil { 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 { 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)) h.log.Warn("couldn't get bucket versioning", zap.String("bucket name", reqInfo.BucketName), zap.Error(err))
} else if settings.VersioningEnabled { } else if settings.VersioningEnabled {
@ -446,7 +442,7 @@ func containsACLHeaders(r *http.Request) bool {
r.Header.Get(api.AmzGrantFullControl) != "" || r.Header.Get(api.AmzGrantWrite) != "" 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 var newEaclTable *eacl.Table
gateKey, err := h.gateKey(r.Context()) gateKey, err := h.gateKey(r.Context())
if err != nil { 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) 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 { if err != nil {
return nil, fmt.Errorf("could not get bucket eacl: %w", err) 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) p.ObjectLockEnabled = isLockEnabled(r.Header)
cid, err := h.obj.CreateBucket(r.Context(), &p) bktInfo, err := h.obj.CreateBucket(r.Context(), &p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not create bucket", reqInfo, err) h.logAndSendError(w, "could not create bucket", reqInfo, err)
return return
} }
if p.ObjectLockEnabled { 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{ sp := &layer.PutSettingsParams{
BktInfo: bktInfo, BktInfo: bktInfo,
Settings: &data.BucketSettings{VersioningEnabled: true}, Settings: &data.BucketSettings{VersioningEnabled: true},
} }
if err = h.obj.PutBucketSettings(r.Context(), sp); err != nil { if err = h.obj.PutBucketSettings(r.Context(), sp); err != nil {
h.logAndSendError(w, "couldn't enable bucket versioning", reqInfo, err, h.logAndSendError(w, "couldn't enable bucket versioning", reqInfo, err,
zap.Stringer("container_id", cid)) zap.Stringer("container_id", bktInfo.CID))
return return
} }
} }
h.log.Info("bucket is created", h.log.Info("bucket is created", zap.Stringer("container_id", bktInfo.CID))
zap.String("container_id", cid.String()))
api.WriteSuccessResponseHeadersOnly(w) api.WriteSuccessResponseHeadersOnly(w)
} }

View file

@ -30,13 +30,14 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
return return
} }
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get("versionId"), 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) { func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
p := &layer.HeadObjectParams{ p := &layer.HeadObjectParams{
Bucket: reqInfo.BucketName, BktInfo: bktInfo,
Object: reqInfo.ObjectName, Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get("versionId"), 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) { func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
p := &layer.HeadObjectParams{ bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
Bucket: reqInfo.BucketName, if err != nil {
Object: reqInfo.ObjectName, h.logAndSendError(w, "could not get bucket info", reqInfo, err)
VersionID: reqInfo.URL.Query().Get("versionId"), return
} }
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil { p := &layer.HeadObjectParams{
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) BktInfo: bktInfo,
return Object: reqInfo.ObjectName,
VersionID: reqInfo.URL.Query().Get("versionId"),
} }
objInfo, err := h.obj.GetObjectInfo(r.Context(), p) objInfo, err := h.obj.GetObjectInfo(r.Context(), p)
@ -111,7 +114,7 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
return 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) h.logAndSendError(w, "could not delete object tagging", reqInfo, err)
return return
} }
@ -127,26 +130,28 @@ func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request
return return
} }
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) 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) { func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil { bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err) if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return return
} }
tagSet, err := h.obj.GetBucketTagging(r.Context(), reqInfo.BucketName) tagSet, err := h.obj.GetBucketTagging(r.Context(), bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get object tagging", reqInfo, err) h.logAndSendError(w, "could not get object tagging", reqInfo, err)
return return
@ -154,17 +159,22 @@ func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request
if err = api.EncodeToResponse(w, encodeTagging(tagSet)); err != nil { if err = api.EncodeToResponse(w, encodeTagging(tagSet)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(w, "something went wrong", reqInfo, err)
return
} }
} }
func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) 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 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) w.WriteHeader(http.StatusNoContent)
} }

View file

@ -5,6 +5,8 @@ import (
"strconv" "strconv"
"strings" "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"
"github.com/nspcc-dev/neofs-s3-gw/api/errors" "github.com/nspcc-dev/neofs-s3-gw/api/errors"
"github.com/nspcc-dev/neofs-s3-gw/api/layer" "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) 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 var expected string
if len(header) == 0 { if len(header) == 0 {
expected = r.Header.Get(api.AmzExpectedBucketOwner) expected = r.Header.Get(api.AmzExpectedBucketOwner)
} else { } else {
expected = header[0] expected = r.Header.Get(header[0])
} }
if len(expected) == 0 { if len(expected) == 0 {
return nil return bktInfo, nil
} }
bktInfo, err := h.obj.GetBucketInfo(r.Context(), bucket) return bktInfo, checkOwner(bktInfo, expected)
if err != nil {
return err
}
return checkOwner(bktInfo, expected)
} }
func parseRange(s string) (*layer.RangeParams, error) { func parseRange(s string) (*layer.RangeParams, error) {

View file

@ -21,15 +21,11 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
return return
} }
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
if err != nil { 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 { if err = h.obj.PutBucketSettings(r.Context(), p); err != nil {
h.logAndSendError(w, "couldn't put update versioning settings", reqInfo, err) h.logAndSendError(w, "couldn't put update versioning settings", reqInfo, err)
return
} }
w.WriteHeader(http.StatusOK)
} }
// GetBucketVersioningHandler implements bucket versioning getter handler. // GetBucketVersioningHandler implements bucket versioning getter handler.
func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context()) reqInfo := api.GetReqInfo(r.Context())
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return 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) settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
if err != nil { if err != nil {

View file

@ -122,7 +122,7 @@ func (n *layer) containerList(ctx context.Context) ([]*data.BucketInfo, error) {
return list, nil 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 var err error
bktInfo := &data.BucketInfo{ bktInfo := &data.BucketInfo{
Name: p.Name, Name: p.Name,
@ -130,6 +130,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
Created: time.Now(), Created: time.Now(),
BasicACL: p.ACL, BasicACL: p.ACL,
LocationConstraint: p.LocationConstraint, LocationConstraint: p.LocationConstraint,
ObjectLockEnabled: p.ObjectLockEnabled,
} }
var attributes [][2]string var attributes [][2]string
@ -169,7 +170,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
zap.Error(err)) zap.Error(err))
} }
return bktInfo.CID, nil return bktInfo, nil
} }
func (n *layer) setContainerEACLTable(ctx context.Context, idCnr *cid.ID, table *eacl.Table) error { func (n *layer) setContainerEACLTable(ctx context.Context, idCnr *cid.ID, table *eacl.Table) error {

View file

@ -84,7 +84,7 @@ type (
// HeadObjectParams stores object head request parameters. // HeadObjectParams stores object head request parameters.
HeadObjectParams struct { HeadObjectParams struct {
Bucket string BktInfo *data.BucketInfo
Object string Object string
VersionID string VersionID string
} }
@ -97,12 +97,12 @@ type (
// PutObjectParams stores object put request parameters. // PutObjectParams stores object put request parameters.
PutObjectParams struct { PutObjectParams struct {
Bucket string BktInfo *data.BucketInfo
Object string Object string
Size int64 Size int64
Reader io.Reader Reader io.Reader
Header map[string]string Header map[string]string
Lock *data.ObjectLock Lock *data.ObjectLock
} }
// PutSettingsParams stores object copy request parameters. // PutSettingsParams stores object copy request parameters.
@ -119,13 +119,13 @@ type (
// CopyObjectParams stores object copy request parameters. // CopyObjectParams stores object copy request parameters.
CopyObjectParams struct { CopyObjectParams struct {
SrcObject *data.ObjectInfo SrcObject *data.ObjectInfo
DstBucket string DstBktInfo *data.BucketInfo
DstObject string DstObject string
SrcSize int64 SrcSize int64
Header map[string]string Header map[string]string
Range *RangeParams Range *RangeParams
Lock *data.ObjectLock Lock *data.ObjectLock
} }
// CreateBucketParams stores bucket create request parameters. // CreateBucketParams stores bucket create request parameters.
CreateBucketParams struct { CreateBucketParams struct {
@ -139,12 +139,12 @@ type (
} }
// PutBucketACLParams stores put bucket acl request parameters. // PutBucketACLParams stores put bucket acl request parameters.
PutBucketACLParams struct { PutBucketACLParams struct {
Name string BktInfo *data.BucketInfo
EACL *eacl.Table EACL *eacl.Table
} }
// DeleteBucketParams stores delete bucket request parameters. // DeleteBucketParams stores delete bucket request parameters.
DeleteBucketParams struct { DeleteBucketParams struct {
Name string BktInfo *data.BucketInfo
} }
// PutSystemObjectParams stores putSystemObject parameters. // PutSystemObjectParams stores putSystemObject parameters.
@ -159,7 +159,7 @@ type (
// ListObjectVersionsParams stores list objects versions parameters. // ListObjectVersionsParams stores list objects versions parameters.
ListObjectVersionsParams struct { ListObjectVersionsParams struct {
Bucket string BktInfo *data.BucketInfo
Delimiter string Delimiter string
KeyMarker string KeyMarker string
MaxKeys int MaxKeys int
@ -196,21 +196,21 @@ type (
ListBuckets(ctx context.Context) ([]*data.BucketInfo, error) ListBuckets(ctx context.Context) ([]*data.BucketInfo, error)
GetBucketInfo(ctx context.Context, name string) (*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 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 DeleteBucket(ctx context.Context, p *DeleteBucketParams) error
GetObject(ctx context.Context, p *GetObjectParams) error GetObject(ctx context.Context, p *GetObjectParams) error
HeadSystemObject(ctx context.Context, bktInfo *data.BucketInfo, name string) (*data.ObjectInfo, error) HeadSystemObject(ctx context.Context, bktInfo *data.BucketInfo, name string) (*data.ObjectInfo, error)
GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error)
GetObjectTagging(ctx context.Context, p *data.ObjectInfo) (map[string]string, 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) PutObject(ctx context.Context, p *PutObjectParams) (*data.ObjectInfo, error)
PutSystemObject(ctx context.Context, p *PutSystemObjectParams) (*data.ObjectInfo, error) PutSystemObject(ctx context.Context, p *PutSystemObjectParams) (*data.ObjectInfo, error)
PutObjectTagging(ctx context.Context, p *PutTaggingParams) 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) CopyObject(ctx context.Context, p *CopyObjectParams) (*data.ObjectInfo, error)
@ -218,10 +218,10 @@ type (
ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*ListObjectsInfoV2, error) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*ListObjectsInfoV2, error)
ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, 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 DeleteSystemObject(ctx context.Context, bktInfo *data.BucketInfo, name string) error
DeleteObjectTagging(ctx context.Context, p *data.ObjectInfo) error DeleteObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) error
DeleteBucketTagging(ctx context.Context, bucket string) error DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error
CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*data.ObjectInfo, error) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*data.ObjectInfo, error)
UploadPart(ctx context.Context, p *UploadPartParams) (*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. // GetBucketACL returns bucket acl info by name.
func (n *layer) GetBucketACL(ctx context.Context, name string) (*BucketACL, error) { func (n *layer) GetBucketACL(ctx context.Context, bktInfo *data.BucketInfo) (*BucketACL, error) {
inf, err := n.GetBucketInfo(ctx, name) eACL, err := n.GetContainerEACL(ctx, bktInfo.CID)
if err != nil {
return nil, err
}
eACL, err := n.GetContainerEACL(ctx, inf.CID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &BucketACL{ return &BucketACL{
Info: inf, Info: bktInfo,
EACL: eACL, EACL: eACL,
}, nil }, nil
} }
// PutBucketACL put bucket acl by name. // PutBucketACL put bucket acl by name.
func (n *layer) PutBucketACL(ctx context.Context, param *PutBucketACLParams) error { func (n *layer) PutBucketACL(ctx context.Context, param *PutBucketACLParams) error {
inf, err := n.GetBucketInfo(ctx, param.Name) return n.setContainerEACLTable(ctx, param.BktInfo.CID, param.EACL)
if err != nil {
return err
}
return n.setContainerEACLTable(ctx, inf.CID, param.EACL)
} }
// ListBuckets returns all user containers. Name of the bucket is a container // 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. // GetObjectInfo returns meta information about the object.
func (n *layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error) { 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 { 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) return n.headVersion(ctx, p.BktInfo, 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)
} }
// GetObjectTagging from storage. // GetObjectTagging from storage.
@ -467,13 +441,8 @@ func (n *layer) GetObjectTagging(ctx context.Context, oi *data.ObjectInfo) (map[
} }
// GetBucketTagging from storage. // GetBucketTagging from storage.
func (n *layer) GetBucketTagging(ctx context.Context, bucketName string) (map[string]string, error) { func (n *layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) {
bktInfo, err := n.GetBucketInfo(ctx, bucketName) objInfo, err := n.HeadSystemObject(ctx, bktInfo, formBucketTagObjectName(bktInfo.Name))
if err != nil {
return nil, err
}
objInfo, err := n.HeadSystemObject(ctx, bktInfo, formBucketTagObjectName(bucketName))
if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) { if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) {
return nil, err return nil, err
} }
@ -518,41 +487,27 @@ func (n *layer) PutObjectTagging(ctx context.Context, p *PutTaggingParams) error
} }
// PutBucketTagging into storage. // PutBucketTagging into storage.
func (n *layer) PutBucketTagging(ctx context.Context, bucketName string, tagSet map[string]string) error { func (n *layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error {
bktInfo, err := n.GetBucketInfo(ctx, bucketName)
if err != nil {
return err
}
s := &PutSystemObjectParams{ s := &PutSystemObjectParams{
BktInfo: bktInfo, BktInfo: bktInfo,
ObjName: formBucketTagObjectName(bucketName), ObjName: formBucketTagObjectName(bktInfo.Name),
Metadata: tagSet, Metadata: tagSet,
Prefix: tagPrefix, Prefix: tagPrefix,
Reader: nil, Reader: nil,
} }
_, err = n.PutSystemObject(ctx, s) _, err := n.PutSystemObject(ctx, s)
return err return err
} }
// DeleteObjectTagging from storage. // DeleteObjectTagging from storage.
func (n *layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectInfo) error { func (n *layer) DeleteObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) error {
bktInfo, err := n.GetBucketInfo(ctx, p.Bucket) return n.DeleteSystemObject(ctx, bktInfo, objInfo.TagsObject())
if err != nil {
return err
}
return n.DeleteSystemObject(ctx, bktInfo, p.TagsObject())
} }
// DeleteBucketTagging from storage. // DeleteBucketTagging from storage.
func (n *layer) DeleteBucketTagging(ctx context.Context, bucketName string) error { func (n *layer) DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error {
bktInfo, err := n.GetBucketInfo(ctx, bucketName) return n.DeleteSystemObject(ctx, bktInfo, formBucketTagObjectName(bktInfo.Name))
if err != nil {
return err
}
return n.DeleteSystemObject(ctx, bktInfo, formBucketTagObjectName(bucketName))
} }
// CopyObject from one bucket into another bucket. // 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{ return n.PutObject(ctx, &PutObjectParams{
Bucket: p.DstBucket, BktInfo: p.DstBktInfo,
Object: p.DstObject, Object: p.DstObject,
Size: p.SrcSize, Size: p.SrcSize,
Reader: pr, Reader: pr,
Header: p.Header, Header: p.Header,
}) })
} }
@ -588,9 +543,10 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, obj *Ver
) )
p := &PutObjectParams{ p := &PutObjectParams{
Object: obj.Name, BktInfo: bkt,
Reader: bytes.NewReader(nil), Object: obj.Name,
Header: map[string]string{}, Reader: bytes.NewReader(nil),
Header: map[string]string{},
} }
versioningEnabled := n.isVersioningEnabled(ctx, bkt) versioningEnabled := n.isVersioningEnabled(ctx, bkt)
@ -637,14 +593,14 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, obj *Ver
obj.Error = err obj.Error = err
return obj 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 obj.Error = err
return obj return obj
} }
} }
n.listsCache.CleanCacheEntriesContainingObject(obj.Name, bkt.CID) n.listsCache.CleanCacheEntriesContainingObject(obj.Name, bkt.CID)
objInfo, err := n.objectPut(ctx, bkt, p) objInfo, err := n.PutObject(ctx, p)
if err != nil { if err != nil {
obj.Error = err obj.Error = err
return obj return obj
@ -657,20 +613,15 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, obj *Ver
} }
// DeleteObjects from the storage. // DeleteObjects from the storage.
func (n *layer) DeleteObjects(ctx context.Context, bucket string, objects []*VersionedObject) ([]*VersionedObject, error) { func (n *layer) DeleteObjects(ctx context.Context, bktInfo *data.BucketInfo, objects []*VersionedObject) ([]*VersionedObject, error) {
bkt, err := n.GetBucketInfo(ctx, bucket)
if err != nil {
return nil, err
}
for i, obj := range objects { for i, obj := range objects {
objects[i] = n.deleteObject(ctx, bkt, obj) objects[i] = n.deleteObject(ctx, bktInfo, obj)
} }
return objects, nil 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) bktInfo, err := n.GetBucketInfo(ctx, p.Name)
if err != nil { if err != nil {
if errors.IsS3Error(err, errors.ErrNoSuchBucket) { 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 { func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
bucketInfo, err := n.GetBucketInfo(ctx, p.Name) objects, err := n.listSortedObjects(ctx, allObjectParams{Bucket: p.BktInfo})
if err != nil {
return err
}
objects, err := n.listSortedObjects(ctx, allObjectParams{Bucket: bucketInfo})
if err != nil { if err != nil {
return err return err
} }
@ -709,9 +655,6 @@ func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
return errors.GetAPIError(errors.ErrBucketNotEmpty) return errors.GetAPIError(errors.ErrBucketNotEmpty)
} }
n.bucketCache.Delete(bucketInfo.Name) n.bucketCache.Delete(p.BktInfo.Name)
if err = n.deleteContainer(ctx, bucketInfo.CID); err != nil { return n.deleteContainer(ctx, p.BktInfo.CID)
return err
}
return nil
} }

View file

@ -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) appendUploadHeaders(p.Header, p.Info.UploadID, p.Info.Key, p.PartNumber)
params := &PutObjectParams{ params := &PutObjectParams{
Bucket: p.Info.Bkt.Name, BktInfo: p.Info.Bkt,
Object: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber), Object: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber),
Size: p.Size, Size: p.Size,
Reader: p.Reader, Reader: p.Reader,
Header: p.Header, 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) { 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) appendUploadHeaders(metadata, p.Info.UploadID, p.Info.Key, p.PartNumber)
c := &CopyObjectParams{ c := &CopyObjectParams{
SrcObject: p.SrcObjInfo, SrcObject: p.SrcObjInfo,
DstBucket: p.Info.Bkt.Name, DstBktInfo: p.Info.Bkt,
DstObject: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber), DstObject: createUploadPartName(p.Info.UploadID, p.Info.Key, p.PartNumber),
SrcSize: p.SrcObjInfo.Size, SrcSize: p.SrcObjInfo.Size,
Header: metadata, Header: metadata,
Range: p.Range, Range: p.Range,
} }
return n.CopyObject(ctx, c) 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 r.prm.cid = p.Info.Bkt.CID
obj, err = n.objectPut(ctx, p.Info.Bkt, &PutObjectParams{ obj, err = n.PutObject(ctx, &PutObjectParams{
Bucket: p.Info.Bkt.Name, BktInfo: p.Info.Bkt,
Object: p.Info.Key, Object: p.Info.Key,
Reader: r, Reader: r,
Header: initMetadata, Header: initMetadata,
}) })
if err != nil { if err != nil {
n.log.Error("could not put a completed object (multipart upload)", n.log.Error("could not put a completed object (multipart upload)",

View file

@ -38,7 +38,7 @@ type (
// ListObjectsParamsCommon contains common parameters for ListObjectsV1 and ListObjectsV2. // ListObjectsParamsCommon contains common parameters for ListObjectsV1 and ListObjectsV2.
ListObjectsParamsCommon struct { ListObjectsParamsCommon struct {
Bucket string BktInfo *data.BucketInfo
Delimiter string Delimiter string
Encode string Encode string
MaxKeys int MaxKeys int
@ -153,12 +153,12 @@ func (n *layer) objectGet(ctx context.Context, addr *address.Address) (*object.O
return res.Head, nil return res.Head, nil
} }
// objectPut into NeoFS, took payload from io.Reader. // PutObject stores object into NeoFS, took payload from io.Reader.
func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjectParams) (*data.ObjectInfo, error) { func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ObjectInfo, error) {
own := n.Owner(ctx) own := n.Owner(ctx)
versioningEnabled := n.isVersioningEnabled(ctx, bkt) versioningEnabled := n.isVersioningEnabled(ctx, p.BktInfo)
versions, err := n.headVersions(ctx, bkt, p.Object) versions, err := n.headVersions(ctx, p.BktInfo, p.Object)
if err != nil && !apiErrors.IsS3Error(err, apiErrors.ErrNoSuchKey) { if err != nil && !apiErrors.IsS3Error(err, apiErrors.ErrNoSuchKey) {
return nil, err return nil, err
} }
@ -176,7 +176,7 @@ func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjec
} }
prm := neofs.PrmObjectCreate{ prm := neofs.PrmObjectCreate{
Container: *bkt.CID, Container: *p.BktInfo.CID,
Creator: *own, Creator: *own,
PayloadSize: uint64(p.Size), PayloadSize: uint64(p.Size),
Filename: p.Object, 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} objInfo := &data.ObjectInfo{ID: id, Name: p.Object}
p.Lock.Objects = append(p.Lock.Objects, *id) p.Lock.Objects = append(p.Lock.Objects, *id)
if p.Lock.LegalHold { 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 return nil, err
} }
} }
if !p.Lock.Until.IsZero() { 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 return nil, err
} }
} }
} }
meta, err := n.objectHead(ctx, bkt.CID, id) meta, err := n.objectHead(ctx, p.BktInfo.CID, id)
if err != nil { if err != nil {
return nil, err 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.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 { 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", n.log.Warn("couldn't delete object",
zap.Stringer("version id", id), zap.Stringer("version id", id),
zap.Error(err)) zap.Error(err))
} }
if !versioningEnabled { if !versioningEnabled {
if objVersion := versions.getVersion(id); objVersion != nil { 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", n.log.Warn("couldn't delete object tagging",
zap.Stringer("version id", id), zap.Stringer("version id", id),
zap.Error(err)) zap.Error(err))
@ -247,10 +247,10 @@ func (n *layer) objectPut(ctx context.Context, bkt *data.BucketInfo, p *PutObjec
return &data.ObjectInfo{ return &data.ObjectInfo{
ID: id, ID: id,
CID: bkt.CID, CID: p.BktInfo.CID,
Owner: own, Owner: own,
Bucket: p.Bucket, Bucket: p.BktInfo.Name,
Name: p.Object, Name: p.Object,
Size: p.Size, Size: p.Size,
Created: time.Now(), 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) { func (n *layer) listAllObjects(ctx context.Context, p ListObjectsParamsCommon) ([]*data.ObjectInfo, error) {
var ( var (
err error err error
bkt *data.BucketInfo
allObjects []*data.ObjectInfo allObjects []*data.ObjectInfo
) )
if bkt, err = n.GetBucketInfo(ctx, p.Bucket); err != nil {
return nil, err
}
allObjects, err = n.listSortedObjects(ctx, allObjectParams{ allObjects, err = n.listSortedObjects(ctx, allObjectParams{
Bucket: bkt, Bucket: p.BktInfo,
Prefix: p.Prefix, Prefix: p.Prefix,
Delimiter: p.Delimiter, Delimiter: p.Delimiter,
}) })

View file

@ -283,18 +283,13 @@ func (v *objectVersions) getVersion(oid *oid.ID) *data.ObjectInfo {
return nil return nil
} }
func (n *layer) PutBucketVersioning(ctx context.Context, p *PutSettingsParams) (*data.ObjectInfo, error) { 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{ metadata := map[string]string{
attrSettingsVersioningEnabled: strconv.FormatBool(p.Settings.VersioningEnabled), attrSettingsVersioningEnabled: strconv.FormatBool(p.Settings.VersioningEnabled),
} }
s := &PutSystemObjectParams{ s := &PutSystemObjectParams{
BktInfo: bktInfo, BktInfo: p.BktInfo,
ObjName: bktInfo.SettingsObjectName(), ObjName: p.BktInfo.SettingsObjectName(),
Metadata: metadata, Metadata: metadata,
Prefix: "", Prefix: "",
Reader: nil, Reader: nil,
@ -303,32 +298,22 @@ func (n *layer) PutBucketVersioning(ctx context.Context, p *PutSettingsParams) (
return n.PutSystemObject(ctx, s) return n.PutSystemObject(ctx, s)
} }
func (n *layer) GetBucketVersioning(ctx context.Context, bucketName string) (*data.BucketSettings, error) { func (n *layer) GetBucketVersioning(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) {
bktInfo, err := n.GetBucketInfo(ctx, bucketName)
if err != nil {
return nil, err
}
return n.GetBucketSettings(ctx, bktInfo) return n.GetBucketSettings(ctx, bktInfo)
} }
func (n *layer) ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error) { func (n *layer) ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error) {
var ( var (
versions map[string]*objectVersions
allObjects = make([]*data.ObjectInfo, 0, p.MaxKeys) allObjects = make([]*data.ObjectInfo, 0, p.MaxKeys)
res = &ListObjectVersionsInfo{} res = &ListObjectVersionsInfo{}
reverse = true reverse = true
) )
bkt, err := n.GetBucketInfo(ctx, p.Bucket) versions, err := n.getAllObjectsVersions(ctx, p.BktInfo, p.Prefix, p.Delimiter)
if err != nil { if err != nil {
return nil, err 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)) sortedNames := make([]string, 0, len(versions))
for k := range versions { for k := range versions {
sortedNames = append(sortedNames, k) sortedNames = append(sortedNames, k)

View file

@ -13,7 +13,6 @@ import (
"github.com/nspcc-dev/neofs-s3-gw/api/layer/neofs" "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/creds/accessbox"
"github.com/nspcc-dev/neofs-s3-gw/internal/neofstest" "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/logger"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
"github.com/nspcc-dev/neofs-sdk-go/object/address" "github.com/nspcc-dev/neofs-sdk-go/object/address"
@ -25,11 +24,11 @@ import (
func (tc *testContext) putObject(content []byte) *data.ObjectInfo { func (tc *testContext) putObject(content []byte) *data.ObjectInfo {
objInfo, err := tc.layer.PutObject(tc.ctx, &PutObjectParams{ objInfo, err := tc.layer.PutObject(tc.ctx, &PutObjectParams{
Bucket: tc.bktID.String(), BktInfo: tc.bktInfo,
Object: tc.obj, Object: tc.obj,
Size: int64(len(content)), Size: int64(len(content)),
Reader: bytes.NewReader(content), Reader: bytes.NewReader(content),
Header: make(map[string]string), Header: make(map[string]string),
}) })
require.NoError(tc.t, err) 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) { func (tc *testContext) getObject(objectName, versionID string, needError bool) (*data.ObjectInfo, []byte) {
objInfo, err := tc.layer.GetObjectInfo(tc.ctx, &HeadObjectParams{ objInfo, err := tc.layer.GetObjectInfo(tc.ctx, &HeadObjectParams{
Bucket: tc.bkt, BktInfo: tc.bktInfo,
Object: objectName, Object: objectName,
VersionID: versionID, VersionID: versionID,
}) })
@ -60,7 +59,7 @@ func (tc *testContext) getObject(objectName, versionID string, needError bool) (
} }
func (tc *testContext) deleteObject(objectName, versionID string) { 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}, {Name: objectName, VersionID: versionID},
}) })
require.NoError(tc.t, err) require.NoError(tc.t, err)
@ -72,7 +71,7 @@ func (tc *testContext) deleteObject(objectName, versionID string) {
func (tc *testContext) listObjectsV1() []*data.ObjectInfo { func (tc *testContext) listObjectsV1() []*data.ObjectInfo {
res, err := tc.layer.ListObjectsV1(tc.ctx, &ListObjectsParamsV1{ res, err := tc.layer.ListObjectsV1(tc.ctx, &ListObjectsParamsV1{
ListObjectsParamsCommon: ListObjectsParamsCommon{ ListObjectsParamsCommon: ListObjectsParamsCommon{
Bucket: tc.bkt, BktInfo: tc.bktInfo,
MaxKeys: 1000, MaxKeys: 1000,
}, },
}) })
@ -83,7 +82,7 @@ func (tc *testContext) listObjectsV1() []*data.ObjectInfo {
func (tc *testContext) listObjectsV2() []*data.ObjectInfo { func (tc *testContext) listObjectsV2() []*data.ObjectInfo {
res, err := tc.layer.ListObjectsV2(tc.ctx, &ListObjectsParamsV2{ res, err := tc.layer.ListObjectsV2(tc.ctx, &ListObjectsParamsV2{
ListObjectsParamsCommon: ListObjectsParamsCommon{ ListObjectsParamsCommon: ListObjectsParamsCommon{
Bucket: tc.bkt, BktInfo: tc.bktInfo,
MaxKeys: 1000, MaxKeys: 1000,
}, },
}) })
@ -93,7 +92,7 @@ func (tc *testContext) listObjectsV2() []*data.ObjectInfo {
func (tc *testContext) listVersions() *ListObjectVersionsInfo { func (tc *testContext) listVersions() *ListObjectVersionsInfo {
res, err := tc.layer.ListObjectVersions(tc.ctx, &ListObjectVersionsParams{ res, err := tc.layer.ListObjectVersions(tc.ctx, &ListObjectVersionsParams{
Bucket: tc.bkt, BktInfo: tc.bktInfo,
MaxKeys: 1000, MaxKeys: 1000,
}) })
require.NoError(tc.t, err) require.NoError(tc.t, err)
@ -129,8 +128,6 @@ type testContext struct {
t *testing.T t *testing.T
ctx context.Context ctx context.Context
layer Client layer Client
bkt string
bktID *cid.ID
bktInfo *data.BucketInfo bktInfo *data.BucketInfo
obj string obj string
testNeoFS *neofstest.TestNeoFS testNeoFS *neofstest.TestNeoFS
@ -172,12 +169,10 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
return &testContext{ return &testContext{
ctx: ctx, ctx: ctx,
layer: NewLayer(l, tp, layerCfg), layer: NewLayer(l, tp, layerCfg),
bkt: bktName,
bktID: bktID,
bktInfo: &data.BucketInfo{ bktInfo: &data.BucketInfo{
Name: bktName, Name: bktName,
CID: bktID,
Owner: owner.NewID(), Owner: owner.NewID(),
CID: bktID,
}, },
obj: "obj1", obj: "obj1",
t: t, t: t,
@ -632,12 +627,7 @@ func TestSystemObjectsVersioning(t *testing.T) {
// simulate failed deletion // simulate failed deletion
tc.testNeoFS.AddObject(addr.String(), objMeta) tc.testNeoFS.AddObject(addr.String(), objMeta)
bktInfo := &data.BucketInfo{ versioning, err := tc.layer.GetBucketSettings(tc.ctx, tc.bktInfo)
Name: tc.bkt,
CID: tc.bktID,
}
versioning, err := tc.layer.GetBucketSettings(tc.ctx, bktInfo)
require.NoError(t, err) require.NoError(t, err)
require.True(t, versioning.VersioningEnabled) require.True(t, versioning.VersioningEnabled)
} }
@ -652,19 +642,19 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
"tag1": "val1", "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) require.NoError(t, err)
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktID.String())) objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktInfo.CID.String()))
tagSet["tag2"] = "val2" 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) require.NoError(t, err)
// simulate failed deletion // simulate failed deletion
tc.testNeoFS.AddObject(newAddress(objMeta.ContainerID(), objMeta.ID()).String(), objMeta) 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) require.NoError(t, err)
expectedTagSet := map[string]string{ expectedTagSet := map[string]string{
@ -673,8 +663,8 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
} }
require.Equal(t, expectedTagSet, tagging) 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.NoError(t, err)
require.Nil(t, tc.getSystemObject(formBucketTagObjectName(tc.bkt))) require.Nil(t, tc.getSystemObject(formBucketTagObjectName(tc.bktInfo.Name)))
} }