[#488] Renamed api/errors, layer/frostfs and layer/tree package names

Signed-off-by: Nikita Zinkevich <n.zinkevich@yadro.com>
This commit is contained in:
Nikita Zinkevich 2024-09-27 12:18:41 +03:00
parent 827ea1a41e
commit 9fadfbbc2f
37 changed files with 359 additions and 358 deletions

View file

@ -14,7 +14,7 @@ import (
"time" "time"
v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4" v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
@ -94,12 +94,12 @@ func New(creds tokens.Credentials, prefixes []string) *Center {
func (c *Center) parseAuthHeader(header string) (*AuthHeader, error) { func (c *Center) parseAuthHeader(header string) (*AuthHeader, error) {
submatches := c.reg.GetSubmatches(header) submatches := c.reg.GetSubmatches(header)
if len(submatches) != authHeaderPartsNum { if len(submatches) != authHeaderPartsNum {
return nil, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrAuthorizationHeaderMalformed), header) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrAuthorizationHeaderMalformed), header)
} }
accessKey := strings.Split(submatches["access_key_id"], "0") accessKey := strings.Split(submatches["access_key_id"], "0")
if len(accessKey) != accessKeyPartsNum { if len(accessKey) != accessKeyPartsNum {
return nil, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrInvalidAccessKeyID), accessKey) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrInvalidAccessKeyID), accessKey)
} }
signedFields := strings.Split(submatches["signed_header_fields"], ";") signedFields := strings.Split(submatches["signed_header_fields"], ";")
@ -117,7 +117,7 @@ func (c *Center) parseAuthHeader(header string) (*AuthHeader, error) {
func getAddress(accessKeyID string) (oid.Address, error) { func getAddress(accessKeyID string) (oid.Address, error) {
var addr oid.Address var addr oid.Address
if err := addr.DecodeString(strings.ReplaceAll(accessKeyID, "0", "/")); err != nil { if err := addr.DecodeString(strings.ReplaceAll(accessKeyID, "0", "/")); err != nil {
return addr, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrInvalidAccessKeyID), accessKeyID) return addr, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrInvalidAccessKeyID), accessKeyID)
} }
return addr, nil return addr, nil
@ -220,11 +220,11 @@ func checkFormatHashContentSHA256(hash string) error {
if !IsStandardContentSHA256(hash) { if !IsStandardContentSHA256(hash) {
hashBinary, err := hex.DecodeString(hash) hashBinary, err := hex.DecodeString(hash)
if err != nil { if err != nil {
return fmt.Errorf("%w: decode hash: %s: %s", apiErrors.GetAPIError(apiErrors.ErrContentSHA256Mismatch), return fmt.Errorf("%w: decode hash: %s: %s", apierr.GetAPIError(apierr.ErrContentSHA256Mismatch),
hash, err.Error()) hash, err.Error())
} }
if len(hashBinary) != sha256.Size && len(hash) != 0 { if len(hashBinary) != sha256.Size && len(hash) != 0 {
return fmt.Errorf("%w: invalid hash size %d", apiErrors.GetAPIError(apiErrors.ErrContentSHA256Mismatch), len(hashBinary)) return fmt.Errorf("%w: invalid hash size %d", apierr.GetAPIError(apierr.ErrContentSHA256Mismatch), len(hashBinary))
} }
} }
@ -242,12 +242,12 @@ func (c Center) checkAccessKeyID(accessKeyID string) error {
} }
} }
return fmt.Errorf("%w: accesskeyID prefix isn't allowed", apiErrors.GetAPIError(apiErrors.ErrAccessDenied)) return fmt.Errorf("%w: accesskeyID prefix isn't allowed", apierr.GetAPIError(apierr.ErrAccessDenied))
} }
func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) { func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
if err := r.ParseMultipartForm(maxFormSizeMemory); err != nil { if err := r.ParseMultipartForm(maxFormSizeMemory); err != nil {
return nil, fmt.Errorf("%w: parse multipart form with max size %d", apiErrors.GetAPIError(apiErrors.ErrInvalidArgument), maxFormSizeMemory) return nil, fmt.Errorf("%w: parse multipart form with max size %d", apierr.GetAPIError(apierr.ErrInvalidArgument), maxFormSizeMemory)
} }
if err := prepareForm(r.MultipartForm); err != nil { if err := prepareForm(r.MultipartForm); err != nil {
@ -262,7 +262,7 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
creds := MultipartFormValue(r, "x-amz-credential") creds := MultipartFormValue(r, "x-amz-credential")
submatches := c.postReg.GetSubmatches(creds) submatches := c.postReg.GetSubmatches(creds)
if len(submatches) != 4 { if len(submatches) != 4 {
return nil, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrAuthorizationHeaderMalformed), creds) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrAuthorizationHeaderMalformed), creds)
} }
signatureDateTime, err := time.Parse("20060102T150405Z", MultipartFormValue(r, "x-amz-date")) signatureDateTime, err := time.Parse("20060102T150405Z", MultipartFormValue(r, "x-amz-date"))
@ -288,7 +288,7 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
signature := SignStr(secret, service, region, signatureDateTime, policy) signature := SignStr(secret, service, region, signatureDateTime, policy)
reqSignature := MultipartFormValue(r, "x-amz-signature") reqSignature := MultipartFormValue(r, "x-amz-signature")
if signature != reqSignature { if signature != reqSignature {
return nil, fmt.Errorf("%w: %s != %s", apiErrors.GetAPIError(apiErrors.ErrSignatureDoesNotMatch), return nil, fmt.Errorf("%w: %s != %s", apierr.GetAPIError(apierr.ErrSignatureDoesNotMatch),
reqSignature, signature) reqSignature, signature)
} }
@ -333,11 +333,11 @@ func (c *Center) checkSign(authHeader *AuthHeader, box *accessbox.Box, request *
if authHeader.IsPresigned { if authHeader.IsPresigned {
now := time.Now() now := time.Now()
if signatureDateTime.Add(authHeader.Expiration).Before(now) { if signatureDateTime.Add(authHeader.Expiration).Before(now) {
return fmt.Errorf("%w: expired: now %s, signature %s", apiErrors.GetAPIError(apiErrors.ErrExpiredPresignRequest), return fmt.Errorf("%w: expired: now %s, signature %s", apierr.GetAPIError(apierr.ErrExpiredPresignRequest),
now.Format(time.RFC3339), signatureDateTime.Format(time.RFC3339)) now.Format(time.RFC3339), signatureDateTime.Format(time.RFC3339))
} }
if now.Before(signatureDateTime) { if now.Before(signatureDateTime) {
return fmt.Errorf("%w: signature time from the future: now %s, signature %s", apiErrors.GetAPIError(apiErrors.ErrBadRequest), return fmt.Errorf("%w: signature time from the future: now %s, signature %s", apierr.GetAPIError(apierr.ErrBadRequest),
now.Format(time.RFC3339), signatureDateTime.Format(time.RFC3339)) now.Format(time.RFC3339), signatureDateTime.Format(time.RFC3339))
} }
if _, err := signer.Presign(request, nil, authHeader.Service, authHeader.Region, authHeader.Expiration, signatureDateTime); err != nil { if _, err := signer.Presign(request, nil, authHeader.Service, authHeader.Region, authHeader.Expiration, signatureDateTime); err != nil {
@ -352,7 +352,7 @@ func (c *Center) checkSign(authHeader *AuthHeader, box *accessbox.Box, request *
} }
if authHeader.SignatureV4 != signature { if authHeader.SignatureV4 != signature {
return fmt.Errorf("%w: %s != %s: headers %v", apiErrors.GetAPIError(apiErrors.ErrSignatureDoesNotMatch), return fmt.Errorf("%w: %s != %s: headers %v", apierr.GetAPIError(apierr.ErrSignatureDoesNotMatch),
authHeader.SignatureV4, signature, authHeader.SignedFields) authHeader.SignatureV4, signature, authHeader.SignedFields)
} }

View file

@ -17,7 +17,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
@ -419,7 +419,7 @@ func TestAuthenticate(t *testing.T) {
if tc.err { if tc.err {
require.Error(t, err) require.Error(t, err)
if tc.errCode > 0 { if tc.errCode > 0 {
err = frostfsErrors.UnwrapErr(err) err = frosterr.UnwrapErr(err)
require.Equal(t, errors.GetAPIError(tc.errCode), err) require.Equal(t, errors.GetAPIError(tc.errCode), err)
} }
} else { } else {
@ -596,7 +596,7 @@ func TestHTTPPostAuthenticate(t *testing.T) {
if tc.err { if tc.err {
require.Error(t, err) require.Error(t, err)
if tc.errCode > 0 { if tc.errCode > 0 {
err = frostfsErrors.UnwrapErr(err) err = frosterr.UnwrapErr(err)
require.Equal(t, errors.GetAPIError(tc.errCode), err) require.Equal(t, errors.GetAPIError(tc.errCode), err)
} }
} else { } else {

View file

@ -11,7 +11,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
@ -28,12 +28,12 @@ func TestPutObjectACLErrorAPE(t *testing.T) {
info := createBucket(hc, bktName) info := createBucket(hc, bktName)
putObjectWithHeadersAssertS3Error(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPublic}, s3errors.ErrAccessControlListNotSupported) putObjectWithHeadersAssertS3Error(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPublic}, apierr.ErrAccessControlListNotSupported)
putObjectWithHeaders(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPrivate}) // only `private` canned acl is allowed, that is actually ignored putObjectWithHeaders(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPrivate}) // only `private` canned acl is allowed, that is actually ignored
putObjectWithHeaders(hc, bktName, objName, nil) putObjectWithHeaders(hc, bktName, objName, nil)
aclBody := &AccessControlPolicy{} aclBody := &AccessControlPolicy{}
putObjectACLAssertS3Error(hc, bktName, objName, info.Box, nil, aclBody, s3errors.ErrAccessControlListNotSupported) putObjectACLAssertS3Error(hc, bktName, objName, info.Box, nil, aclBody, apierr.ErrAccessControlListNotSupported)
aclRes := getObjectACL(hc, bktName, objName) aclRes := getObjectACL(hc, bktName, objName)
checkPrivateACL(t, aclRes, info.Key.PublicKey()) checkPrivateACL(t, aclRes, info.Key.PublicKey())
@ -49,7 +49,7 @@ func TestCreateObjectACLErrorAPE(t *testing.T) {
copyObject(hc, bktName, objName, objNameCopy, CopyMeta{Headers: map[string]string{api.AmzACL: basicACLPublic}}, http.StatusBadRequest) copyObject(hc, bktName, objName, objNameCopy, CopyMeta{Headers: map[string]string{api.AmzACL: basicACLPublic}}, http.StatusBadRequest)
copyObject(hc, bktName, objName, objNameCopy, CopyMeta{Headers: map[string]string{api.AmzACL: basicACLPrivate}}, http.StatusOK) copyObject(hc, bktName, objName, objNameCopy, CopyMeta{Headers: map[string]string{api.AmzACL: basicACLPrivate}}, http.StatusOK)
createMultipartUploadAssertS3Error(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPublic}, s3errors.ErrAccessControlListNotSupported) createMultipartUploadAssertS3Error(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPublic}, apierr.ErrAccessControlListNotSupported)
createMultipartUpload(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPrivate}) createMultipartUpload(hc, bktName, objName, map[string]string{api.AmzACL: basicACLPrivate})
} }
@ -60,7 +60,7 @@ func TestBucketACLAPE(t *testing.T) {
info := createBucket(hc, bktName) info := createBucket(hc, bktName)
aclBody := &AccessControlPolicy{} aclBody := &AccessControlPolicy{}
putBucketACLAssertS3Error(hc, bktName, info.Box, nil, aclBody, s3errors.ErrAccessControlListNotSupported) putBucketACLAssertS3Error(hc, bktName, info.Box, nil, aclBody, apierr.ErrAccessControlListNotSupported)
aclRes := getBucketACL(hc, bktName) aclRes := getBucketACL(hc, bktName)
checkPrivateACL(t, aclRes, info.Key.PublicKey()) checkPrivateACL(t, aclRes, info.Key.PublicKey())
@ -113,7 +113,7 @@ func TestBucketPolicy(t *testing.T) {
createTestBucket(hc, bktName) createTestBucket(hc, bktName)
getBucketPolicy(hc, bktName, s3errors.ErrNoSuchBucketPolicy) getBucketPolicy(hc, bktName, apierr.ErrNoSuchBucketPolicy)
newPolicy := engineiam.Policy{ newPolicy := engineiam.Policy{
Version: "2012-10-17", Version: "2012-10-17",
@ -125,7 +125,7 @@ func TestBucketPolicy(t *testing.T) {
}}, }},
} }
putBucketPolicy(hc, bktName, newPolicy, s3errors.ErrMalformedPolicy) putBucketPolicy(hc, bktName, newPolicy, apierr.ErrMalformedPolicy)
newPolicy.Statement[0].Resource[0] = arnAwsPrefix + bktName + "/*" newPolicy.Statement[0].Resource[0] = arnAwsPrefix + bktName + "/*"
putBucketPolicy(hc, bktName, newPolicy) putBucketPolicy(hc, bktName, newPolicy)
@ -140,7 +140,7 @@ func TestBucketPolicyStatus(t *testing.T) {
createTestBucket(hc, bktName) createTestBucket(hc, bktName)
getBucketPolicy(hc, bktName, s3errors.ErrNoSuchBucketPolicy) getBucketPolicy(hc, bktName, apierr.ErrNoSuchBucketPolicy)
newPolicy := engineiam.Policy{ newPolicy := engineiam.Policy{
Version: "2012-10-17", Version: "2012-10-17",
@ -152,7 +152,7 @@ func TestBucketPolicyStatus(t *testing.T) {
}}, }},
} }
putBucketPolicy(hc, bktName, newPolicy, s3errors.ErrMalformedPolicyNotPrincipal) putBucketPolicy(hc, bktName, newPolicy, apierr.ErrMalformedPolicyNotPrincipal)
newPolicy.Statement[0].NotPrincipal = nil newPolicy.Statement[0].NotPrincipal = nil
newPolicy.Statement[0].Principal = map[engineiam.PrincipalType][]string{engineiam.Wildcard: {}} newPolicy.Statement[0].Principal = map[engineiam.PrincipalType][]string{engineiam.Wildcard: {}}
@ -221,7 +221,7 @@ func TestPutBucketPolicy(t *testing.T) {
assertStatus(hc.t, w, http.StatusOK) assertStatus(hc.t, w, http.StatusOK)
} }
func getBucketPolicy(hc *handlerContext, bktName string, errCode ...s3errors.ErrorCode) engineiam.Policy { func getBucketPolicy(hc *handlerContext, bktName string, errCode ...apierr.ErrorCode) engineiam.Policy {
w, r := prepareTestRequest(hc, bktName, "", nil) w, r := prepareTestRequest(hc, bktName, "", nil)
hc.Handler().GetBucketPolicyHandler(w, r) hc.Handler().GetBucketPolicyHandler(w, r)
@ -231,13 +231,13 @@ func getBucketPolicy(hc *handlerContext, bktName string, errCode ...s3errors.Err
err := json.NewDecoder(w.Result().Body).Decode(&policy) err := json.NewDecoder(w.Result().Body).Decode(&policy)
require.NoError(hc.t, err) require.NoError(hc.t, err)
} else { } else {
assertS3Error(hc.t, w, s3errors.GetAPIError(errCode[0])) assertS3Error(hc.t, w, apierr.GetAPIError(errCode[0]))
} }
return policy return policy
} }
func getBucketPolicyStatus(hc *handlerContext, bktName string, errCode ...s3errors.ErrorCode) PolicyStatus { func getBucketPolicyStatus(hc *handlerContext, bktName string, errCode ...apierr.ErrorCode) PolicyStatus {
w, r := prepareTestRequest(hc, bktName, "", nil) w, r := prepareTestRequest(hc, bktName, "", nil)
hc.Handler().GetBucketPolicyStatusHandler(w, r) hc.Handler().GetBucketPolicyStatusHandler(w, r)
@ -247,13 +247,13 @@ func getBucketPolicyStatus(hc *handlerContext, bktName string, errCode ...s3erro
err := xml.NewDecoder(w.Result().Body).Decode(&policyStatus) err := xml.NewDecoder(w.Result().Body).Decode(&policyStatus)
require.NoError(hc.t, err) require.NoError(hc.t, err)
} else { } else {
assertS3Error(hc.t, w, s3errors.GetAPIError(errCode[0])) assertS3Error(hc.t, w, apierr.GetAPIError(errCode[0]))
} }
return policyStatus return policyStatus
} }
func putBucketPolicy(hc *handlerContext, bktName string, bktPolicy engineiam.Policy, errCode ...s3errors.ErrorCode) { func putBucketPolicy(hc *handlerContext, bktName string, bktPolicy engineiam.Policy, errCode ...apierr.ErrorCode) {
body, err := json.Marshal(bktPolicy) body, err := json.Marshal(bktPolicy)
require.NoError(hc.t, err) require.NoError(hc.t, err)
@ -263,7 +263,7 @@ func putBucketPolicy(hc *handlerContext, bktName string, bktPolicy engineiam.Pol
if len(errCode) == 0 { if len(errCode) == 0 {
assertStatus(hc.t, w, http.StatusOK) assertStatus(hc.t, w, http.StatusOK)
} else { } else {
assertS3Error(hc.t, w, s3errors.GetAPIError(errCode[0])) assertS3Error(hc.t, w, apierr.GetAPIError(errCode[0]))
} }
} }
@ -312,9 +312,9 @@ func createBucket(hc *handlerContext, bktName string) *createBucketInfo {
} }
} }
func createBucketAssertS3Error(hc *handlerContext, bktName string, box *accessbox.Box, code s3errors.ErrorCode) { func createBucketAssertS3Error(hc *handlerContext, bktName string, box *accessbox.Box, code apierr.ErrorCode) {
w := createBucketBase(hc, bktName, box) w := createBucketBase(hc, bktName, box)
assertS3Error(hc.t, w, s3errors.GetAPIError(code)) assertS3Error(hc.t, w, apierr.GetAPIError(code))
} }
func createBucketBase(hc *handlerContext, bktName string, box *accessbox.Box) *httptest.ResponseRecorder { func createBucketBase(hc *handlerContext, bktName string, box *accessbox.Box) *httptest.ResponseRecorder {
@ -330,9 +330,9 @@ func putBucketACL(hc *handlerContext, bktName string, box *accessbox.Box, header
assertStatus(hc.t, w, http.StatusOK) assertStatus(hc.t, w, http.StatusOK)
} }
func putBucketACLAssertS3Error(hc *handlerContext, bktName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy, code s3errors.ErrorCode) { func putBucketACLAssertS3Error(hc *handlerContext, bktName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy, code apierr.ErrorCode) {
w := putBucketACLBase(hc, bktName, box, header, body) w := putBucketACLBase(hc, bktName, box, header, body)
assertS3Error(hc.t, w, s3errors.GetAPIError(code)) assertS3Error(hc.t, w, apierr.GetAPIError(code))
} }
func putBucketACLBase(hc *handlerContext, bktName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy) *httptest.ResponseRecorder { func putBucketACLBase(hc *handlerContext, bktName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy) *httptest.ResponseRecorder {
@ -360,9 +360,9 @@ func getBucketACLBase(hc *handlerContext, bktName string) *httptest.ResponseReco
return w return w
} }
func putObjectACLAssertS3Error(hc *handlerContext, bktName, objName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy, code s3errors.ErrorCode) { func putObjectACLAssertS3Error(hc *handlerContext, bktName, objName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy, code apierr.ErrorCode) {
w := putObjectACLBase(hc, bktName, objName, box, header, body) w := putObjectACLBase(hc, bktName, objName, box, header, body)
assertS3Error(hc.t, w, s3errors.GetAPIError(code)) assertS3Error(hc.t, w, apierr.GetAPIError(code))
} }
func putObjectACLBase(hc *handlerContext, bktName, objName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy) *httptest.ResponseRecorder { func putObjectACLBase(hc *handlerContext, bktName, objName string, box *accessbox.Box, header map[string]string, body *AccessControlPolicy) *httptest.ResponseRecorder {
@ -396,9 +396,9 @@ func putObjectWithHeaders(hc *handlerContext, bktName, objName string, headers m
return w.Header() return w.Header()
} }
func putObjectWithHeadersAssertS3Error(hc *handlerContext, bktName, objName string, headers map[string]string, code s3errors.ErrorCode) { func putObjectWithHeadersAssertS3Error(hc *handlerContext, bktName, objName string, headers map[string]string, code apierr.ErrorCode) {
w := putObjectWithHeadersBase(hc, bktName, objName, headers, nil, nil) w := putObjectWithHeadersBase(hc, bktName, objName, headers, nil, nil)
assertS3Error(hc.t, w, s3errors.GetAPIError(code)) assertS3Error(hc.t, w, apierr.GetAPIError(code))
} }
func putObjectWithHeadersBase(hc *handlerContext, bktName, objName string, headers map[string]string, box *accessbox.Box, data []byte) *httptest.ResponseRecorder { func putObjectWithHeadersBase(hc *handlerContext, bktName, objName string, headers map[string]string, box *accessbox.Box, data []byte) *httptest.ResponseRecorder {

View file

@ -10,7 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
@ -131,7 +131,7 @@ func TestDeleteObjectsError(t *testing.T) {
addr.SetContainer(bktInfo.CID) addr.SetContainer(bktInfo.CID)
addr.SetObject(nodeVersion.OID) addr.SetObject(nodeVersion.OID)
expectedError := apiErrors.GetAPIError(apiErrors.ErrAccessDenied) expectedError := apierr.GetAPIError(apierr.ErrAccessDenied)
hc.tp.SetObjectError(addr, expectedError) hc.tp.SetObjectError(addr, expectedError)
w := deleteObjectsBase(hc, bktName, [][2]string{{objName, nodeVersion.OID.EncodeToString()}}) w := deleteObjectsBase(hc, bktName, [][2]string{{objName, nodeVersion.OID.EncodeToString()}})
@ -553,9 +553,9 @@ func checkNotFound(t *testing.T, hc *handlerContext, bktName, objName, version s
assertStatus(t, w, http.StatusNotFound) assertStatus(t, w, http.StatusNotFound)
} }
func headObjectAssertS3Error(hc *handlerContext, bktName, objName, version string, code apiErrors.ErrorCode) { func headObjectAssertS3Error(hc *handlerContext, bktName, objName, version string, code apierr.ErrorCode) {
w := headObjectBase(hc, bktName, objName, version) w := headObjectBase(hc, bktName, objName, version)
assertS3Error(hc.t, w, apiErrors.GetAPIError(code)) assertS3Error(hc.t, w, apierr.GetAPIError(code))
} }
func checkFound(t *testing.T, hc *handlerContext, bktName, objName, version string) { func checkFound(t *testing.T, hc *handlerContext, bktName, objName, version string) {

View file

@ -2,7 +2,7 @@ package handler
import ( import (
"bytes" "bytes"
stderrors "errors" "errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@ -13,7 +13,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -89,7 +89,7 @@ func TestPreconditions(t *testing.T) {
name: "IfMatch false", name: "IfMatch false",
info: newInfo(etag, today), info: newInfo(etag, today),
args: &conditionalArgs{IfMatch: etag2}, args: &conditionalArgs{IfMatch: etag2},
expected: errors.GetAPIError(errors.ErrPreconditionFailed)}, expected: apierr.GetAPIError(apierr.ErrPreconditionFailed)},
{ {
name: "IfNoneMatch true", name: "IfNoneMatch true",
info: newInfo(etag, today), info: newInfo(etag, today),
@ -99,7 +99,7 @@ func TestPreconditions(t *testing.T) {
name: "IfNoneMatch false", name: "IfNoneMatch false",
info: newInfo(etag, today), info: newInfo(etag, today),
args: &conditionalArgs{IfNoneMatch: etag}, args: &conditionalArgs{IfNoneMatch: etag},
expected: errors.GetAPIError(errors.ErrNotModified)}, expected: apierr.GetAPIError(apierr.ErrNotModified)},
{ {
name: "IfModifiedSince true", name: "IfModifiedSince true",
info: newInfo(etag, today), info: newInfo(etag, today),
@ -109,7 +109,7 @@ func TestPreconditions(t *testing.T) {
name: "IfModifiedSince false", name: "IfModifiedSince false",
info: newInfo(etag, yesterday), info: newInfo(etag, yesterday),
args: &conditionalArgs{IfModifiedSince: &today}, args: &conditionalArgs{IfModifiedSince: &today},
expected: errors.GetAPIError(errors.ErrNotModified)}, expected: apierr.GetAPIError(apierr.ErrNotModified)},
{ {
name: "IfUnmodifiedSince true", name: "IfUnmodifiedSince true",
info: newInfo(etag, yesterday), info: newInfo(etag, yesterday),
@ -119,7 +119,7 @@ func TestPreconditions(t *testing.T) {
name: "IfUnmodifiedSince false", name: "IfUnmodifiedSince false",
info: newInfo(etag, today), info: newInfo(etag, today),
args: &conditionalArgs{IfUnmodifiedSince: &yesterday}, args: &conditionalArgs{IfUnmodifiedSince: &yesterday},
expected: errors.GetAPIError(errors.ErrPreconditionFailed)}, expected: apierr.GetAPIError(apierr.ErrPreconditionFailed)},
{ {
name: "IfMatch true, IfUnmodifiedSince false", name: "IfMatch true, IfUnmodifiedSince false",
@ -131,19 +131,19 @@ func TestPreconditions(t *testing.T) {
name: "IfMatch false, IfUnmodifiedSince true", name: "IfMatch false, IfUnmodifiedSince true",
info: newInfo(etag, yesterday), info: newInfo(etag, yesterday),
args: &conditionalArgs{IfMatch: etag2, IfUnmodifiedSince: &today}, args: &conditionalArgs{IfMatch: etag2, IfUnmodifiedSince: &today},
expected: errors.GetAPIError(errors.ErrPreconditionFailed), expected: apierr.GetAPIError(apierr.ErrPreconditionFailed),
}, },
{ {
name: "IfNoneMatch false, IfModifiedSince true", name: "IfNoneMatch false, IfModifiedSince true",
info: newInfo(etag, today), info: newInfo(etag, today),
args: &conditionalArgs{IfNoneMatch: etag, IfModifiedSince: &yesterday}, args: &conditionalArgs{IfNoneMatch: etag, IfModifiedSince: &yesterday},
expected: errors.GetAPIError(errors.ErrNotModified), expected: apierr.GetAPIError(apierr.ErrNotModified),
}, },
{ {
name: "IfNoneMatch true, IfModifiedSince false", name: "IfNoneMatch true, IfModifiedSince false",
info: newInfo(etag, yesterday), info: newInfo(etag, yesterday),
args: &conditionalArgs{IfNoneMatch: etag2, IfModifiedSince: &today}, args: &conditionalArgs{IfNoneMatch: etag2, IfModifiedSince: &today},
expected: errors.GetAPIError(errors.ErrNotModified), expected: apierr.GetAPIError(apierr.ErrNotModified),
}, },
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
@ -151,7 +151,7 @@ func TestPreconditions(t *testing.T) {
if tc.expected == nil { if tc.expected == nil {
require.NoError(t, actual) require.NoError(t, actual)
} else { } else {
require.True(t, stderrors.Is(actual, tc.expected), tc.expected, actual) require.True(t, errors.Is(actual, tc.expected), tc.expected, actual)
} }
}) })
} }
@ -193,8 +193,8 @@ func TestGetObject(t *testing.T) {
hc.tp.SetObjectError(addr, &apistatus.ObjectNotFound{}) hc.tp.SetObjectError(addr, &apistatus.ObjectNotFound{})
hc.tp.SetObjectError(objInfo.Address(), &apistatus.ObjectNotFound{}) hc.tp.SetObjectError(objInfo.Address(), &apistatus.ObjectNotFound{})
getObjectAssertS3Error(hc, bktName, objName, objInfo.VersionID(), errors.ErrNoSuchVersion) getObjectAssertS3Error(hc, bktName, objName, objInfo.VersionID(), apierr.ErrNoSuchVersion)
getObjectAssertS3Error(hc, bktName, objName, emptyVersion, errors.ErrNoSuchKey) getObjectAssertS3Error(hc, bktName, objName, emptyVersion, apierr.ErrNoSuchKey)
} }
func TestGetObjectEnabledMD5(t *testing.T) { func TestGetObjectEnabledMD5(t *testing.T) {
@ -236,9 +236,9 @@ func getObjectVersion(tc *handlerContext, bktName, objName, version string) []by
return content return content
} }
func getObjectAssertS3Error(hc *handlerContext, bktName, objName, version string, code errors.ErrorCode) { func getObjectAssertS3Error(hc *handlerContext, bktName, objName, version string, code apierr.ErrorCode) {
w := getObjectBaseResponse(hc, bktName, objName, version) w := getObjectBaseResponse(hc, bktName, objName, version)
assertS3Error(hc.t, w, errors.GetAPIError(code)) assertS3Error(hc.t, w, apierr.GetAPIError(code))
} }
func getObjectBaseResponse(hc *handlerContext, bktName, objName, version string) *httptest.ResponseRecorder { func getObjectBaseResponse(hc *handlerContext, bktName, objName, version string) *httptest.ResponseRecorder {

View file

@ -6,7 +6,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
@ -95,8 +95,8 @@ func TestHeadObject(t *testing.T) {
hc.tp.SetObjectError(addr, &apistatus.ObjectNotFound{}) hc.tp.SetObjectError(addr, &apistatus.ObjectNotFound{})
hc.tp.SetObjectError(objInfo.Address(), &apistatus.ObjectNotFound{}) hc.tp.SetObjectError(objInfo.Address(), &apistatus.ObjectNotFound{})
headObjectAssertS3Error(hc, bktName, objName, objInfo.VersionID(), s3errors.ErrNoSuchVersion) headObjectAssertS3Error(hc, bktName, objName, objInfo.VersionID(), apierr.ErrNoSuchVersion)
headObjectAssertS3Error(hc, bktName, objName, emptyVersion, s3errors.ErrNoSuchKey) headObjectAssertS3Error(hc, bktName, objName, emptyVersion, apierr.ErrNoSuchKey)
} }
func TestIsAvailableToResolve(t *testing.T) { func TestIsAvailableToResolve(t *testing.T) {

View file

@ -9,7 +9,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
) )
@ -52,7 +52,7 @@ func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque
// Content-Md5 is required and should be set // Content-Md5 is required and should be set
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html // https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html
if _, ok := r.Header[api.ContentMD5]; !ok { if _, ok := r.Header[api.ContentMD5]; !ok {
h.logAndSendError(w, "missing Content-MD5", reqInfo, apiErr.GetAPIError(apiErr.ErrMissingContentMD5)) h.logAndSendError(w, "missing Content-MD5", reqInfo, apierr.GetAPIError(apierr.ErrMissingContentMD5))
return return
} }
@ -64,12 +64,12 @@ func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque
cfg := new(data.LifecycleConfiguration) cfg := new(data.LifecycleConfiguration)
if err = h.cfg.NewXMLDecoder(tee).Decode(cfg); err != nil { if err = h.cfg.NewXMLDecoder(tee).Decode(cfg); err != nil {
h.logAndSendError(w, "could not decode body", reqInfo, fmt.Errorf("%w: %s", apiErr.GetAPIError(apiErr.ErrMalformedXML), err.Error())) h.logAndSendError(w, "could not decode body", reqInfo, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error()))
return return
} }
if err = checkLifecycleConfiguration(cfg); err != nil { if err = checkLifecycleConfiguration(cfg); err != nil {
h.logAndSendError(w, "invalid lifecycle configuration", reqInfo, fmt.Errorf("%w: %s", apiErr.GetAPIError(apiErr.ErrMalformedXML), err.Error())) h.logAndSendError(w, "invalid lifecycle configuration", reqInfo, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error()))
return return
} }

View file

@ -14,7 +14,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -340,7 +340,7 @@ func TestPutBucketLifecycleConfiguration(t *testing.T) {
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if tc.error { if tc.error {
putBucketLifecycleConfigurationErr(hc, bktName, tc.body, apiErrors.GetAPIError(apiErrors.ErrMalformedXML)) putBucketLifecycleConfigurationErr(hc, bktName, tc.body, apierr.GetAPIError(apierr.ErrMalformedXML))
return return
} }
@ -350,7 +350,7 @@ func TestPutBucketLifecycleConfiguration(t *testing.T) {
require.Equal(t, *tc.body, *cfg) require.Equal(t, *tc.body, *cfg)
deleteBucketLifecycleConfiguration(hc, bktName) deleteBucketLifecycleConfiguration(hc, bktName)
getBucketLifecycleConfigurationErr(hc, bktName, apiErrors.GetAPIError(apiErrors.ErrNoSuchLifecycleConfiguration)) getBucketLifecycleConfigurationErr(hc, bktName, apierr.GetAPIError(apierr.ErrNoSuchLifecycleConfiguration))
}) })
} }
} }
@ -374,17 +374,17 @@ func TestPutBucketLifecycleInvalidMD5(t *testing.T) {
w, r := prepareTestRequest(hc, bktName, "", lifecycle) w, r := prepareTestRequest(hc, bktName, "", lifecycle)
hc.Handler().PutBucketLifecycleHandler(w, r) hc.Handler().PutBucketLifecycleHandler(w, r)
assertS3Error(hc.t, w, apiErrors.GetAPIError(apiErrors.ErrMissingContentMD5)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrMissingContentMD5))
w, r = prepareTestRequest(hc, bktName, "", lifecycle) w, r = prepareTestRequest(hc, bktName, "", lifecycle)
r.Header.Set(api.ContentMD5, "") r.Header.Set(api.ContentMD5, "")
hc.Handler().PutBucketLifecycleHandler(w, r) hc.Handler().PutBucketLifecycleHandler(w, r)
assertS3Error(hc.t, w, apiErrors.GetAPIError(apiErrors.ErrInvalidDigest)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrInvalidDigest))
w, r = prepareTestRequest(hc, bktName, "", lifecycle) w, r = prepareTestRequest(hc, bktName, "", lifecycle)
r.Header.Set(api.ContentMD5, "some-hash") r.Header.Set(api.ContentMD5, "some-hash")
hc.Handler().PutBucketLifecycleHandler(w, r) hc.Handler().PutBucketLifecycleHandler(w, r)
assertS3Error(hc.t, w, apiErrors.GetAPIError(apiErrors.ErrInvalidDigest)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrInvalidDigest))
} }
func TestPutBucketLifecycleInvalidXML(t *testing.T) { func TestPutBucketLifecycleInvalidXML(t *testing.T) {
@ -396,7 +396,7 @@ func TestPutBucketLifecycleInvalidXML(t *testing.T) {
w, r := prepareTestRequest(hc, bktName, "", &data.CORSConfiguration{}) w, r := prepareTestRequest(hc, bktName, "", &data.CORSConfiguration{})
r.Header.Set(api.ContentMD5, "") r.Header.Set(api.ContentMD5, "")
hc.Handler().PutBucketLifecycleHandler(w, r) hc.Handler().PutBucketLifecycleHandler(w, r)
assertS3Error(hc.t, w, apiErrors.GetAPIError(apiErrors.ErrMalformedXML)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrMalformedXML))
} }
func putBucketLifecycleConfiguration(hc *handlerContext, bktName string, cfg *data.LifecycleConfiguration) { func putBucketLifecycleConfiguration(hc *handlerContext, bktName string, cfg *data.LifecycleConfiguration) {
@ -404,7 +404,7 @@ func putBucketLifecycleConfiguration(hc *handlerContext, bktName string, cfg *da
assertStatus(hc.t, w, http.StatusOK) assertStatus(hc.t, w, http.StatusOK)
} }
func putBucketLifecycleConfigurationErr(hc *handlerContext, bktName string, cfg *data.LifecycleConfiguration, err apiErrors.Error) { func putBucketLifecycleConfigurationErr(hc *handlerContext, bktName string, cfg *data.LifecycleConfiguration, err apierr.Error) {
w := putBucketLifecycleConfigurationBase(hc, bktName, cfg) w := putBucketLifecycleConfigurationBase(hc, bktName, cfg)
assertS3Error(hc.t, w, err) assertS3Error(hc.t, w, err)
} }
@ -430,7 +430,7 @@ func getBucketLifecycleConfiguration(hc *handlerContext, bktName string) *data.L
return res return res
} }
func getBucketLifecycleConfigurationErr(hc *handlerContext, bktName string, err apiErrors.Error) { func getBucketLifecycleConfigurationErr(hc *handlerContext, bktName string, err apierr.Error) {
w := getBucketLifecycleConfigurationBase(hc, bktName) w := getBucketLifecycleConfigurationBase(hc, bktName)
assertS3Error(hc.t, w, err) assertS3Error(hc.t, w, err)
} }

View file

@ -9,7 +9,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
) )
@ -36,7 +36,7 @@ func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
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,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotAllowed)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotAllowed))
return return
} }
@ -83,7 +83,7 @@ func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -116,7 +116,7 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -168,7 +168,7 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -204,7 +204,7 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -252,7 +252,7 @@ func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(w, "object lock disabled", reqInfo,
apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -269,7 +269,7 @@ func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
} }
if !lockInfo.IsRetentionSet() { if !lockInfo.IsRetentionSet() {
h.logAndSendError(w, "retention lock isn't set", reqInfo, apiErrors.GetAPIError(apiErrors.ErrNoSuchKey)) h.logAndSendError(w, "retention lock isn't set", reqInfo, apierr.GetAPIError(apierr.ErrNoSuchKey))
return return
} }
@ -314,7 +314,7 @@ func checkLockConfiguration(conf *data.ObjectLockConfiguration) error {
func formObjectLock(ctx context.Context, bktInfo *data.BucketInfo, defaultConfig *data.ObjectLockConfiguration, header http.Header) (*data.ObjectLock, error) { func formObjectLock(ctx context.Context, bktInfo *data.BucketInfo, defaultConfig *data.ObjectLockConfiguration, header http.Header) (*data.ObjectLock, error) {
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
if existLockHeaders(header) { if existLockHeaders(header) {
return nil, apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound) return nil, apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound)
} }
return nil, nil return nil, nil
} }
@ -346,7 +346,7 @@ func formObjectLock(ctx context.Context, bktInfo *data.BucketInfo, defaultConfig
until := header.Get(api.AmzObjectLockRetainUntilDate) until := header.Get(api.AmzObjectLockRetainUntilDate)
if mode != "" && until == "" || mode == "" && until != "" { if mode != "" && until == "" || mode == "" && until != "" {
return nil, apiErrors.GetAPIError(apiErrors.ErrObjectLockInvalidHeaders) return nil, apierr.GetAPIError(apierr.ErrObjectLockInvalidHeaders)
} }
if mode != "" { if mode != "" {
@ -355,7 +355,7 @@ func formObjectLock(ctx context.Context, bktInfo *data.BucketInfo, defaultConfig
} }
if mode != complianceMode && mode != governanceMode { if mode != complianceMode && mode != governanceMode {
return nil, apiErrors.GetAPIError(apiErrors.ErrUnknownWORMModeDirective) return nil, apierr.GetAPIError(apierr.ErrUnknownWORMModeDirective)
} }
objectLock.Retention.IsCompliance = mode == complianceMode objectLock.Retention.IsCompliance = mode == complianceMode
@ -364,7 +364,7 @@ func formObjectLock(ctx context.Context, bktInfo *data.BucketInfo, defaultConfig
if until != "" { if until != "" {
retentionDate, err := time.Parse(time.RFC3339, until) retentionDate, err := time.Parse(time.RFC3339, until)
if err != nil { if err != nil {
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidRetentionDate) return nil, apierr.GetAPIError(apierr.ErrInvalidRetentionDate)
} }
if objectLock.Retention == nil { if objectLock.Retention == nil {
objectLock.Retention = &data.RetentionLock{} objectLock.Retention = &data.RetentionLock{}
@ -382,7 +382,7 @@ func formObjectLock(ctx context.Context, bktInfo *data.BucketInfo, defaultConfig
} }
if objectLock.Retention.Until.Before(layer.TimeNow(ctx)) { if objectLock.Retention.Until.Before(layer.TimeNow(ctx)) {
return nil, apiErrors.GetAPIError(apiErrors.ErrPastObjectLockRetainDate) return nil, apierr.GetAPIError(apierr.ErrPastObjectLockRetainDate)
} }
} }
@ -397,16 +397,16 @@ func existLockHeaders(header http.Header) bool {
func formObjectLockFromRetention(ctx context.Context, retention *data.Retention, header http.Header) (*data.ObjectLock, error) { func formObjectLockFromRetention(ctx context.Context, retention *data.Retention, header http.Header) (*data.ObjectLock, error) {
if retention.Mode != governanceMode && retention.Mode != complianceMode { if retention.Mode != governanceMode && retention.Mode != complianceMode {
return nil, apiErrors.GetAPIError(apiErrors.ErrMalformedXML) return nil, apierr.GetAPIError(apierr.ErrMalformedXML)
} }
retentionDate, err := time.Parse(time.RFC3339, retention.RetainUntilDate) retentionDate, err := time.Parse(time.RFC3339, retention.RetainUntilDate)
if err != nil { if err != nil {
return nil, apiErrors.GetAPIError(apiErrors.ErrMalformedXML) return nil, apierr.GetAPIError(apierr.ErrMalformedXML)
} }
if retentionDate.Before(layer.TimeNow(ctx)) { if retentionDate.Before(layer.TimeNow(ctx)) {
return nil, apiErrors.GetAPIError(apiErrors.ErrPastObjectLockRetainDate) return nil, apierr.GetAPIError(apierr.ErrPastObjectLockRetainDate)
} }
var bypass bool var bypass bool

View file

@ -12,7 +12,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -270,23 +270,23 @@ func TestPutBucketLockConfigurationHandler(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
name string name string
bucket string bucket string
expectedError apiErrors.Error expectedError apierr.Error
noError bool noError bool
configuration *data.ObjectLockConfiguration configuration *data.ObjectLockConfiguration
}{ }{
{ {
name: "bkt not found", name: "bkt not found",
expectedError: apiErrors.GetAPIError(apiErrors.ErrNoSuchBucket), expectedError: apierr.GetAPIError(apierr.ErrNoSuchBucket),
}, },
{ {
name: "bkt lock disabled", name: "bkt lock disabled",
bucket: bktLockDisabled, bucket: bktLockDisabled,
expectedError: apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotAllowed), expectedError: apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotAllowed),
}, },
{ {
name: "invalid configuration", name: "invalid configuration",
bucket: bktLockEnabled, bucket: bktLockEnabled,
expectedError: apiErrors.GetAPIError(apiErrors.ErrInternalError), expectedError: apierr.GetAPIError(apierr.ErrInternalError),
configuration: &data.ObjectLockConfiguration{ObjectLockEnabled: "dummy"}, configuration: &data.ObjectLockConfiguration{ObjectLockEnabled: "dummy"},
}, },
{ {
@ -359,18 +359,18 @@ func TestGetBucketLockConfigurationHandler(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
name string name string
bucket string bucket string
expectedError apiErrors.Error expectedError apierr.Error
noError bool noError bool
expectedConf *data.ObjectLockConfiguration expectedConf *data.ObjectLockConfiguration
}{ }{
{ {
name: "bkt not found", name: "bkt not found",
expectedError: apiErrors.GetAPIError(apiErrors.ErrNoSuchBucket), expectedError: apierr.GetAPIError(apierr.ErrNoSuchBucket),
}, },
{ {
name: "bkt lock disabled", name: "bkt lock disabled",
bucket: bktLockDisabled, bucket: bktLockDisabled,
expectedError: apiErrors.GetAPIError(apiErrors.ErrObjectLockConfigurationNotFound), expectedError: apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound),
}, },
{ {
name: "bkt lock enabled empty default", name: "bkt lock enabled empty default",
@ -407,7 +407,7 @@ func TestGetBucketLockConfigurationHandler(t *testing.T) {
} }
} }
func assertS3Error(t *testing.T, w *httptest.ResponseRecorder, expectedError apiErrors.Error) { func assertS3Error(t *testing.T, w *httptest.ResponseRecorder, expectedError apierr.Error) {
actualErrorResponse := &middleware.ErrorResponse{} actualErrorResponse := &middleware.ErrorResponse{}
err := xml.NewDecoder(w.Result().Body).Decode(actualErrorResponse) err := xml.NewDecoder(w.Result().Body).Decode(actualErrorResponse)
require.NoError(t, err) require.NoError(t, err)
@ -415,7 +415,7 @@ func assertS3Error(t *testing.T, w *httptest.ResponseRecorder, expectedError api
require.Equal(t, expectedError.HTTPStatusCode, w.Code) require.Equal(t, expectedError.HTTPStatusCode, w.Code)
require.Equal(t, expectedError.Code, actualErrorResponse.Code) require.Equal(t, expectedError.Code, actualErrorResponse.Code)
if expectedError.ErrCode != apiErrors.ErrInternalError { if expectedError.ErrCode != apierr.ErrInternalError {
require.Equal(t, expectedError.Description, actualErrorResponse.Message) require.Equal(t, expectedError.Description, actualErrorResponse.Message)
} }
} }
@ -473,33 +473,33 @@ func TestObjectRetention(t *testing.T) {
objName := "obj-for-retention" objName := "obj-for-retention"
createTestObject(hc, bktInfo, objName, encryption.Params{}) createTestObject(hc, bktInfo, objName, encryption.Params{})
getObjectRetention(hc, bktName, objName, nil, apiErrors.ErrNoSuchKey) getObjectRetention(hc, bktName, objName, nil, apierr.ErrNoSuchKey)
retention := &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)} retention := &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
putObjectRetention(hc, bktName, objName, retention, false, 0) putObjectRetention(hc, bktName, objName, retention, false, 0)
getObjectRetention(hc, bktName, objName, retention, 0) getObjectRetention(hc, bktName, objName, retention, 0)
retention = &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().UTC().Add(time.Minute).Format(time.RFC3339)} retention = &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().UTC().Add(time.Minute).Format(time.RFC3339)}
putObjectRetention(hc, bktName, objName, retention, false, apiErrors.ErrInternalError) putObjectRetention(hc, bktName, objName, retention, false, apierr.ErrInternalError)
retention = &data.Retention{Mode: complianceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)} retention = &data.Retention{Mode: complianceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
putObjectRetention(hc, bktName, objName, retention, true, 0) putObjectRetention(hc, bktName, objName, retention, true, 0)
getObjectRetention(hc, bktName, objName, retention, 0) getObjectRetention(hc, bktName, objName, retention, 0)
putObjectRetention(hc, bktName, objName, retention, true, apiErrors.ErrInternalError) putObjectRetention(hc, bktName, objName, retention, true, apierr.ErrInternalError)
} }
func getObjectRetention(hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apiErrors.ErrorCode) { func getObjectRetention(hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apierr.ErrorCode) {
w, r := prepareTestRequest(hc, bktName, objName, nil) w, r := prepareTestRequest(hc, bktName, objName, nil)
hc.Handler().GetObjectRetentionHandler(w, r) hc.Handler().GetObjectRetentionHandler(w, r)
if errCode == 0 { if errCode == 0 {
assertRetention(hc.t, w, retention) assertRetention(hc.t, w, retention)
} else { } else {
assertS3Error(hc.t, w, apiErrors.GetAPIError(errCode)) assertS3Error(hc.t, w, apierr.GetAPIError(errCode))
} }
} }
func putObjectRetention(hc *handlerContext, bktName, objName string, retention *data.Retention, byPass bool, errCode apiErrors.ErrorCode) { func putObjectRetention(hc *handlerContext, bktName, objName string, retention *data.Retention, byPass bool, errCode apierr.ErrorCode) {
w, r := prepareTestRequest(hc, bktName, objName, retention) w, r := prepareTestRequest(hc, bktName, objName, retention)
if byPass { if byPass {
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true)) r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
@ -508,7 +508,7 @@ func putObjectRetention(hc *handlerContext, bktName, objName string, retention *
if errCode == 0 { if errCode == 0 {
assertStatus(hc.t, w, http.StatusOK) assertStatus(hc.t, w, http.StatusOK)
} else { } else {
assertS3Error(hc.t, w, apiErrors.GetAPIError(errCode)) assertS3Error(hc.t, w, apierr.GetAPIError(errCode))
} }
} }
@ -572,37 +572,37 @@ func TestPutLockErrors(t *testing.T) {
createTestBucketWithLock(hc, bktName, nil) createTestBucketWithLock(hc, bktName, nil)
headers := map[string]string{api.AmzObjectLockMode: complianceMode} headers := map[string]string{api.AmzObjectLockMode: complianceMode}
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrObjectLockInvalidHeaders) putObjectWithLockFailed(t, hc, bktName, objName, headers, apierr.ErrObjectLockInvalidHeaders)
delete(headers, api.AmzObjectLockMode) delete(headers, api.AmzObjectLockMode)
headers[api.AmzObjectLockRetainUntilDate] = time.Now().Add(time.Minute).Format(time.RFC3339) headers[api.AmzObjectLockRetainUntilDate] = time.Now().Add(time.Minute).Format(time.RFC3339)
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrObjectLockInvalidHeaders) putObjectWithLockFailed(t, hc, bktName, objName, headers, apierr.ErrObjectLockInvalidHeaders)
headers[api.AmzObjectLockMode] = "dummy" headers[api.AmzObjectLockMode] = "dummy"
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrUnknownWORMModeDirective) putObjectWithLockFailed(t, hc, bktName, objName, headers, apierr.ErrUnknownWORMModeDirective)
headers[api.AmzObjectLockMode] = complianceMode headers[api.AmzObjectLockMode] = complianceMode
headers[api.AmzObjectLockRetainUntilDate] = time.Now().Format(time.RFC3339) headers[api.AmzObjectLockRetainUntilDate] = time.Now().Format(time.RFC3339)
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrPastObjectLockRetainDate) putObjectWithLockFailed(t, hc, bktName, objName, headers, apierr.ErrPastObjectLockRetainDate)
headers[api.AmzObjectLockRetainUntilDate] = "dummy" headers[api.AmzObjectLockRetainUntilDate] = "dummy"
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrInvalidRetentionDate) putObjectWithLockFailed(t, hc, bktName, objName, headers, apierr.ErrInvalidRetentionDate)
putObject(hc, bktName, objName) putObject(hc, bktName, objName)
retention := &data.Retention{Mode: governanceMode} retention := &data.Retention{Mode: governanceMode}
putObjectRetentionFailed(t, hc, bktName, objName, retention, apiErrors.ErrMalformedXML) putObjectRetentionFailed(t, hc, bktName, objName, retention, apierr.ErrMalformedXML)
retention.Mode = "dummy" retention.Mode = "dummy"
retention.RetainUntilDate = time.Now().Add(time.Minute).UTC().Format(time.RFC3339) retention.RetainUntilDate = time.Now().Add(time.Minute).UTC().Format(time.RFC3339)
putObjectRetentionFailed(t, hc, bktName, objName, retention, apiErrors.ErrMalformedXML) putObjectRetentionFailed(t, hc, bktName, objName, retention, apierr.ErrMalformedXML)
retention.Mode = governanceMode retention.Mode = governanceMode
retention.RetainUntilDate = time.Now().UTC().Format(time.RFC3339) retention.RetainUntilDate = time.Now().UTC().Format(time.RFC3339)
putObjectRetentionFailed(t, hc, bktName, objName, retention, apiErrors.ErrPastObjectLockRetainDate) putObjectRetentionFailed(t, hc, bktName, objName, retention, apierr.ErrPastObjectLockRetainDate)
} }
func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName string, headers map[string]string, errCode apiErrors.ErrorCode) { func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName string, headers map[string]string, errCode apierr.ErrorCode) {
w, r := prepareTestRequest(hc, bktName, objName, nil) w, r := prepareTestRequest(hc, bktName, objName, nil)
for key, val := range headers { for key, val := range headers {
@ -610,13 +610,13 @@ func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName
} }
hc.Handler().PutObjectHandler(w, r) hc.Handler().PutObjectHandler(w, r)
assertS3Error(t, w, apiErrors.GetAPIError(errCode)) assertS3Error(t, w, apierr.GetAPIError(errCode))
} }
func putObjectRetentionFailed(t *testing.T, hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apiErrors.ErrorCode) { func putObjectRetentionFailed(t *testing.T, hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apierr.ErrorCode) {
w, r := prepareTestRequest(hc, bktName, objName, retention) w, r := prepareTestRequest(hc, bktName, objName, retention)
hc.Handler().PutObjectRetentionHandler(w, r) hc.Handler().PutObjectRetentionHandler(w, r)
assertS3Error(t, w, apiErrors.GetAPIError(errCode)) assertS3Error(t, w, apierr.GetAPIError(errCode))
} }
func assertRetentionApproximate(t *testing.T, w *httptest.ResponseRecorder, retention *data.Retention, delta float64) { func assertRetentionApproximate(t *testing.T, w *httptest.ResponseRecorder, retention *data.Retention, delta float64) {

View file

@ -15,7 +15,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3Errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
@ -40,7 +40,7 @@ func TestMultipartUploadInvalidPart(t *testing.T) {
etag1, _ := uploadPart(hc, bktName, objName, multipartUpload.UploadID, 1, partSize) etag1, _ := uploadPart(hc, bktName, objName, multipartUpload.UploadID, 1, partSize)
etag2, _ := uploadPart(hc, bktName, objName, multipartUpload.UploadID, 2, partSize) etag2, _ := uploadPart(hc, bktName, objName, multipartUpload.UploadID, 2, partSize)
w := completeMultipartUploadBase(hc, bktName, objName, multipartUpload.UploadID, []string{etag1, etag2}) w := completeMultipartUploadBase(hc, bktName, objName, multipartUpload.UploadID, []string{etag1, etag2})
assertS3Error(hc.t, w, s3Errors.GetAPIError(s3Errors.ErrEntityTooSmall)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrEntityTooSmall))
} }
func TestDeleteMultipartAllParts(t *testing.T) { func TestDeleteMultipartAllParts(t *testing.T) {
@ -104,7 +104,7 @@ func TestMultipartReUploadPart(t *testing.T) {
require.Equal(t, etag2, list.Parts[1].ETag) require.Equal(t, etag2, list.Parts[1].ETag)
w := completeMultipartUploadBase(hc, bktName, objName, uploadInfo.UploadID, []string{etag1, etag2}) w := completeMultipartUploadBase(hc, bktName, objName, uploadInfo.UploadID, []string{etag1, etag2})
assertS3Error(hc.t, w, s3Errors.GetAPIError(s3Errors.ErrEntityTooSmall)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrEntityTooSmall))
etag1, data1 := uploadPart(hc, bktName, objName, uploadInfo.UploadID, 1, partSizeFirst) etag1, data1 := uploadPart(hc, bktName, objName, uploadInfo.UploadID, 1, partSizeFirst)
etag2, data2 := uploadPart(hc, bktName, objName, uploadInfo.UploadID, 2, partSizeLast) etag2, data2 := uploadPart(hc, bktName, objName, uploadInfo.UploadID, 2, partSizeLast)
@ -521,7 +521,7 @@ func TestUploadPartCheckContentSHA256(t *testing.T) {
r.Header.Set(api.AmzContentSha256, tc.hash) r.Header.Set(api.AmzContentSha256, tc.hash)
hc.Handler().UploadPartHandler(w, r) hc.Handler().UploadPartHandler(w, r)
if tc.error { if tc.error {
assertS3Error(t, w, s3Errors.GetAPIError(s3Errors.ErrContentSHA256Mismatch)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrContentSHA256Mismatch))
list := listParts(hc, bktName, objName, multipartUpload.UploadID, "0", http.StatusOK) list := listParts(hc, bktName, objName, multipartUpload.UploadID, "0", http.StatusOK)
require.Len(t, list.Parts, 1) require.Len(t, list.Parts, 1)

View file

@ -18,7 +18,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -50,7 +50,7 @@ func TestPatch(t *testing.T) {
name string name string
rng string rng string
headers map[string]string headers map[string]string
code s3errors.ErrorCode code apierr.ErrorCode
}{ }{
{ {
name: "success", name: "success",
@ -63,22 +63,22 @@ func TestPatch(t *testing.T) {
{ {
name: "invalid range syntax", name: "invalid range syntax",
rng: "bytes 0-2", rng: "bytes 0-2",
code: s3errors.ErrInvalidRange, code: apierr.ErrInvalidRange,
}, },
{ {
name: "invalid range length", name: "invalid range length",
rng: "bytes 0-5/*", rng: "bytes 0-5/*",
code: s3errors.ErrInvalidRangeLength, code: apierr.ErrInvalidRangeLength,
}, },
{ {
name: "invalid range start", name: "invalid range start",
rng: "bytes 20-22/*", rng: "bytes 20-22/*",
code: s3errors.ErrRangeOutOfBounds, code: apierr.ErrRangeOutOfBounds,
}, },
{ {
name: "range is too long", name: "range is too long",
rng: "bytes 0-5368709120/*", rng: "bytes 0-5368709120/*",
code: s3errors.ErrInvalidRange, code: apierr.ErrInvalidRange,
}, },
{ {
name: "If-Unmodified-Since precondition are not satisfied", name: "If-Unmodified-Since precondition are not satisfied",
@ -86,7 +86,7 @@ func TestPatch(t *testing.T) {
headers: map[string]string{ headers: map[string]string{
api.IfUnmodifiedSince: created.Add(-24 * time.Hour).Format(http.TimeFormat), api.IfUnmodifiedSince: created.Add(-24 * time.Hour).Format(http.TimeFormat),
}, },
code: s3errors.ErrPreconditionFailed, code: apierr.ErrPreconditionFailed,
}, },
{ {
name: "If-Match precondition are not satisfied", name: "If-Match precondition are not satisfied",
@ -94,7 +94,7 @@ func TestPatch(t *testing.T) {
headers: map[string]string{ headers: map[string]string{
api.IfMatch: "etag", api.IfMatch: "etag",
}, },
code: s3errors.ErrPreconditionFailed, code: apierr.ErrPreconditionFailed,
}, },
} { } {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -377,7 +377,7 @@ func TestPatchEncryptedObject(t *testing.T) {
tc.Handler().PutObjectHandler(w, r) tc.Handler().PutObjectHandler(w, r)
assertStatus(t, w, http.StatusOK) assertStatus(t, w, http.StatusOK)
patchObjectErr(t, tc, bktName, objName, "bytes 2-4/*", []byte("new"), nil, s3errors.ErrInternalError) patchObjectErr(t, tc, bktName, objName, "bytes 2-4/*", []byte("new"), nil, apierr.ErrInternalError)
} }
func TestPatchMissingHeaders(t *testing.T) { func TestPatchMissingHeaders(t *testing.T) {
@ -393,13 +393,13 @@ func TestPatchMissingHeaders(t *testing.T) {
w = httptest.NewRecorder() w = httptest.NewRecorder()
r = httptest.NewRequest(http.MethodPatch, defaultURL, strings.NewReader("new")) r = httptest.NewRequest(http.MethodPatch, defaultURL, strings.NewReader("new"))
tc.Handler().PatchObjectHandler(w, r) tc.Handler().PatchObjectHandler(w, r)
assertS3Error(t, w, s3errors.GetAPIError(s3errors.ErrMissingContentRange)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrMissingContentRange))
w = httptest.NewRecorder() w = httptest.NewRecorder()
r = httptest.NewRequest(http.MethodPatch, defaultURL, strings.NewReader("new")) r = httptest.NewRequest(http.MethodPatch, defaultURL, strings.NewReader("new"))
r.Header.Set(api.ContentRange, "bytes 0-2/*") r.Header.Set(api.ContentRange, "bytes 0-2/*")
tc.Handler().PatchObjectHandler(w, r) tc.Handler().PatchObjectHandler(w, r)
assertS3Error(t, w, s3errors.GetAPIError(s3errors.ErrMissingContentLength)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrMissingContentLength))
} }
func TestParsePatchByteRange(t *testing.T) { func TestParsePatchByteRange(t *testing.T) {
@ -501,9 +501,9 @@ func patchObjectVersion(t *testing.T, tc *handlerContext, bktName, objName, vers
return result return result
} }
func patchObjectErr(t *testing.T, tc *handlerContext, bktName, objName, rng string, payload []byte, headers map[string]string, code s3errors.ErrorCode) { func patchObjectErr(t *testing.T, tc *handlerContext, bktName, objName, rng string, payload []byte, headers map[string]string, code apierr.ErrorCode) {
w := patchObjectBase(tc, bktName, objName, "", rng, payload, headers) w := patchObjectBase(tc, bktName, objName, "", rng, payload, headers)
assertS3Error(t, w, s3errors.GetAPIError(code)) assertS3Error(t, w, apierr.GetAPIError(code))
} }
func patchObjectBase(tc *handlerContext, bktName, objName, version, rng string, payload []byte, headers map[string]string) *httptest.ResponseRecorder { func patchObjectBase(tc *handlerContext, bktName, objName, version, rng string, payload []byte, headers map[string]string) *httptest.ResponseRecorder {

View file

@ -7,7 +7,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"encoding/xml" "encoding/xml"
stderrors "errors" "errors"
"fmt" "fmt"
"io" "io"
"mime/multipart" "mime/multipart"
@ -21,7 +21,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
@ -92,11 +92,11 @@ func (p *postPolicy) CheckField(key string, value string) error {
} }
cond := p.condition(key) cond := p.condition(key)
if cond == nil { if cond == nil {
return errors.GetAPIError(errors.ErrPostPolicyConditionInvalidFormat) return apierr.GetAPIError(apierr.ErrPostPolicyConditionInvalidFormat)
} }
if !cond.match(value) { if !cond.match(value) {
return errors.GetAPIError(errors.ErrPostPolicyConditionInvalidFormat) return apierr.GetAPIError(apierr.ErrPostPolicyConditionInvalidFormat)
} }
return nil return nil
@ -204,7 +204,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
if cannedACLStatus == aclStatusYes { if cannedACLStatus == aclStatusYes {
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported)) h.logAndSendError(w, "acl not supported for this bucket", reqInfo, apierr.GetAPIError(apierr.ErrAccessControlListNotSupported))
return return
} }
@ -333,16 +333,16 @@ func (h *handler) getBodyReader(r *http.Request) (io.ReadCloser, error) {
if !chunkedEncoding && !h.cfg.BypassContentEncodingInChunks() { if !chunkedEncoding && !h.cfg.BypassContentEncodingInChunks() {
return nil, fmt.Errorf("%w: request is not chunk encoded, encodings '%s'", return nil, fmt.Errorf("%w: request is not chunk encoded, encodings '%s'",
errors.GetAPIError(errors.ErrInvalidEncodingMethod), strings.Join(encodings, ",")) apierr.GetAPIError(apierr.ErrInvalidEncodingMethod), strings.Join(encodings, ","))
} }
decodeContentSize := r.Header.Get(api.AmzDecodedContentLength) decodeContentSize := r.Header.Get(api.AmzDecodedContentLength)
if len(decodeContentSize) == 0 { if len(decodeContentSize) == 0 {
return nil, errors.GetAPIError(errors.ErrMissingContentLength) return nil, apierr.GetAPIError(apierr.ErrMissingContentLength)
} }
if _, err := strconv.Atoi(decodeContentSize); err != nil { if _, err := strconv.Atoi(decodeContentSize); err != nil {
return nil, fmt.Errorf("%w: parse decoded content length: %s", errors.GetAPIError(errors.ErrMissingContentLength), err.Error()) return nil, fmt.Errorf("%w: parse decoded content length: %s", apierr.GetAPIError(apierr.ErrMissingContentLength), err.Error())
} }
chunkReader, err := newSignV4ChunkedReader(r) chunkReader, err := newSignV4ChunkedReader(r)
@ -378,43 +378,43 @@ func formEncryptionParamsBase(r *http.Request, isCopySource bool) (enc encryptio
} }
if r.TLS == nil { if r.TLS == nil {
return enc, errors.GetAPIError(errors.ErrInsecureSSECustomerRequest) return enc, apierr.GetAPIError(apierr.ErrInsecureSSECustomerRequest)
} }
if len(sseCustomerKey) > 0 && len(sseCustomerAlgorithm) == 0 { if len(sseCustomerKey) > 0 && len(sseCustomerAlgorithm) == 0 {
return enc, errors.GetAPIError(errors.ErrMissingSSECustomerAlgorithm) return enc, apierr.GetAPIError(apierr.ErrMissingSSECustomerAlgorithm)
} }
if len(sseCustomerAlgorithm) > 0 && len(sseCustomerKey) == 0 { if len(sseCustomerAlgorithm) > 0 && len(sseCustomerKey) == 0 {
return enc, errors.GetAPIError(errors.ErrMissingSSECustomerKey) return enc, apierr.GetAPIError(apierr.ErrMissingSSECustomerKey)
} }
if sseCustomerAlgorithm != layer.AESEncryptionAlgorithm { if sseCustomerAlgorithm != layer.AESEncryptionAlgorithm {
return enc, errors.GetAPIError(errors.ErrInvalidEncryptionAlgorithm) return enc, apierr.GetAPIError(apierr.ErrInvalidEncryptionAlgorithm)
} }
key, err := base64.StdEncoding.DecodeString(sseCustomerKey) key, err := base64.StdEncoding.DecodeString(sseCustomerKey)
if err != nil { if err != nil {
if isCopySource { if isCopySource {
return enc, errors.GetAPIError(errors.ErrInvalidSSECustomerParameters) return enc, apierr.GetAPIError(apierr.ErrInvalidSSECustomerParameters)
} }
return enc, errors.GetAPIError(errors.ErrInvalidSSECustomerKey) return enc, apierr.GetAPIError(apierr.ErrInvalidSSECustomerKey)
} }
if len(key) != layer.AESKeySize { if len(key) != layer.AESKeySize {
if isCopySource { if isCopySource {
return enc, errors.GetAPIError(errors.ErrInvalidSSECustomerParameters) return enc, apierr.GetAPIError(apierr.ErrInvalidSSECustomerParameters)
} }
return enc, errors.GetAPIError(errors.ErrInvalidSSECustomerKey) return enc, apierr.GetAPIError(apierr.ErrInvalidSSECustomerKey)
} }
keyMD5, err := base64.StdEncoding.DecodeString(sseCustomerKeyMD5) keyMD5, err := base64.StdEncoding.DecodeString(sseCustomerKeyMD5)
if err != nil { if err != nil {
return enc, errors.GetAPIError(errors.ErrSSECustomerKeyMD5Mismatch) return enc, apierr.GetAPIError(apierr.ErrSSECustomerKeyMD5Mismatch)
} }
md5Sum := md5.Sum(key) md5Sum := md5.Sum(key)
if !bytes.Equal(md5Sum[:], keyMD5) { if !bytes.Equal(md5Sum[:], keyMD5) {
return enc, errors.GetAPIError(errors.ErrSSECustomerKeyMD5Mismatch) return enc, apierr.GetAPIError(apierr.ErrSSECustomerKeyMD5Mismatch)
} }
params, err := encryption.NewParams(key) params, err := encryption.NewParams(key)
@ -444,7 +444,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
tags := new(data.Tagging) tags := new(data.Tagging)
if err = h.cfg.NewXMLDecoder(buffer).Decode(tags); err != nil { if err = h.cfg.NewXMLDecoder(buffer).Decode(tags); err != nil {
h.logAndSendError(w, "could not decode tag set", reqInfo, h.logAndSendError(w, "could not decode tag set", reqInfo,
fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrMalformedXML), err.Error())) fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error()))
return return
} }
tagSet, err = h.readTagSet(tags) tagSet, err = h.readTagSet(tags)
@ -467,7 +467,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
} }
if acl := auth.MultipartFormValue(r, "acl"); acl != "" && acl != basicACLPrivate { if acl := auth.MultipartFormValue(r, "acl"); acl != "" && acl != basicACLPrivate {
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported)) h.logAndSendError(w, "acl not supported for this bucket", reqInfo, apierr.GetAPIError(apierr.ErrAccessControlListNotSupported))
return return
} }
@ -508,12 +508,12 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
} }
if reqInfo.ObjectName == "" { if reqInfo.ObjectName == "" {
h.logAndSendError(w, "missing object name", reqInfo, errors.GetAPIError(errors.ErrInvalidArgument)) h.logAndSendError(w, "missing object name", reqInfo, apierr.GetAPIError(apierr.ErrInvalidArgument))
return return
} }
if !policy.CheckContentLength(size) { if !policy.CheckContentLength(size) {
h.logAndSendError(w, "invalid content-length", reqInfo, errors.GetAPIError(errors.ErrInvalidArgument)) h.logAndSendError(w, "invalid content-length", reqInfo, apierr.GetAPIError(apierr.ErrInvalidArgument))
return return
} }
@ -595,13 +595,13 @@ func checkPostPolicy(r *http.Request, reqInfo *middleware.ReqInfo, metadata map[
return nil, fmt.Errorf("could not unmarshal policy: %w", err) return nil, fmt.Errorf("could not unmarshal policy: %w", err)
} }
if policy.Expiration.Before(time.Now()) { if policy.Expiration.Before(time.Now()) {
return nil, fmt.Errorf("policy is expired: %w", errors.GetAPIError(errors.ErrInvalidArgument)) return nil, fmt.Errorf("policy is expired: %w", apierr.GetAPIError(apierr.ErrInvalidArgument))
} }
policy.empty = false policy.empty = false
} }
if r.MultipartForm == nil { if r.MultipartForm == nil {
return nil, stderrors.New("empty multipart form") return nil, errors.New("empty multipart form")
} }
for key, v := range r.MultipartForm.Value { for key, v := range r.MultipartForm.Value {
@ -632,7 +632,7 @@ func checkPostPolicy(r *http.Request, reqInfo *middleware.ReqInfo, metadata map[
for _, cond := range policy.Conditions { for _, cond := range policy.Conditions {
if cond.Key == "bucket" { if cond.Key == "bucket" {
if !cond.match(reqInfo.BucketName) { if !cond.match(reqInfo.BucketName) {
return nil, errors.GetAPIError(errors.ErrPostPolicyConditionInvalidFormat) return nil, apierr.GetAPIError(apierr.ErrPostPolicyConditionInvalidFormat)
} }
} }
} }
@ -674,10 +674,10 @@ func parseTaggingHeader(header http.Header) (map[string]string, error) {
if tagging := header.Get(api.AmzTagging); len(tagging) > 0 { if tagging := header.Get(api.AmzTagging); len(tagging) > 0 {
queries, err := url.ParseQuery(tagging) queries, err := url.ParseQuery(tagging)
if err != nil { if err != nil {
return nil, errors.GetAPIError(errors.ErrInvalidArgument) return nil, apierr.GetAPIError(apierr.ErrInvalidArgument)
} }
if len(queries) > maxTags { if len(queries) > maxTags {
return nil, errors.GetAPIError(errors.ErrInvalidTagsSizeExceed) return nil, apierr.GetAPIError(apierr.ErrInvalidTagsSizeExceed)
} }
tagSet = make(map[string]string, len(queries)) tagSet = make(map[string]string, len(queries))
for k, v := range queries { for k, v := range queries {
@ -727,7 +727,7 @@ func (h *handler) parseCommonCreateBucketParams(reqInfo *middleware.ReqInfo, box
} }
if p.SessionContainerCreation == nil { if p.SessionContainerCreation == nil {
return nil, nil, fmt.Errorf("%w: couldn't find session token for put", errors.GetAPIError(errors.ErrAccessDenied)) return nil, nil, fmt.Errorf("%w: couldn't find session token for put", apierr.GetAPIError(apierr.ErrAccessDenied))
} }
if err := checkBucketName(reqInfo.BucketName); err != nil { if err := checkBucketName(reqInfo.BucketName); err != nil {
@ -853,7 +853,7 @@ func (h *handler) putBucketSettingsRetryer() aws.RetryerV2 {
} }
options.Retryables = []retry.IsErrorRetryable{retry.IsErrorRetryableFunc(func(err error) aws.Ternary { options.Retryables = []retry.IsErrorRetryable{retry.IsErrorRetryableFunc(func(err error) aws.Ternary {
if stderrors.Is(err, tree.ErrNodeAccessDenied) { if errors.Is(err, tree.ErrNodeAccessDenied) {
return aws.TrueTernary return aws.TrueTernary
} }
return aws.FalseTernary return aws.FalseTernary
@ -982,7 +982,7 @@ func (h handler) setPlacementPolicy(prm *layer.CreateBucketParams, namespace, lo
return nil return nil
} }
return errors.GetAPIError(errors.ErrInvalidLocationConstraint) return apierr.GetAPIError(apierr.ErrInvalidLocationConstraint)
} }
func isLockEnabled(log *zap.Logger, header http.Header) bool { func isLockEnabled(log *zap.Logger, header http.Header) bool {
@ -1001,27 +1001,27 @@ func isLockEnabled(log *zap.Logger, header http.Header) bool {
func checkBucketName(bucketName string) error { func checkBucketName(bucketName string) error {
if len(bucketName) < 3 || len(bucketName) > 63 { if len(bucketName) < 3 || len(bucketName) > 63 {
return errors.GetAPIError(errors.ErrInvalidBucketName) return apierr.GetAPIError(apierr.ErrInvalidBucketName)
} }
if strings.HasPrefix(bucketName, "xn--") || strings.HasSuffix(bucketName, "-s3alias") { if strings.HasPrefix(bucketName, "xn--") || strings.HasSuffix(bucketName, "-s3alias") {
return errors.GetAPIError(errors.ErrInvalidBucketName) return apierr.GetAPIError(apierr.ErrInvalidBucketName)
} }
if net.ParseIP(bucketName) != nil { if net.ParseIP(bucketName) != nil {
return errors.GetAPIError(errors.ErrInvalidBucketName) return apierr.GetAPIError(apierr.ErrInvalidBucketName)
} }
labels := strings.Split(bucketName, ".") labels := strings.Split(bucketName, ".")
for _, label := range labels { for _, label := range labels {
if len(label) == 0 { if len(label) == 0 {
return errors.GetAPIError(errors.ErrInvalidBucketName) return apierr.GetAPIError(apierr.ErrInvalidBucketName)
} }
for i, r := range label { for i, r := range label {
if !isAlphaNum(r) && r != '-' { if !isAlphaNum(r) && r != '-' {
return errors.GetAPIError(errors.ErrInvalidBucketName) return apierr.GetAPIError(apierr.ErrInvalidBucketName)
} }
if (i == 0 || i == len(label)-1) && r == '-' { if (i == 0 || i == len(label)-1) && r == '-' {
return errors.GetAPIError(errors.ErrInvalidBucketName) return apierr.GetAPIError(apierr.ErrInvalidBucketName)
} }
} }
} }
@ -1040,7 +1040,7 @@ func (h *handler) parseLocationConstraint(r *http.Request) (*createBucketParams,
params := new(createBucketParams) params := new(createBucketParams)
if err := h.cfg.NewXMLDecoder(r.Body).Decode(params); err != nil { if err := h.cfg.NewXMLDecoder(r.Body).Decode(params); err != nil {
return nil, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrMalformedXML), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error())
} }
return params, nil return params, nil
} }

View file

@ -21,7 +21,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4" v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
@ -205,7 +205,7 @@ func TestPostObject(t *testing.T) {
t.Run(tc.key+";"+tc.filename, func(t *testing.T) { t.Run(tc.key+";"+tc.filename, func(t *testing.T) {
w := postObjectBase(hc, ns, bktName, tc.key, tc.filename, tc.content) w := postObjectBase(hc, ns, bktName, tc.key, tc.filename, tc.content)
if tc.err { if tc.err {
assertS3Error(hc.t, w, s3errors.GetAPIError(s3errors.ErrInternalError)) assertS3Error(hc.t, w, apierr.GetAPIError(apierr.ErrInternalError))
return return
} }
assertStatus(hc.t, w, http.StatusNoContent) assertStatus(hc.t, w, http.StatusNoContent)
@ -268,7 +268,7 @@ func TestPutObjectWithStreamBodyError(t *testing.T) {
r.Header.Set(api.AmzContentSha256, api.StreamingContentSHA256) r.Header.Set(api.AmzContentSha256, api.StreamingContentSHA256)
r.Header.Set(api.ContentEncoding, api.AwsChunked) r.Header.Set(api.ContentEncoding, api.AwsChunked)
tc.Handler().PutObjectHandler(w, r) tc.Handler().PutObjectHandler(w, r)
assertS3Error(t, w, s3errors.GetAPIError(s3errors.ErrMissingContentLength)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrMissingContentLength))
checkNotFound(t, tc, bktName, objName, emptyVersion) checkNotFound(t, tc, bktName, objName, emptyVersion)
} }
@ -284,7 +284,7 @@ func TestPutObjectWithInvalidContentMD5(t *testing.T) {
w, r := prepareTestPayloadRequest(tc, bktName, objName, bytes.NewReader(content)) w, r := prepareTestPayloadRequest(tc, bktName, objName, bytes.NewReader(content))
r.Header.Set(api.ContentMD5, base64.StdEncoding.EncodeToString([]byte("invalid"))) r.Header.Set(api.ContentMD5, base64.StdEncoding.EncodeToString([]byte("invalid")))
tc.Handler().PutObjectHandler(w, r) tc.Handler().PutObjectHandler(w, r)
assertS3Error(t, w, s3errors.GetAPIError(s3errors.ErrInvalidDigest)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrInvalidDigest))
checkNotFound(t, tc, bktName, objName, emptyVersion) checkNotFound(t, tc, bktName, objName, emptyVersion)
} }
@ -347,7 +347,7 @@ func TestPutObjectCheckContentSHA256(t *testing.T) {
hc.Handler().PutObjectHandler(w, r) hc.Handler().PutObjectHandler(w, r)
if tc.error { if tc.error {
assertS3Error(t, w, s3errors.GetAPIError(s3errors.ErrContentSHA256Mismatch)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrContentSHA256Mismatch))
w, r := prepareTestRequest(hc, bktName, objName, nil) w, r := prepareTestRequest(hc, bktName, objName, nil)
hc.Handler().GetObjectHandler(w, r) hc.Handler().GetObjectHandler(w, r)
@ -400,7 +400,7 @@ func TestPutChunkedTestContentEncoding(t *testing.T) {
w, req, _ = getChunkedRequest(hc.context, t, bktName, objName) w, req, _ = getChunkedRequest(hc.context, t, bktName, objName)
req.Header.Set(api.ContentEncoding, "gzip") req.Header.Set(api.ContentEncoding, "gzip")
hc.Handler().PutObjectHandler(w, req) hc.Handler().PutObjectHandler(w, req)
assertS3Error(t, w, s3errors.GetAPIError(s3errors.ErrInvalidEncodingMethod)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrInvalidEncodingMethod))
hc.config.bypassContentEncodingInChunks = true hc.config.bypassContentEncodingInChunks = true
w, req, _ = getChunkedRequest(hc.context, t, bktName, objName) w, req, _ = getChunkedRequest(hc.context, t, bktName, objName)
@ -479,10 +479,10 @@ func TestCreateBucket(t *testing.T) {
bktName := "bkt-name" bktName := "bkt-name"
info := createBucket(hc, bktName) info := createBucket(hc, bktName)
createBucketAssertS3Error(hc, bktName, info.Box, s3errors.ErrBucketAlreadyOwnedByYou) createBucketAssertS3Error(hc, bktName, info.Box, apierr.ErrBucketAlreadyOwnedByYou)
box2, _ := createAccessBox(t) box2, _ := createAccessBox(t)
createBucketAssertS3Error(hc, bktName, box2, s3errors.ErrBucketAlreadyExists) createBucketAssertS3Error(hc, bktName, box2, apierr.ErrBucketAlreadyExists)
} }
func TestCreateBucketWithoutPermissions(t *testing.T) { func TestCreateBucketWithoutPermissions(t *testing.T) {

View file

@ -6,7 +6,7 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -98,7 +98,7 @@ func TestPutObjectTaggingCheckUniqueness(t *testing.T) {
middleware.GetReqInfo(r.Context()).Tagging = tc.body middleware.GetReqInfo(r.Context()).Tagging = tc.body
hc.Handler().PutObjectTaggingHandler(w, r) hc.Handler().PutObjectTaggingHandler(w, r)
if tc.error { if tc.error {
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInvalidTagKeyUniqueness)) assertS3Error(t, w, apierr.GetAPIError(apierr.ErrInvalidTagKeyUniqueness))
return return
} }
assertStatus(t, w, http.StatusOK) assertStatus(t, w, http.StatusOK)

View file

@ -10,7 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
@ -59,25 +59,25 @@ func handleDeleteMarker(w http.ResponseWriter, err error) error {
} }
w.Header().Set(api.AmzDeleteMarker, "true") w.Header().Set(api.AmzDeleteMarker, "true")
return fmt.Errorf("%w: %s", s3errors.GetAPIError(target.ErrorCode), err) return fmt.Errorf("%w: %s", apierr.GetAPIError(target.ErrorCode), err)
} }
func transformToS3Error(err error) error { func transformToS3Error(err error) error {
err = frosterrors.UnwrapErr(err) // this wouldn't work with errors.Join err = frosterrors.UnwrapErr(err) // this wouldn't work with errors.Join
if _, ok := err.(s3errors.Error); ok { if _, ok := err.(apierr.Error); ok {
return err return err
} }
if errors.Is(err, frostfs.ErrAccessDenied) || if errors.Is(err, frostfs.ErrAccessDenied) ||
errors.Is(err, tree.ErrNodeAccessDenied) { errors.Is(err, tree.ErrNodeAccessDenied) {
return s3errors.GetAPIError(s3errors.ErrAccessDenied) return apierr.GetAPIError(apierr.ErrAccessDenied)
} }
if errors.Is(err, frostfs.ErrGatewayTimeout) { if errors.Is(err, frostfs.ErrGatewayTimeout) {
return s3errors.GetAPIError(s3errors.ErrGatewayTimeout) return apierr.GetAPIError(apierr.ErrGatewayTimeout)
} }
return s3errors.GetAPIError(s3errors.ErrInternalError) return apierr.GetAPIError(apierr.ErrInternalError)
} }
func (h *handler) ResolveBucket(ctx context.Context, bucket string) (*data.BucketInfo, error) { func (h *handler) ResolveBucket(ctx context.Context, bucket string) (*data.BucketInfo, error) {
@ -133,26 +133,26 @@ func parseRange(s string) (*layer.RangeParams, error) {
prefix := "bytes=" prefix := "bytes="
if !strings.HasPrefix(s, prefix) { if !strings.HasPrefix(s, prefix) {
return nil, s3errors.GetAPIError(s3errors.ErrInvalidRange) return nil, apierr.GetAPIError(apierr.ErrInvalidRange)
} }
s = strings.TrimPrefix(s, prefix) s = strings.TrimPrefix(s, prefix)
valuesStr := strings.Split(s, "-") valuesStr := strings.Split(s, "-")
if len(valuesStr) != 2 { if len(valuesStr) != 2 {
return nil, s3errors.GetAPIError(s3errors.ErrInvalidRange) return nil, apierr.GetAPIError(apierr.ErrInvalidRange)
} }
values := make([]uint64, 0, len(valuesStr)) values := make([]uint64, 0, len(valuesStr))
for _, v := range valuesStr { for _, v := range valuesStr {
num, err := strconv.ParseUint(v, 10, 64) num, err := strconv.ParseUint(v, 10, 64)
if err != nil { if err != nil {
return nil, s3errors.GetAPIError(s3errors.ErrInvalidRange) return nil, apierr.GetAPIError(apierr.ErrInvalidRange)
} }
values = append(values, num) values = append(values, num)
} }
if values[0] > values[1] { if values[0] > values[1] {
return nil, s3errors.GetAPIError(s3errors.ErrInvalidRange) return nil, apierr.GetAPIError(apierr.ErrInvalidRange)
} }
return &layer.RangeParams{ return &layer.RangeParams{

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
) )
@ -31,7 +31,7 @@ func (n *Layer) GetObjectTaggingAndLock(ctx context.Context, objVersion *data.Ob
tags, lockInfo, err = n.treeService.GetObjectTaggingAndLock(ctx, objVersion.BktInfo, nodeVersion) tags, lockInfo, err = n.treeService.GetObjectTaggingAndLock(ctx, objVersion.BktInfo, nodeVersion)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, data.LockInfo{}, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchKey), err.Error()) return nil, data.LockInfo{}, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
return nil, data.LockInfo{}, err return nil, data.LockInfo{}, err
} }

View file

@ -7,7 +7,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
@ -38,7 +38,7 @@ func (n *Layer) containerInfo(ctx context.Context, prm frostfs.PrmContainer) (*d
res, err = n.frostFS.Container(ctx, prm) res, err = n.frostFS.Container(ctx, prm)
if err != nil { if err != nil {
if client.IsErrContainerNotFound(err) { if client.IsErrContainerNotFound(err) {
return nil, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchBucket), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchBucket), err.Error())
} }
return nil, fmt.Errorf("get frostfs container: %w", err) return nil, fmt.Errorf("get frostfs container: %w", err)
} }

View file

@ -3,12 +3,12 @@ package layer
import ( import (
"bytes" "bytes"
"context" "context"
errorsStd "errors" "errors"
"fmt" "fmt"
"io" "io"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
@ -33,7 +33,7 @@ func (n *Layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
} }
if cors.CORSRules == nil { if cors.CORSRules == nil {
return errors.GetAPIError(errors.ErrMalformedXML) return apierr.GetAPIError(apierr.ErrMalformedXML)
} }
if err := checkCORS(cors); err != nil { if err := checkCORS(cors); err != nil {
@ -63,7 +63,7 @@ func (n *Layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
} }
objsToDelete, err := n.treeService.PutBucketCORS(ctx, p.BktInfo, newAddress(corsBkt.CID, createdObj.ID)) objsToDelete, err := n.treeService.PutBucketCORS(ctx, p.BktInfo, newAddress(corsBkt.CID, createdObj.ID))
objToDeleteNotFound := errorsStd.Is(err, tree.ErrNoNodeToRemove) objToDeleteNotFound := errors.Is(err, tree.ErrNoNodeToRemove)
if err != nil && !objToDeleteNotFound { if err != nil && !objToDeleteNotFound {
return err return err
} }
@ -106,7 +106,7 @@ func (n *Layer) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (*d
func (n *Layer) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) error { func (n *Layer) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) error {
objs, err := n.treeService.DeleteBucketCORS(ctx, bktInfo) objs, err := n.treeService.DeleteBucketCORS(ctx, bktInfo)
objNotFound := errorsStd.Is(err, tree.ErrNoNodeToRemove) objNotFound := errors.Is(err, tree.ErrNoNodeToRemove)
if err != nil && !objNotFound { if err != nil && !objNotFound {
return err return err
} }
@ -126,12 +126,12 @@ func checkCORS(cors *data.CORSConfiguration) error {
for _, r := range cors.CORSRules { for _, r := range cors.CORSRules {
for _, m := range r.AllowedMethods { for _, m := range r.AllowedMethods {
if _, ok := supportedMethods[m]; !ok { if _, ok := supportedMethods[m]; !ok {
return errors.GetAPIErrorWithError(errors.ErrCORSUnsupportedMethod, fmt.Errorf("unsupported method is %s", m)) return apierr.GetAPIErrorWithError(apierr.ErrCORSUnsupportedMethod, fmt.Errorf("unsupported method is %s", m))
} }
} }
for _, h := range r.ExposeHeaders { for _, h := range r.ExposeHeaders {
if h == wildcard { if h == wildcard {
return errors.GetAPIError(errors.ErrCORSWildcardExposeHeaders) return apierr.GetAPIError(apierr.ErrCORSWildcardExposeHeaders)
} }
} }
} }

View file

@ -6,7 +6,7 @@ import (
"crypto/rand" "crypto/rand"
"encoding/json" "encoding/json"
"encoding/xml" "encoding/xml"
stderrors "errors" "errors"
"fmt" "fmt"
"io" "io"
"net/url" "net/url"
@ -17,8 +17,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
@ -333,7 +332,7 @@ func (n *Layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInf
containerID, err := n.ResolveBucket(ctx, zone, name) containerID, err := n.ResolveBucket(ctx, zone, name)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "not found") { if strings.Contains(err.Error(), "not found") {
return nil, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucket), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchBucket), err.Error())
} }
return nil, err return nil, err
} }
@ -399,9 +398,9 @@ func (n *Layer) GetObject(ctx context.Context, p *GetObjectParams) (*ObjectPaylo
if err != nil { if err != nil {
if client.IsErrObjectNotFound(err) { if client.IsErrObjectNotFound(err) {
if p.Versioned { if p.Versioned {
err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchVersion), err.Error()) err = fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchVersion), err.Error())
} else { } else {
err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchKey), err.Error()) err = fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
} }
@ -657,22 +656,22 @@ func (n *Layer) handleNotFoundError(bkt *data.BucketInfo, obj *VersionedObject)
} }
func isNotFoundError(err error) bool { func isNotFoundError(err error) bool {
return errors.IsS3Error(err, errors.ErrNoSuchKey) || return apierr.IsS3Error(err, apierr.ErrNoSuchKey) ||
errors.IsS3Error(err, errors.ErrNoSuchVersion) apierr.IsS3Error(err, apierr.ErrNoSuchVersion)
} }
func (n *Layer) getNodeVersionsToDelete(ctx context.Context, bkt *data.BucketInfo, obj *VersionedObject) ([]*data.NodeVersion, error) { func (n *Layer) getNodeVersionsToDelete(ctx context.Context, bkt *data.BucketInfo, obj *VersionedObject) ([]*data.NodeVersion, error) {
var versionsToDelete []*data.NodeVersion var versionsToDelete []*data.NodeVersion
versions, err := n.treeService.GetVersions(ctx, bkt, obj.Name) versions, err := n.treeService.GetVersions(ctx, bkt, obj.Name)
if err != nil { if err != nil {
if stderrors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchKey), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
return nil, err return nil, err
} }
if len(versions) == 0 { if len(versions) == 0 {
return nil, fmt.Errorf("%w: there isn't tree node with requested version id", s3errors.GetAPIError(s3errors.ErrNoSuchVersion)) return nil, fmt.Errorf("%w: there isn't tree node with requested version id", apierr.GetAPIError(apierr.ErrNoSuchVersion))
} }
sort.Slice(versions, func(i, j int) bool { sort.Slice(versions, func(i, j int) bool {
@ -714,7 +713,7 @@ func (n *Layer) getNodeVersionsToDelete(ctx context.Context, bkt *data.BucketInf
} }
if len(versionsToDelete) == 0 { if len(versionsToDelete) == 0 {
return nil, fmt.Errorf("%w: there isn't tree node with requested version id", s3errors.GetAPIError(s3errors.ErrNoSuchVersion)) return nil, fmt.Errorf("%w: there isn't tree node with requested version id", apierr.GetAPIError(apierr.ErrNoSuchVersion))
} }
n.reqLogger(ctx).Debug(logs.GetTreeNodeToDelete, zap.Stringer("cid", bkt.CID), zap.Strings("oids", oids)) n.reqLogger(ctx).Debug(logs.GetTreeNodeToDelete, zap.Stringer("cid", bkt.CID), zap.Strings("oids", oids))
@ -787,17 +786,17 @@ func (n *Layer) DeleteObjects(ctx context.Context, p *DeleteObjectParams) []*Ver
func (n *Layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, 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 apierr.IsS3Error(err, apierr.ErrNoSuchBucket) {
return n.createContainer(ctx, p) return n.createContainer(ctx, p)
} }
return nil, err return nil, err
} }
if p.SessionContainerCreation != nil && session.IssuedBy(*p.SessionContainerCreation, bktInfo.Owner) { if p.SessionContainerCreation != nil && session.IssuedBy(*p.SessionContainerCreation, bktInfo.Owner) {
return nil, errors.GetAPIError(errors.ErrBucketAlreadyOwnedByYou) return nil, apierr.GetAPIError(apierr.ErrBucketAlreadyOwnedByYou)
} }
return nil, errors.GetAPIError(errors.ErrBucketAlreadyExists) return nil, apierr.GetAPIError(apierr.ErrBucketAlreadyExists)
} }
func (n *Layer) ResolveBucket(ctx context.Context, zone, name string) (cid.ID, error) { func (n *Layer) ResolveBucket(ctx context.Context, zone, name string) (cid.ID, error) {
@ -824,7 +823,7 @@ func (n *Layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
return err return err
} }
if len(res) != 0 { if len(res) != 0 {
return errors.GetAPIError(errors.ErrBucketNotEmpty) return apierr.GetAPIError(apierr.ErrBucketNotEmpty)
} }
} }

View file

@ -10,7 +10,7 @@ import (
"io" "io"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
@ -51,13 +51,13 @@ func (n *Layer) PutBucketLifecycleConfiguration(ctx context.Context, p *PutBucke
hashBytes, err := base64.StdEncoding.DecodeString(p.MD5Hash) hashBytes, err := base64.StdEncoding.DecodeString(p.MD5Hash)
if err != nil { if err != nil {
return apiErr.GetAPIError(apiErr.ErrInvalidDigest) return apierr.GetAPIError(apierr.ErrInvalidDigest)
} }
if !bytes.Equal(hashBytes, createdObj.MD5Sum) { if !bytes.Equal(hashBytes, createdObj.MD5Sum) {
n.deleteLifecycleObject(ctx, p.BktInfo, newAddress(lifecycleBkt.CID, createdObj.ID)) n.deleteLifecycleObject(ctx, p.BktInfo, newAddress(lifecycleBkt.CID, createdObj.ID))
return apiErr.GetAPIError(apiErr.ErrInvalidDigest) return apierr.GetAPIError(apierr.ErrInvalidDigest)
} }
objsToDelete, err := n.treeService.PutBucketLifecycleConfiguration(ctx, p.BktInfo, newAddress(lifecycleBkt.CID, createdObj.ID)) objsToDelete, err := n.treeService.PutBucketLifecycleConfiguration(ctx, p.BktInfo, newAddress(lifecycleBkt.CID, createdObj.ID))
@ -106,7 +106,7 @@ func (n *Layer) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *da
} }
if objNotFound { if objNotFound {
return nil, fmt.Errorf("%w: %s", apiErr.GetAPIError(apiErr.ErrNoSuchLifecycleConfiguration), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchLifecycleConfiguration), err.Error())
} }
var prmAuth frostfs.PrmAuth var prmAuth frostfs.PrmAuth

View file

@ -8,8 +8,8 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -36,7 +36,7 @@ func TestBucketLifecycle(t *testing.T) {
hash.Write(lifecycleBytes) hash.Write(lifecycleBytes)
_, err = tc.layer.GetBucketLifecycleConfiguration(tc.ctx, tc.bktInfo) _, err = tc.layer.GetBucketLifecycleConfiguration(tc.ctx, tc.bktInfo)
require.Equal(t, apiErr.GetAPIError(apiErr.ErrNoSuchLifecycleConfiguration), frostfsErrors.UnwrapErr(err)) require.Equal(t, apierr.GetAPIError(apierr.ErrNoSuchLifecycleConfiguration), frosterr.UnwrapErr(err))
err = tc.layer.DeleteBucketLifecycleConfiguration(tc.ctx, tc.bktInfo) err = tc.layer.DeleteBucketLifecycleConfiguration(tc.ctx, tc.bktInfo)
require.NoError(t, err) require.NoError(t, err)
@ -57,7 +57,7 @@ func TestBucketLifecycle(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
_, err = tc.layer.GetBucketLifecycleConfiguration(tc.ctx, tc.bktInfo) _, err = tc.layer.GetBucketLifecycleConfiguration(tc.ctx, tc.bktInfo)
require.Equal(t, apiErr.GetAPIError(apiErr.ErrNoSuchLifecycleConfiguration), frostfsErrors.UnwrapErr(err)) require.Equal(t, apierr.GetAPIError(apierr.ErrNoSuchLifecycleConfiguration), frosterr.UnwrapErr(err))
} }
func ptr[T any](t T) *T { func ptr[T any](t T) *T {

View file

@ -11,7 +11,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
"github.com/panjf2000/ants/v2" "github.com/panjf2000/ants/v2"
@ -691,10 +691,10 @@ func filterVersionsByMarker(objects []*data.ExtendedNodeVersion, p *ListObjectVe
return objects[j+1:], nil return objects[j+1:], nil
} }
} }
return nil, s3errors.GetAPIError(s3errors.ErrInvalidVersion) return nil, apierr.GetAPIError(apierr.ErrInvalidVersion)
} else if obj.NodeVersion.FilePath > p.KeyMarker { } else if obj.NodeVersion.FilePath > p.KeyMarker {
if p.VersionIDMarker != "" { if p.VersionIDMarker != "" {
return nil, s3errors.GetAPIError(s3errors.ErrInvalidVersion) return nil, apierr.GetAPIError(apierr.ErrInvalidVersion)
} }
return objects[i:], nil return objects[i:], nil
} }

View file

@ -17,7 +17,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
@ -190,13 +190,13 @@ func (n *Layer) UploadPart(ctx context.Context, p *UploadPartParams) (string, er
multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID) multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return "", fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchUpload), err.Error()) return "", fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchUpload), err.Error())
} }
return "", err return "", err
} }
if p.Size > UploadMaxSize { if p.Size > UploadMaxSize {
return "", fmt.Errorf("%w: %d/%d", s3errors.GetAPIError(s3errors.ErrEntityTooLarge), p.Size, UploadMaxSize) return "", fmt.Errorf("%w: %d/%d", apierr.GetAPIError(apierr.ErrEntityTooLarge), p.Size, UploadMaxSize)
} }
objInfo, err := n.uploadPart(ctx, multipartInfo, p) objInfo, err := n.uploadPart(ctx, multipartInfo, p)
@ -211,7 +211,7 @@ func (n *Layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
encInfo := FormEncryptionInfo(multipartInfo.Meta) encInfo := FormEncryptionInfo(multipartInfo.Meta)
if err := p.Info.Encryption.MatchObjectEncryption(encInfo); err != nil { if err := p.Info.Encryption.MatchObjectEncryption(encInfo); err != nil {
n.reqLogger(ctx).Warn(logs.MismatchedObjEncryptionInfo, zap.Error(err)) n.reqLogger(ctx).Warn(logs.MismatchedObjEncryptionInfo, zap.Error(err))
return nil, s3errors.GetAPIError(s3errors.ErrInvalidEncryptionParameters) return nil, apierr.GetAPIError(apierr.ErrInvalidEncryptionParameters)
} }
bktInfo := p.Info.Bkt bktInfo := p.Info.Bkt
@ -244,7 +244,7 @@ func (n *Layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
if len(p.ContentMD5) > 0 { if len(p.ContentMD5) > 0 {
hashBytes, err := base64.StdEncoding.DecodeString(p.ContentMD5) hashBytes, err := base64.StdEncoding.DecodeString(p.ContentMD5)
if err != nil { if err != nil {
return nil, s3errors.GetAPIError(s3errors.ErrInvalidDigest) return nil, apierr.GetAPIError(apierr.ErrInvalidDigest)
} }
if hex.EncodeToString(hashBytes) != hex.EncodeToString(createdObj.MD5Sum) { if hex.EncodeToString(hashBytes) != hex.EncodeToString(createdObj.MD5Sum) {
prm := frostfs.PrmObjectDelete{ prm := frostfs.PrmObjectDelete{
@ -256,7 +256,7 @@ func (n *Layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
if err != nil { if err != nil {
n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", bktInfo.CID), zap.Stringer("oid", createdObj.ID)) n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", bktInfo.CID), zap.Stringer("oid", createdObj.ID))
} }
return nil, s3errors.GetAPIError(s3errors.ErrInvalidDigest) return nil, apierr.GetAPIError(apierr.ErrInvalidDigest)
} }
} }
if p.Info.Encryption.Enabled() { if p.Info.Encryption.Enabled() {
@ -266,14 +266,14 @@ func (n *Layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
if !p.Info.Encryption.Enabled() && len(p.ContentSHA256Hash) > 0 && !auth.IsStandardContentSHA256(p.ContentSHA256Hash) { if !p.Info.Encryption.Enabled() && len(p.ContentSHA256Hash) > 0 && !auth.IsStandardContentSHA256(p.ContentSHA256Hash) {
contentHashBytes, err := hex.DecodeString(p.ContentSHA256Hash) contentHashBytes, err := hex.DecodeString(p.ContentSHA256Hash)
if err != nil { if err != nil {
return nil, s3errors.GetAPIError(s3errors.ErrContentSHA256Mismatch) return nil, apierr.GetAPIError(apierr.ErrContentSHA256Mismatch)
} }
if !bytes.Equal(contentHashBytes, createdObj.HashSum) { if !bytes.Equal(contentHashBytes, createdObj.HashSum) {
err = n.objectDelete(ctx, bktInfo, createdObj.ID) err = n.objectDelete(ctx, bktInfo, createdObj.ID)
if err != nil { if err != nil {
n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", bktInfo.CID), zap.Stringer("oid", createdObj.ID)) n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", bktInfo.CID), zap.Stringer("oid", createdObj.ID))
} }
return nil, s3errors.GetAPIError(s3errors.ErrContentSHA256Mismatch) return nil, apierr.GetAPIError(apierr.ErrContentSHA256Mismatch)
} }
} }
@ -326,7 +326,7 @@ func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.
multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID) multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchUpload), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchUpload), err.Error())
} }
return nil, err return nil, err
} }
@ -342,11 +342,11 @@ func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.
if p.Range != nil { if p.Range != nil {
size = p.Range.End - p.Range.Start + 1 size = p.Range.End - p.Range.Start + 1
if p.Range.End > srcObjectSize { if p.Range.End > srcObjectSize {
return nil, fmt.Errorf("%w: %d-%d/%d", s3errors.GetAPIError(s3errors.ErrInvalidCopyPartRangeSource), p.Range.Start, p.Range.End, srcObjectSize) return nil, fmt.Errorf("%w: %d-%d/%d", apierr.GetAPIError(apierr.ErrInvalidCopyPartRangeSource), p.Range.Start, p.Range.End, srcObjectSize)
} }
} }
if size > UploadMaxSize { if size > UploadMaxSize {
return nil, fmt.Errorf("%w: %d/%d", s3errors.GetAPIError(s3errors.ErrEntityTooLarge), size, UploadMaxSize) return nil, fmt.Errorf("%w: %d/%d", apierr.GetAPIError(apierr.ErrEntityTooLarge), size, UploadMaxSize)
} }
objPayload, err := n.GetObject(ctx, &GetObjectParams{ objPayload, err := n.GetObject(ctx, &GetObjectParams{
@ -373,7 +373,7 @@ func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.
func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*UploadData, *data.ExtendedObjectInfo, error) { func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*UploadData, *data.ExtendedObjectInfo, error) {
for i := 1; i < len(p.Parts); i++ { for i := 1; i < len(p.Parts); i++ {
if p.Parts[i].PartNumber <= p.Parts[i-1].PartNumber { if p.Parts[i].PartNumber <= p.Parts[i-1].PartNumber {
return nil, nil, s3errors.GetAPIError(s3errors.ErrInvalidPartOrder) return nil, nil, apierr.GetAPIError(apierr.ErrInvalidPartOrder)
} }
} }
@ -384,7 +384,7 @@ func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
encInfo := FormEncryptionInfo(multipartInfo.Meta) encInfo := FormEncryptionInfo(multipartInfo.Meta)
if len(partsInfo) < len(p.Parts) { if len(partsInfo) < len(p.Parts) {
return nil, nil, fmt.Errorf("%w: found %d parts, need %d", s3errors.GetAPIError(s3errors.ErrInvalidPart), len(partsInfo), len(p.Parts)) return nil, nil, fmt.Errorf("%w: found %d parts, need %d", apierr.GetAPIError(apierr.ErrInvalidPart), len(partsInfo), len(p.Parts))
} }
var multipartObjetSize uint64 var multipartObjetSize uint64
@ -396,12 +396,12 @@ func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
for i, part := range p.Parts { for i, part := range p.Parts {
partInfo := partsInfo.Extract(part.PartNumber, data.UnQuote(part.ETag), n.features.MD5Enabled()) partInfo := partsInfo.Extract(part.PartNumber, data.UnQuote(part.ETag), n.features.MD5Enabled())
if partInfo == nil { if partInfo == nil {
return nil, nil, fmt.Errorf("%w: unknown part %d or etag mismatched", s3errors.GetAPIError(s3errors.ErrInvalidPart), part.PartNumber) return nil, nil, fmt.Errorf("%w: unknown part %d or etag mismatched", apierr.GetAPIError(apierr.ErrInvalidPart), part.PartNumber)
} }
// for the last part we have no minimum size limit // for the last part we have no minimum size limit
if i != len(p.Parts)-1 && partInfo.Size < UploadMinSize { if i != len(p.Parts)-1 && partInfo.Size < UploadMinSize {
return nil, nil, fmt.Errorf("%w: %d/%d", s3errors.GetAPIError(s3errors.ErrEntityTooSmall), partInfo.Size, UploadMinSize) return nil, nil, fmt.Errorf("%w: %d/%d", apierr.GetAPIError(apierr.ErrEntityTooSmall), partInfo.Size, UploadMinSize)
} }
parts = append(parts, partInfo) parts = append(parts, partInfo)
multipartObjetSize += partInfo.Size // even if encryption is enabled size is actual (decrypted) multipartObjetSize += partInfo.Size // even if encryption is enabled size is actual (decrypted)
@ -473,7 +473,7 @@ func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
zap.String("uploadKey", p.Info.Key), zap.String("uploadKey", p.Info.Key),
zap.Error(err)) zap.Error(err))
return nil, nil, s3errors.GetAPIError(s3errors.ErrInternalError) return nil, nil, apierr.GetAPIError(apierr.ErrInternalError)
} }
var addr oid.Address var addr oid.Address
@ -581,7 +581,7 @@ func (n *Layer) ListParts(ctx context.Context, p *ListPartsParams) (*ListPartsIn
encInfo := FormEncryptionInfo(multipartInfo.Meta) encInfo := FormEncryptionInfo(multipartInfo.Meta)
if err = p.Info.Encryption.MatchObjectEncryption(encInfo); err != nil { if err = p.Info.Encryption.MatchObjectEncryption(encInfo); err != nil {
n.reqLogger(ctx).Warn(logs.MismatchedObjEncryptionInfo, zap.Error(err)) n.reqLogger(ctx).Warn(logs.MismatchedObjEncryptionInfo, zap.Error(err))
return nil, s3errors.GetAPIError(s3errors.ErrInvalidEncryptionParameters) return nil, apierr.GetAPIError(apierr.ErrInvalidEncryptionParameters)
} }
res.Owner = multipartInfo.Owner res.Owner = multipartInfo.Owner
@ -649,7 +649,7 @@ func (n *Layer) getUploadParts(ctx context.Context, p *UploadInfoParams) (*data.
multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Bkt, p.Key, p.UploadID) multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Bkt, p.Key, p.UploadID)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, nil, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchUpload), err.Error()) return nil, nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchUpload), err.Error())
} }
return nil, nil, err return nil, nil, err
} }

View file

@ -20,7 +20,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
@ -51,7 +51,7 @@ type (
} }
DeleteMarkerError struct { DeleteMarkerError struct {
ErrorCode apiErrors.ErrorCode ErrorCode apierr.ErrorCode
} }
) )
@ -289,28 +289,28 @@ func (n *Layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Extend
if !p.Encryption.Enabled() && len(p.ContentMD5) > 0 { if !p.Encryption.Enabled() && len(p.ContentMD5) > 0 {
headerMd5Hash, err := base64.StdEncoding.DecodeString(p.ContentMD5) headerMd5Hash, err := base64.StdEncoding.DecodeString(p.ContentMD5)
if err != nil { if err != nil {
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidDigest) return nil, apierr.GetAPIError(apierr.ErrInvalidDigest)
} }
if !bytes.Equal(headerMd5Hash, createdObj.MD5Sum) { if !bytes.Equal(headerMd5Hash, createdObj.MD5Sum) {
err = n.objectDelete(ctx, p.BktInfo, createdObj.ID) err = n.objectDelete(ctx, p.BktInfo, createdObj.ID)
if err != nil { if err != nil {
n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", p.BktInfo.CID), zap.Stringer("oid", createdObj.ID)) n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", p.BktInfo.CID), zap.Stringer("oid", createdObj.ID))
} }
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidDigest) return nil, apierr.GetAPIError(apierr.ErrInvalidDigest)
} }
} }
if !p.Encryption.Enabled() && len(p.ContentSHA256Hash) > 0 && !auth.IsStandardContentSHA256(p.ContentSHA256Hash) { if !p.Encryption.Enabled() && len(p.ContentSHA256Hash) > 0 && !auth.IsStandardContentSHA256(p.ContentSHA256Hash) {
contentHashBytes, err := hex.DecodeString(p.ContentSHA256Hash) contentHashBytes, err := hex.DecodeString(p.ContentSHA256Hash)
if err != nil { if err != nil {
return nil, apiErrors.GetAPIError(apiErrors.ErrContentSHA256Mismatch) return nil, apierr.GetAPIError(apierr.ErrContentSHA256Mismatch)
} }
if !bytes.Equal(contentHashBytes, createdObj.HashSum) { if !bytes.Equal(contentHashBytes, createdObj.HashSum) {
err = n.objectDelete(ctx, p.BktInfo, createdObj.ID) err = n.objectDelete(ctx, p.BktInfo, createdObj.ID)
if err != nil { if err != nil {
n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", p.BktInfo.CID), zap.Stringer("oid", createdObj.ID)) n.reqLogger(ctx).Debug(logs.FailedToDeleteObject, zap.Stringer("cid", p.BktInfo.CID), zap.Stringer("oid", createdObj.ID))
} }
return nil, apiErrors.GetAPIError(apiErrors.ErrContentSHA256Mismatch) return nil, apierr.GetAPIError(apierr.ErrContentSHA256Mismatch)
} }
} }
@ -398,19 +398,19 @@ func (n *Layer) headLastVersionIfNotDeleted(ctx context.Context, bkt *data.Bucke
node, err := n.treeService.GetLatestVersion(ctx, bkt, objectName) node, err := n.treeService.GetLatestVersion(ctx, bkt, objectName)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrNoSuchKey), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
return nil, err return nil, err
} }
if node.IsDeleteMarker { if node.IsDeleteMarker {
return nil, DeleteMarkerError{ErrorCode: apiErrors.ErrNoSuchKey} return nil, DeleteMarkerError{ErrorCode: apierr.ErrNoSuchKey}
} }
meta, err := n.objectHead(ctx, bkt, node.OID) meta, err := n.objectHead(ctx, bkt, node.OID)
if err != nil { if err != nil {
if client.IsErrObjectNotFound(err) { if client.IsErrObjectNotFound(err) {
return nil, fmt.Errorf("%w: %s; %s", apiErrors.GetAPIError(apiErrors.ErrNoSuchKey), err.Error(), node.OID.EncodeToString()) return nil, fmt.Errorf("%w: %s; %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error(), node.OID.EncodeToString())
} }
return nil, err return nil, err
} }
@ -434,7 +434,7 @@ func (n *Layer) headVersion(ctx context.Context, bkt *data.BucketInfo, p *HeadOb
foundVersion, err = n.treeService.GetUnversioned(ctx, bkt, p.Object) foundVersion, err = n.treeService.GetUnversioned(ctx, bkt, p.Object)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrNoSuchVersion), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchVersion), err.Error())
} }
return nil, err return nil, err
} }
@ -451,7 +451,7 @@ func (n *Layer) headVersion(ctx context.Context, bkt *data.BucketInfo, p *HeadOb
} }
} }
if foundVersion == nil { if foundVersion == nil {
return nil, fmt.Errorf("%w: there isn't tree node with requested version id", apiErrors.GetAPIError(apiErrors.ErrNoSuchVersion)) return nil, fmt.Errorf("%w: there isn't tree node with requested version id", apierr.GetAPIError(apierr.ErrNoSuchVersion))
} }
} }
@ -461,13 +461,13 @@ func (n *Layer) headVersion(ctx context.Context, bkt *data.BucketInfo, p *HeadOb
} }
if foundVersion.IsDeleteMarker { if foundVersion.IsDeleteMarker {
return nil, DeleteMarkerError{ErrorCode: apiErrors.ErrMethodNotAllowed} return nil, DeleteMarkerError{ErrorCode: apierr.ErrMethodNotAllowed}
} }
meta, err := n.objectHead(ctx, bkt, foundVersion.OID) meta, err := n.objectHead(ctx, bkt, foundVersion.OID)
if err != nil { if err != nil {
if client.IsErrObjectNotFound(err) { if client.IsErrObjectNotFound(err) {
return nil, fmt.Errorf("%w: %s", apiErrors.GetAPIError(apiErrors.ErrNoSuchVersion), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchVersion), err.Error())
} }
return nil, err return nil, err
} }

View file

@ -3,7 +3,7 @@ package layer
import ( import (
"context" "context"
"encoding/xml" "encoding/xml"
errorsStd "errors" "errors"
"fmt" "fmt"
"math" "math"
"strconv" "strconv"
@ -11,7 +11,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
@ -42,7 +42,7 @@ func (n *Layer) PutLockInfo(ctx context.Context, p *PutLockInfoParams) (err erro
} }
lockInfo, err := n.treeService.GetLock(ctx, p.ObjVersion.BktInfo, versionNode.ID) lockInfo, err := n.treeService.GetLock(ctx, p.ObjVersion.BktInfo, versionNode.ID)
if err != nil && !errorsStd.Is(err, tree.ErrNodeNotFound) { if err != nil && !errors.Is(err, tree.ErrNodeNotFound) {
return err return err
} }
@ -148,7 +148,7 @@ func (n *Layer) GetLockInfo(ctx context.Context, objVersion *data.ObjectVersion)
} }
lockInfo, err := n.treeService.GetLock(ctx, objVersion.BktInfo, versionNode.ID) lockInfo, err := n.treeService.GetLock(ctx, objVersion.BktInfo, versionNode.ID)
if err != nil && !errorsStd.Is(err, tree.ErrNodeNotFound) { if err != nil && !errors.Is(err, tree.ErrNodeNotFound) {
return nil, err return nil, err
} }
if lockInfo == nil { if lockInfo == nil {
@ -167,13 +167,13 @@ func (n *Layer) getCORS(ctx context.Context, bkt *data.BucketInfo) (*data.CORSCo
} }
addr, err := n.treeService.GetBucketCORS(ctx, bkt) addr, err := n.treeService.GetBucketCORS(ctx, bkt)
objNotFound := errorsStd.Is(err, tree.ErrNodeNotFound) objNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !objNotFound { if err != nil && !objNotFound {
return nil, err return nil, err
} }
if objNotFound { if objNotFound {
return nil, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchCORSConfiguration), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchCORSConfiguration), err.Error())
} }
var prmAuth frostfs.PrmAuth var prmAuth frostfs.PrmAuth
@ -211,7 +211,7 @@ func (n *Layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo)
settings, err := n.treeService.GetSettingsNode(ctx, bktInfo) settings, err := n.treeService.GetSettingsNode(ctx, bktInfo)
if err != nil { if err != nil {
if !errorsStd.Is(err, tree.ErrNodeNotFound) { if !errors.Is(err, tree.ErrNodeNotFound) {
return nil, err return nil, err
} }
settings = &data.BucketSettings{Versioning: data.VersioningUnversioned} settings = &data.BucketSettings{Versioning: data.VersioningUnversioned}

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
@ -41,7 +41,7 @@ func (n *Layer) GetObjectTagging(ctx context.Context, p *data.GetObjectTaggingPa
tags, err := n.treeService.GetObjectTagging(ctx, p.ObjectVersion.BktInfo, nodeVersion) tags, err := n.treeService.GetObjectTagging(ctx, p.ObjectVersion.BktInfo, nodeVersion)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return "", nil, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchKey), err.Error()) return "", nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
return "", nil, err return "", nil, err
} }
@ -64,7 +64,7 @@ func (n *Layer) PutObjectTagging(ctx context.Context, p *data.PutObjectTaggingPa
err = n.treeService.PutObjectTagging(ctx, p.ObjectVersion.BktInfo, nodeVersion, p.TagSet) err = n.treeService.PutObjectTagging(ctx, p.ObjectVersion.BktInfo, nodeVersion, p.TagSet)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchKey), err.Error()) return fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
return err return err
} }
@ -83,7 +83,7 @@ func (n *Layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectVersion)
err = n.treeService.DeleteObjectTagging(ctx, p.BktInfo, version) err = n.treeService.DeleteObjectTagging(ctx, p.BktInfo, version)
if err != nil { if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchKey), err.Error()) return fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
return err return err
} }
@ -156,14 +156,14 @@ func (n *Layer) getNodeVersion(ctx context.Context, objVersion *data.ObjectVersi
} }
} }
if version == nil { if version == nil {
err = fmt.Errorf("%w: there isn't tree node with requested version id", s3errors.GetAPIError(s3errors.ErrNoSuchVersion)) err = fmt.Errorf("%w: there isn't tree node with requested version id", apierr.GetAPIError(apierr.ErrNoSuchVersion))
} }
} }
if err == nil && version.IsDeleteMarker && !objVersion.NoErrorOnDeleteMarker { if err == nil && version.IsDeleteMarker && !objVersion.NoErrorOnDeleteMarker {
return nil, fmt.Errorf("%w: found version is delete marker", s3errors.GetAPIError(s3errors.ErrNoSuchKey)) return nil, fmt.Errorf("%w: found version is delete marker", apierr.GetAPIError(apierr.ErrNoSuchKey))
} else if errors.Is(err, tree.ErrNodeNotFound) { } else if errors.Is(err, tree.ErrNodeNotFound) {
return nil, fmt.Errorf("%w: %s", s3errors.GetAPIError(s3errors.ErrNoSuchKey), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchKey), err.Error())
} }
if err == nil && version != nil && !version.IsDeleteMarker { if err == nil && version != nil && !version.IsDeleteMarker {

View file

@ -8,9 +8,9 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
@ -57,9 +57,10 @@ func Auth(center Center, log *zap.Logger) Func {
reqLogOrDefault(ctx, log).Debug(logs.CouldntReceiveAccessBoxForGateKeyRandomKeyWillBeUsed, zap.Error(err)) reqLogOrDefault(ctx, log).Debug(logs.CouldntReceiveAccessBoxForGateKeyRandomKeyWillBeUsed, zap.Error(err))
} else { } else {
reqLogOrDefault(ctx, log).Error(logs.FailedToPassAuthentication, zap.Error(err)) reqLogOrDefault(ctx, log).Error(logs.FailedToPassAuthentication, zap.Error(err))
err = frostfsErrors.UnwrapErr(err) err = frosterr.UnwrapErr(err)
if _, ok := err.(apiErrors.Error); !ok { log.Info("error", zap.Error(err), zap.String("code", err.(apierr.Error).Code), zap.String("description", err.(apierr.Error).Description))
err = apiErrors.GetAPIError(apiErrors.ErrAccessDenied) if _, ok := err.(apierr.Error); !ok {
err = apierr.GetAPIError(apierr.ErrAccessDenied)
} }
if _, wrErr := WriteErrorResponse(w, GetReqInfo(r.Context()), err); wrErr != nil { if _, wrErr := WriteErrorResponse(w, GetReqInfo(r.Context()), err); wrErr != nil {
reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr)) reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr))

View file

@ -11,7 +11,7 @@ import (
"strings" "strings"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
@ -145,11 +145,11 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error {
case st == chain.Allow: case st == chain.Allow:
return nil return nil
case st != chain.NoRuleFound: case st != chain.NoRuleFound:
return apiErr.GetAPIErrorWithError(apiErr.ErrAccessDenied, fmt.Errorf("policy check: %s", st.String())) return apierr.GetAPIErrorWithError(apierr.ErrAccessDenied, fmt.Errorf("policy check: %s", st.String()))
} }
if cfg.Settings.PolicyDenyByDefault() { if cfg.Settings.PolicyDenyByDefault() {
return apiErr.GetAPIErrorWithError(apiErr.ErrAccessDenied, fmt.Errorf("policy check: %s", st.String())) return apierr.GetAPIErrorWithError(apierr.ErrAccessDenied, fmt.Errorf("policy check: %s", st.String()))
} }
return nil return nil
@ -461,7 +461,7 @@ func determineRequestTags(r *http.Request, decoder XMLDecoder, op string) (map[s
if strings.HasSuffix(op, PutObjectTaggingOperation) || strings.HasSuffix(op, PutBucketTaggingOperation) { if strings.HasSuffix(op, PutObjectTaggingOperation) || strings.HasSuffix(op, PutBucketTaggingOperation) {
tagging := new(data.Tagging) tagging := new(data.Tagging)
if err := decoder.NewXMLDecoder(r.Body).Decode(tagging); err != nil { if err := decoder.NewXMLDecoder(r.Body).Decode(tagging); err != nil {
return nil, fmt.Errorf("%w: %s", apiErr.GetAPIError(apiErr.ErrMalformedXML), err.Error()) return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error())
} }
GetReqInfo(r.Context()).Tagging = tagging GetReqInfo(r.Context()).Tagging = tagging
@ -473,7 +473,7 @@ func determineRequestTags(r *http.Request, decoder XMLDecoder, op string) (map[s
if tagging := r.Header.Get(amzTagging); len(tagging) > 0 { if tagging := r.Header.Get(amzTagging); len(tagging) > 0 {
queries, err := url.ParseQuery(tagging) queries, err := url.ParseQuery(tagging)
if err != nil { if err != nil {
return nil, apiErr.GetAPIError(apiErr.ErrInvalidArgument) return nil, apierr.GetAPIError(apierr.ErrInvalidArgument)
} }
for key := range queries { for key := range queries {
tags[fmt.Sprintf(s3.PropertyKeyFormatRequestTag, key)] = queries.Get(key) tags[fmt.Sprintf(s3.PropertyKeyFormatRequestTag, key)] = queries.Get(key)

View file

@ -62,7 +62,7 @@ const (
hdrSSE = "X-Amz-Server-Side-Encryption" hdrSSE = "X-Amz-Server-Side-Encryption"
// hdrSSECustomerKey is the HTTP header key referencing the // hdrSSECustomerKey is the HTTP header key referencing the
// SSE-C client-provided key.. // SSE-C client-provided key.
hdrSSECustomerKey = hdrSSE + "-Customer-Key" hdrSSECustomerKey = hdrSSE + "-Customer-Key"
// hdrSSECopyKey is the HTTP header key referencing the SSE-C // hdrSSECopyKey is the HTTP header key referencing the SSE-C
@ -74,7 +74,7 @@ var (
xmlHeader = []byte(xml.Header) xmlHeader = []byte(xml.Header)
) )
// Non exhaustive list of AWS S3 standard error responses - // Non-exhaustive list of AWS S3 standard error responses -
// http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html // http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
var s3ErrorResponseMap = map[string]string{ var s3ErrorResponseMap = map[string]string{
"AccessDenied": "Access Denied.", "AccessDenied": "Access Denied.",

View file

@ -10,7 +10,7 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
@ -159,14 +159,14 @@ type resourceTaggingMock struct {
func (m *resourceTaggingMock) GetBucketTagging(context.Context, *data.BucketInfo) (map[string]string, error) { func (m *resourceTaggingMock) GetBucketTagging(context.Context, *data.BucketInfo) (map[string]string, error) {
if m.noSuchBucketKey { if m.noSuchBucketKey {
return nil, apiErrors.GetAPIError(apiErrors.ErrNoSuchKey) return nil, apierr.GetAPIError(apierr.ErrNoSuchKey)
} }
return m.bucketTags, nil return m.bucketTags, nil
} }
func (m *resourceTaggingMock) GetObjectTagging(context.Context, *data.GetObjectTaggingParams) (string, map[string]string, error) { func (m *resourceTaggingMock) GetObjectTagging(context.Context, *data.GetObjectTaggingParams) (string, map[string]string, error) {
if m.noSuchObjectKey { if m.noSuchObjectKey {
return "", nil, apiErrors.GetAPIError(apiErrors.ErrNoSuchKey) return "", nil, apierr.GetAPIError(apierr.ErrNoSuchKey)
} }
return "", m.objectTags, nil return "", m.objectTags, nil
} }
@ -573,7 +573,7 @@ func (h *handlerMock) ResolveBucket(ctx context.Context, name string) (*data.Buc
reqInfo := middleware.GetReqInfo(ctx) reqInfo := middleware.GetReqInfo(ctx)
bktInfo, ok := h.buckets[reqInfo.Namespace+name] bktInfo, ok := h.buckets[reqInfo.Namespace+name]
if !ok { if !ok {
return nil, apiErrors.GetAPIError(apiErrors.ErrNoSuchBucket) return nil, apierr.GetAPIError(apierr.ErrNoSuchBucket)
} }
return bktInfo, nil return bktInfo, nil
} }

View file

@ -14,7 +14,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
@ -214,18 +214,18 @@ func TestPolicyChecker(t *testing.T) {
deleteObject(chiRouter, ns2, bktName2, objName2, nil) deleteObject(chiRouter, ns2, bktName2, objName2, nil)
// check we cannot access 'bucket' in custom namespace // check we cannot access 'bucket' in custom namespace
putObjectErr(chiRouter, ns2, bktName1, objName2, nil, apiErrors.ErrAccessDenied) putObjectErr(chiRouter, ns2, bktName1, objName2, nil, apierr.ErrAccessDenied)
deleteObjectErr(chiRouter, ns2, bktName1, objName2, nil, apiErrors.ErrAccessDenied) deleteObjectErr(chiRouter, ns2, bktName1, objName2, nil, apierr.ErrAccessDenied)
} }
func TestPolicyCheckerError(t *testing.T) { func TestPolicyCheckerError(t *testing.T) {
chiRouter := prepareRouter(t) chiRouter := prepareRouter(t)
ns1, bktName1, objName1 := "", "bucket", "object" ns1, bktName1, objName1 := "", "bucket", "object"
putObjectErr(chiRouter, ns1, bktName1, objName1, nil, apiErrors.ErrNoSuchBucket) putObjectErr(chiRouter, ns1, bktName1, objName1, nil, apierr.ErrNoSuchBucket)
chiRouter = prepareRouter(t) chiRouter = prepareRouter(t)
chiRouter.cfg.FrostfsID.(*frostFSIDMock).userGroupsError = true chiRouter.cfg.FrostfsID.(*frostFSIDMock).userGroupsError = true
putObjectErr(chiRouter, ns1, bktName1, objName1, nil, apiErrors.ErrInternalError) putObjectErr(chiRouter, ns1, bktName1, objName1, nil, apierr.ErrInternalError)
} }
func TestPolicyCheckerReqTypeDetermination(t *testing.T) { func TestPolicyCheckerReqTypeDetermination(t *testing.T) {
@ -283,7 +283,7 @@ func TestDefaultBehaviorPolicyChecker(t *testing.T) {
// check we cannot access if rules not found when settings is enabled // check we cannot access if rules not found when settings is enabled
chiRouter.middlewareSettings.denyByDefault = true chiRouter.middlewareSettings.denyByDefault = true
createBucketErr(chiRouter, ns, bktName, nil, apiErrors.ErrAccessDenied) createBucketErr(chiRouter, ns, bktName, nil, apierr.ErrAccessDenied)
} }
func TestDefaultPolicyCheckerWithUserTags(t *testing.T) { func TestDefaultPolicyCheckerWithUserTags(t *testing.T) {
@ -294,7 +294,7 @@ func TestDefaultPolicyCheckerWithUserTags(t *testing.T) {
allowOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{ allowOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{
engineiam.CondStringEquals: engineiam.Condition{fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "tag-test"): []string{"test"}}, engineiam.CondStringEquals: engineiam.Condition{fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "tag-test"): []string{"test"}},
}) })
createBucketErr(router, ns, bktName, nil, apiErrors.ErrAccessDenied) createBucketErr(router, ns, bktName, nil, apierr.ErrAccessDenied)
tags := make(map[string]string) tags := make(map[string]string)
tags["tag-test"] = "test" tags["tag-test"] = "test"
@ -321,8 +321,8 @@ func TestRequestParametersCheck(t *testing.T) {
}) })
listObjectsV1(router, ns, bktName, prefix, "", "") listObjectsV1(router, ns, bktName, prefix, "", "")
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", "", apierr.ErrAccessDenied)
listObjectsV1Err(router, ns, bktName, "invalid", "", "", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "invalid", "", "", apierr.ErrAccessDenied)
}) })
t.Run("delimiter parameter, prohibit specific value", func(t *testing.T) { t.Run("delimiter parameter, prohibit specific value", func(t *testing.T) {
@ -344,7 +344,7 @@ func TestRequestParametersCheck(t *testing.T) {
listObjectsV1(router, ns, bktName, "", "", "") listObjectsV1(router, ns, bktName, "", "", "")
listObjectsV1(router, ns, bktName, "", "some-delimiter", "") listObjectsV1(router, ns, bktName, "", "some-delimiter", "")
listObjectsV1Err(router, ns, bktName, "", delimiter, "", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", delimiter, "", apierr.ErrAccessDenied)
}) })
t.Run("max-keys parameter, allow specific value", func(t *testing.T) { t.Run("max-keys parameter, allow specific value", func(t *testing.T) {
@ -365,9 +365,9 @@ func TestRequestParametersCheck(t *testing.T) {
}) })
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys)) listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys))
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", "", apierr.ErrAccessDenied)
listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1), apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1), apierr.ErrAccessDenied)
listObjectsV1Err(router, ns, bktName, "", "", "invalid", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", "invalid", apierr.ErrAccessDenied)
}) })
t.Run("max-keys parameter, allow range of values", func(t *testing.T) { t.Run("max-keys parameter, allow range of values", func(t *testing.T) {
@ -389,7 +389,7 @@ func TestRequestParametersCheck(t *testing.T) {
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys)) listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys))
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1)) listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1))
listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys+1), apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys+1), apierr.ErrAccessDenied)
}) })
t.Run("max-keys parameter, prohibit specific value", func(t *testing.T) { t.Run("max-keys parameter, prohibit specific value", func(t *testing.T) {
@ -411,7 +411,7 @@ func TestRequestParametersCheck(t *testing.T) {
listObjectsV1(router, ns, bktName, "", "", "") listObjectsV1(router, ns, bktName, "", "", "")
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1)) listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1))
listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys), apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys), apierr.ErrAccessDenied)
}) })
} }
@ -439,10 +439,10 @@ func TestRequestTagsCheck(t *testing.T) {
tagging, err = xml.Marshal(data.Tagging{TagSet: []data.Tag{{Key: "key", Value: tagValue}}}) tagging, err = xml.Marshal(data.Tagging{TagSet: []data.Tag{{Key: "key", Value: tagValue}}})
require.NoError(t, err) require.NoError(t, err)
putBucketTaggingErr(router, ns, bktName, tagging, apiErrors.ErrAccessDenied) putBucketTaggingErr(router, ns, bktName, tagging, apierr.ErrAccessDenied)
tagging = nil tagging = nil
putBucketTaggingErr(router, ns, bktName, tagging, apiErrors.ErrMalformedXML) putBucketTaggingErr(router, ns, bktName, tagging, apierr.ErrMalformedXML)
}) })
t.Run("put object with tag", func(t *testing.T) { t.Run("put object with tag", func(t *testing.T) {
@ -464,7 +464,7 @@ func TestRequestTagsCheck(t *testing.T) {
putObject(router, ns, bktName, objName, &data.Tag{Key: tagKey, Value: tagValue}) putObject(router, ns, bktName, objName, &data.Tag{Key: tagKey, Value: tagValue})
putObjectErr(router, ns, bktName, objName, &data.Tag{Key: "key", Value: tagValue}, apiErrors.ErrAccessDenied) putObjectErr(router, ns, bktName, objName, &data.Tag{Key: "key", Value: tagValue}, apierr.ErrAccessDenied)
}) })
} }
@ -490,7 +490,7 @@ func TestResourceTagsCheck(t *testing.T) {
listObjectsV1(router, ns, bktName, "", "", "") listObjectsV1(router, ns, bktName, "", "", "")
router.cfg.Tagging.(*resourceTaggingMock).bucketTags = map[string]string{} router.cfg.Tagging.(*resourceTaggingMock).bucketTags = map[string]string{}
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", "", apierr.ErrAccessDenied)
}) })
t.Run("object tagging", func(t *testing.T) { t.Run("object tagging", func(t *testing.T) {
@ -515,22 +515,22 @@ func TestResourceTagsCheck(t *testing.T) {
getObject(router, ns, bktName, objName) getObject(router, ns, bktName, objName)
router.cfg.Tagging.(*resourceTaggingMock).objectTags = map[string]string{} router.cfg.Tagging.(*resourceTaggingMock).objectTags = map[string]string{}
getObjectErr(router, ns, bktName, objName, apiErrors.ErrAccessDenied) getObjectErr(router, ns, bktName, objName, apierr.ErrAccessDenied)
}) })
t.Run("non-existent resources", func(t *testing.T) { t.Run("non-existent resources", func(t *testing.T) {
router := prepareRouter(t) router := prepareRouter(t)
ns, bktName, objName := "", "bucket", "object" ns, bktName, objName := "", "bucket", "object"
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrNoSuchBucket) listObjectsV1Err(router, ns, bktName, "", "", "", apierr.ErrNoSuchBucket)
router.cfg.Tagging.(*resourceTaggingMock).noSuchBucketKey = true router.cfg.Tagging.(*resourceTaggingMock).noSuchBucketKey = true
createBucket(router, ns, bktName) createBucket(router, ns, bktName)
getBucketErr(router, ns, bktName, apiErrors.ErrNoSuchKey) getBucketErr(router, ns, bktName, apierr.ErrNoSuchKey)
router.cfg.Tagging.(*resourceTaggingMock).noSuchObjectKey = true router.cfg.Tagging.(*resourceTaggingMock).noSuchObjectKey = true
createBucket(router, ns, bktName) createBucket(router, ns, bktName)
getObjectErr(router, ns, bktName, objName, apiErrors.ErrNoSuchKey) getObjectErr(router, ns, bktName, objName, apierr.ErrNoSuchKey)
}) })
} }
@ -548,7 +548,7 @@ func TestAccessBoxAttributesCheck(t *testing.T) {
engineiam.CondBool: engineiam.Condition{fmt.Sprintf(s3.PropertyKeyFormatAccessBoxAttr, attrKey): []string{attrValue}}, engineiam.CondBool: engineiam.Condition{fmt.Sprintf(s3.PropertyKeyFormatAccessBoxAttr, attrKey): []string{attrValue}},
}) })
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied) listObjectsV1Err(router, ns, bktName, "", "", "", apierr.ErrAccessDenied)
var attr object.Attribute var attr object.Attribute
attr.SetKey(attrKey) attr.SetKey(attrKey)
@ -570,7 +570,7 @@ func TestSourceIPCheck(t *testing.T) {
router.middlewareSettings.sourceIPHeader = hdr router.middlewareSettings.sourceIPHeader = hdr
header := map[string][]string{hdr: {"192.0.3.0"}} header := map[string][]string{hdr: {"192.0.3.0"}}
createBucketErr(router, ns, bktName, header, apiErrors.ErrAccessDenied) createBucketErr(router, ns, bktName, header, apierr.ErrAccessDenied)
router.middlewareSettings.sourceIPHeader = "" router.middlewareSettings.sourceIPHeader = ""
createBucket(router, ns, bktName) createBucket(router, ns, bktName)
@ -586,7 +586,7 @@ func TestMFAPolicy(t *testing.T) {
denyOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{ denyOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{
engineiam.CondBool: engineiam.Condition{s3.PropertyKeyAccessBoxAttrMFA: []string{"false"}}, engineiam.CondBool: engineiam.Condition{s3.PropertyKeyAccessBoxAttrMFA: []string{"false"}},
}) })
createBucketErr(router, ns, bktName, nil, apiErrors.ErrAccessDenied) createBucketErr(router, ns, bktName, nil, apierr.ErrAccessDenied)
var attr object.Attribute var attr object.Attribute
attr.SetKey("IAM-MFA") attr.SetKey("IAM-MFA")
@ -630,7 +630,7 @@ func createBucket(router *routerMock, namespace, bktName string) {
require.Equal(router.t, s3middleware.CreateBucketOperation, resp.Method) require.Equal(router.t, s3middleware.CreateBucketOperation, resp.Method)
} }
func createBucketErr(router *routerMock, namespace, bktName string, header http.Header, errCode apiErrors.ErrorCode) { func createBucketErr(router *routerMock, namespace, bktName string, header http.Header, errCode apierr.ErrorCode) {
w := createBucketBase(router, namespace, bktName, header) w := createBucketBase(router, namespace, bktName, header)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -646,7 +646,7 @@ func createBucketBase(router *routerMock, namespace, bktName string, header http
return w return w
} }
func getBucketErr(router *routerMock, namespace, bktName string, errCode apiErrors.ErrorCode) { func getBucketErr(router *routerMock, namespace, bktName string, errCode apierr.ErrorCode) {
w := getBucketBase(router, namespace, bktName) w := getBucketBase(router, namespace, bktName)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -665,7 +665,7 @@ func putObject(router *routerMock, namespace, bktName, objName string, tag *data
return resp return resp
} }
func putObjectErr(router *routerMock, namespace, bktName, objName string, tag *data.Tag, errCode apiErrors.ErrorCode) { func putObjectErr(router *routerMock, namespace, bktName, objName string, tag *data.Tag, errCode apierr.ErrorCode) {
w := putObjectBase(router, namespace, bktName, objName, tag) w := putObjectBase(router, namespace, bktName, objName, tag)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -690,7 +690,7 @@ func deleteObject(router *routerMock, namespace, bktName, objName string, tag *d
return resp return resp
} }
func deleteObjectErr(router *routerMock, namespace, bktName, objName string, tag *data.Tag, errCode apiErrors.ErrorCode) { func deleteObjectErr(router *routerMock, namespace, bktName, objName string, tag *data.Tag, errCode apierr.ErrorCode) {
w := deleteObjectBase(router, namespace, bktName, objName, tag) w := deleteObjectBase(router, namespace, bktName, objName, tag)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -715,7 +715,7 @@ func putBucketTagging(router *routerMock, namespace, bktName string, tagging []b
return resp return resp
} }
func putBucketTaggingErr(router *routerMock, namespace, bktName string, tagging []byte, errCode apiErrors.ErrorCode) { func putBucketTaggingErr(router *routerMock, namespace, bktName string, tagging []byte, errCode apierr.ErrorCode) {
w := putBucketTaggingBase(router, namespace, bktName, tagging) w := putBucketTaggingBase(router, namespace, bktName, tagging)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -738,7 +738,7 @@ func getObject(router *routerMock, namespace, bktName, objName string) handlerRe
return resp return resp
} }
func getObjectErr(router *routerMock, namespace, bktName, objName string, errCode apiErrors.ErrorCode) { func getObjectErr(router *routerMock, namespace, bktName, objName string, errCode apierr.ErrorCode) {
w := getObjectBase(router, namespace, bktName, objName) w := getObjectBase(router, namespace, bktName, objName)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -757,7 +757,7 @@ func listObjectsV1(router *routerMock, namespace, bktName, prefix, delimiter, ma
return resp return resp
} }
func listObjectsV1Err(router *routerMock, namespace, bktName, prefix, delimiter, maxKeys string, errCode apiErrors.ErrorCode) { func listObjectsV1Err(router *routerMock, namespace, bktName, prefix, delimiter, maxKeys string, errCode apierr.ErrorCode) {
w := listObjectsV1Base(router, namespace, bktName, prefix, delimiter, maxKeys) w := listObjectsV1Base(router, namespace, bktName, prefix, delimiter, maxKeys)
assertAPIError(router.t, w, errCode) assertAPIError(router.t, w, errCode)
} }
@ -827,7 +827,7 @@ func TestAuthenticate(t *testing.T) {
chiRouter = prepareRouter(t) chiRouter = prepareRouter(t)
chiRouter.cfg.Center.(*centerMock).isError = true chiRouter.cfg.Center.(*centerMock).isError = true
createBucketErr(chiRouter, "", "bkt-3", nil, apiErrors.ErrAccessDenied) createBucketErr(chiRouter, "", "bkt-3", nil, apierr.ErrAccessDenied)
} }
func TestFrostFSIDValidation(t *testing.T) { func TestFrostFSIDValidation(t *testing.T) {
@ -843,7 +843,7 @@ func TestFrostFSIDValidation(t *testing.T) {
// frostFSID validation failed // frostFSID validation failed
chiRouter = prepareRouter(t, frostFSIDValidation(true)) chiRouter = prepareRouter(t, frostFSIDValidation(true))
chiRouter.cfg.FrostfsID.(*frostFSIDMock).validateError = true chiRouter.cfg.FrostfsID.(*frostFSIDMock).validateError = true
createBucketErr(chiRouter, "", "bkt-3", nil, apiErrors.ErrInternalError) createBucketErr(chiRouter, "", "bkt-3", nil, apierr.ErrInternalError)
} }
func TestRouterListObjectsV2Domains(t *testing.T) { func TestRouterListObjectsV2Domains(t *testing.T) {
@ -882,17 +882,17 @@ func readResponse(t *testing.T, w *httptest.ResponseRecorder) handlerResult {
return res return res
} }
func assertAPIError(t *testing.T, w *httptest.ResponseRecorder, expectedErrorCode apiErrors.ErrorCode) { func assertAPIError(t *testing.T, w *httptest.ResponseRecorder, expectedErrorCode apierr.ErrorCode) {
actualErrorResponse := &s3middleware.ErrorResponse{} actualErrorResponse := &s3middleware.ErrorResponse{}
err := xml.NewDecoder(w.Result().Body).Decode(actualErrorResponse) err := xml.NewDecoder(w.Result().Body).Decode(actualErrorResponse)
require.NoError(t, err) require.NoError(t, err)
expectedError := apiErrors.GetAPIError(expectedErrorCode) expectedError := apierr.GetAPIError(expectedErrorCode)
require.Equal(t, expectedError.HTTPStatusCode, w.Code) require.Equal(t, expectedError.HTTPStatusCode, w.Code)
require.Equal(t, expectedError.Code, actualErrorResponse.Code) require.Equal(t, expectedError.Code, actualErrorResponse.Code)
if expectedError.ErrCode != apiErrors.ErrInternalError { if expectedError.ErrCode != apierr.ErrInternalError {
require.Contains(t, actualErrorResponse.Message, expectedError.Description) require.Contains(t, actualErrorResponse.Message, expectedError.Description)
} }
} }

View file

@ -11,7 +11,7 @@ import (
objectv2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" objectv2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
errorsFrost "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
@ -466,11 +466,11 @@ func handleObjectError(msg string, err error) error {
return nil return nil
} }
if reason, ok := errorsFrost.IsErrObjectAccessDenied(err); ok { if reason, ok := frosterr.IsErrObjectAccessDenied(err); ok {
return fmt.Errorf("%s: %w: %s", msg, frostfs.ErrAccessDenied, reason) return fmt.Errorf("%s: %w: %s", msg, frostfs.ErrAccessDenied, reason)
} }
if errorsFrost.IsTimeoutError(err) { if frosterr.IsTimeoutError(err) {
return fmt.Errorf("%s: %w: %s", msg, frostfs.ErrGatewayTimeout, err.Error()) return fmt.Errorf("%s: %w: %s", msg, frostfs.ErrGatewayTimeout, err.Error())
} }

View file

@ -8,7 +8,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
errorsFrost "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
@ -22,7 +22,7 @@ func TestErrorChecking(t *testing.T) {
var wrappedError error var wrappedError error
if fetchedReason, ok := errorsFrost.IsErrObjectAccessDenied(err); ok { if fetchedReason, ok := frosterr.IsErrObjectAccessDenied(err); ok {
wrappedError = fmt.Errorf("%w: %s", frostfs.ErrAccessDenied, fetchedReason) wrappedError = fmt.Errorf("%w: %s", frostfs.ErrAccessDenied, fetchedReason)
} }
@ -32,7 +32,7 @@ func TestErrorChecking(t *testing.T) {
func TestErrorTimeoutChecking(t *testing.T) { func TestErrorTimeoutChecking(t *testing.T) {
t.Run("simple timeout", func(t *testing.T) { t.Run("simple timeout", func(t *testing.T) {
require.True(t, errorsFrost.IsTimeoutError(errors.New("timeout"))) require.True(t, frosterr.IsTimeoutError(errors.New("timeout")))
}) })
t.Run("deadline exceeded", func(t *testing.T) { t.Run("deadline exceeded", func(t *testing.T) {
@ -40,11 +40,11 @@ func TestErrorTimeoutChecking(t *testing.T) {
defer cancel() defer cancel()
<-ctx.Done() <-ctx.Done()
require.True(t, errorsFrost.IsTimeoutError(ctx.Err())) require.True(t, frosterr.IsTimeoutError(ctx.Err()))
}) })
t.Run("grpc deadline exceeded", func(t *testing.T) { t.Run("grpc deadline exceeded", func(t *testing.T) {
err := fmt.Errorf("wrap grpc error: %w", status.Error(codes.DeadlineExceeded, "error")) err := fmt.Errorf("wrap grpc error: %w", status.Error(codes.DeadlineExceeded, "error"))
require.True(t, errorsFrost.IsTimeoutError(err)) require.True(t, frosterr.IsTimeoutError(err))
}) })
} }

View file

@ -8,15 +8,15 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
errorsFrost "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/tree" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/tree"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
treepool "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool/tree" treepool "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool/tree"
grpcService "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool/tree/service" grpcservice "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool/tree/service"
) )
type GetNodeByPathResponseInfoWrapper struct { type GetNodeByPathResponseInfoWrapper struct {
response *grpcService.GetNodeByPathResponse_Info response *grpcservice.GetNodeByPathResponse_Info
} }
func (n GetNodeByPathResponseInfoWrapper) GetNodeID() []uint64 { func (n GetNodeByPathResponseInfoWrapper) GetNodeID() []uint64 {
@ -40,7 +40,7 @@ func (n GetNodeByPathResponseInfoWrapper) GetMeta() []tree.Meta {
} }
type GetSubTreeResponseBodyWrapper struct { type GetSubTreeResponseBodyWrapper struct {
response *grpcService.GetSubTreeResponse_Body response *grpcservice.GetSubTreeResponse_Body
} }
func (n GetSubTreeResponseBodyWrapper) GetNodeID() []uint64 { func (n GetSubTreeResponseBodyWrapper) GetNodeID() []uint64 {
@ -144,7 +144,7 @@ func (w *PoolWrapper) GetSubTree(ctx context.Context, bktInfo *data.BucketInfo,
type SubTreeStreamImpl struct { type SubTreeStreamImpl struct {
r *treepool.SubTreeReader r *treepool.SubTreeReader
buffer []*grpcService.GetSubTreeResponse_Body buffer []*grpcservice.GetSubTreeResponse_Body
eof bool eof bool
index int index int
ln int ln int
@ -204,7 +204,7 @@ func (w *PoolWrapper) GetSubTreeStream(ctx context.Context, bktInfo *data.Bucket
return &SubTreeStreamImpl{ return &SubTreeStreamImpl{
r: subTreeReader, r: subTreeReader,
buffer: make([]*grpcService.GetSubTreeResponse_Body, bufSize), buffer: make([]*grpcservice.GetSubTreeResponse_Body, bufSize),
index: -1, index: -1,
}, nil }, nil
} }
@ -273,7 +273,7 @@ func handleError(err error) error {
if errors.Is(err, treepool.ErrNodeAccessDenied) { if errors.Is(err, treepool.ErrNodeAccessDenied) {
return fmt.Errorf("%w: %s", tree.ErrNodeAccessDenied, err.Error()) return fmt.Errorf("%w: %s", tree.ErrNodeAccessDenied, err.Error())
} }
if errorsFrost.IsTimeoutError(err) { if frosterr.IsTimeoutError(err) {
return fmt.Errorf("%w: %s", tree.ErrGatewayTimeout, err.Error()) return fmt.Errorf("%w: %s", tree.ErrGatewayTimeout, err.Error())
} }

View file

@ -978,7 +978,7 @@ func (s *VersionsByPrefixStreamImpl) getNodeFromMainStream() (NodeResponse, erro
for { for {
node, err := s.mainStream.Next() node, err := s.mainStream.Next()
if err != nil { if err != nil {
if errors.Is(err, ErrNodeNotFound) { if errors.Is(err, tree.ErrNodeNotFound) {
return nil, io.EOF return nil, io.EOF
} }
return nil, fmt.Errorf("main stream next: %w", err) return nil, fmt.Errorf("main stream next: %w", err)

View file

@ -9,6 +9,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -242,7 +243,7 @@ func (c *ServiceClientMemory) GetSubTree(_ context.Context, bktInfo *data.Bucket
tr, ok := cnr.trees[treeID] tr, ok := cnr.trees[treeID]
if !ok { if !ok {
return nil, ErrNodeNotFound return nil, tree.ErrNodeNotFound
} }
if len(rootID) != 1 { if len(rootID) != 1 {
@ -251,7 +252,7 @@ func (c *ServiceClientMemory) GetSubTree(_ context.Context, bktInfo *data.Bucket
node := tr.treeData.getNode(rootID[0]) node := tr.treeData.getNode(rootID[0])
if node == nil { if node == nil {
return nil, ErrNodeNotFound return nil, tree.ErrNodeNotFound
} }
if sort { if sort {
@ -282,12 +283,12 @@ func (s *SubTreeStreamMemoryImpl) Next() (NodeResponse, error) {
func (c *ServiceClientMemory) GetSubTreeStream(_ context.Context, bktInfo *data.BucketInfo, treeID string, rootID []uint64, depth uint32) (SubTreeStream, error) { func (c *ServiceClientMemory) GetSubTreeStream(_ context.Context, bktInfo *data.BucketInfo, treeID string, rootID []uint64, depth uint32) (SubTreeStream, error) {
cnr, ok := c.containers[bktInfo.CID.EncodeToString()] cnr, ok := c.containers[bktInfo.CID.EncodeToString()]
if !ok { if !ok {
return &SubTreeStreamMemoryImpl{err: ErrNodeNotFound}, nil return &SubTreeStreamMemoryImpl{err: tree.ErrNodeNotFound}, nil
} }
tr, ok := cnr.trees[treeID] tr, ok := cnr.trees[treeID]
if !ok { if !ok {
return nil, ErrNodeNotFound return nil, tree.ErrNodeNotFound
} }
if len(rootID) != 1 { if len(rootID) != 1 {
@ -296,7 +297,7 @@ func (c *ServiceClientMemory) GetSubTreeStream(_ context.Context, bktInfo *data.
node := tr.treeData.getNode(rootID[0]) node := tr.treeData.getNode(rootID[0])
if node == nil { if node == nil {
return nil, ErrNodeNotFound return nil, tree.ErrNodeNotFound
} }
sortNode(tr.treeData) sortNode(tr.treeData)
@ -353,7 +354,7 @@ func (c *ServiceClientMemory) AddNodeBase(_ context.Context, bktInfo *data.Bucke
parentNode := tr.treeData.getNode(parent) parentNode := tr.treeData.getNode(parent)
if parentNode == nil { if parentNode == nil {
return 0, ErrNodeNotFound return 0, tree.ErrNodeNotFound
} }
newID := tr.idCounter newID := tr.idCounter
@ -418,22 +419,22 @@ func (c *ServiceClientMemory) AddNodeByPath(_ context.Context, bktInfo *data.Buc
func (c *ServiceClientMemory) MoveNode(_ context.Context, bktInfo *data.BucketInfo, treeID string, nodeID, parentID uint64, meta map[string]string) error { func (c *ServiceClientMemory) MoveNode(_ context.Context, bktInfo *data.BucketInfo, treeID string, nodeID, parentID uint64, meta map[string]string) error {
cnr, ok := c.containers[bktInfo.CID.EncodeToString()] cnr, ok := c.containers[bktInfo.CID.EncodeToString()]
if !ok { if !ok {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
tr, ok := cnr.trees[treeID] tr, ok := cnr.trees[treeID]
if !ok { if !ok {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
node := tr.treeData.getNode(nodeID) node := tr.treeData.getNode(nodeID)
if node == nil { if node == nil {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
newParent := tr.treeData.getNode(parentID) newParent := tr.treeData.getNode(parentID)
if newParent == nil { if newParent == nil {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
node.data.meta = metaToNodeMeta(meta) node.data.meta = metaToNodeMeta(meta)
@ -466,17 +467,17 @@ func sortNodes(list []*treeNodeMemory) {
func (c *ServiceClientMemory) RemoveNode(_ context.Context, bktInfo *data.BucketInfo, treeID string, nodeID uint64) error { func (c *ServiceClientMemory) RemoveNode(_ context.Context, bktInfo *data.BucketInfo, treeID string, nodeID uint64) error {
cnr, ok := c.containers[bktInfo.CID.EncodeToString()] cnr, ok := c.containers[bktInfo.CID.EncodeToString()]
if !ok { if !ok {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
tr, ok := cnr.trees[treeID] tr, ok := cnr.trees[treeID]
if !ok { if !ok {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
node := tr.treeData.getNode(nodeID) node := tr.treeData.getNode(nodeID)
if node == nil { if node == nil {
return ErrNodeNotFound return tree.ErrNodeNotFound
} }
node.parent.removeChild(nodeID) node.parent.removeChild(nodeID)