forked from TrueCloudLab/frostfs-s3-gw
[#377] Reuse BucketInfo in layer
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
46e4b28489
commit
f0914b8a43
23 changed files with 341 additions and 521 deletions
|
@ -127,19 +127,21 @@ type astOperation struct {
|
||||||
func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
|
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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)",
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue