feature/501-add_trace_id_to_logs_of_erroneous_requests_at_middleware #525

24 changed files with 456 additions and 437 deletions

View file

@ -52,18 +52,18 @@ func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get bucket settings", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, h.encodeBucketCannedACL(ctx, bktInfo, settings)); err != nil { if err = middleware.EncodeToResponse(w, h.encodeBucketCannedACL(ctx, bktInfo, settings)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
} }
@ -127,17 +127,18 @@ func getTokenIssuerKey(box *accessbox.Box) (*keys.PublicKey, error) {
} }
func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get bucket settings", reqInfo, err)
return return
} }
@ -149,30 +150,30 @@ func (h *handler) putBucketACLAPEHandler(w http.ResponseWriter, r *http.Request,
defer func() { defer func() {
if errBody := r.Body.Close(); errBody != nil { if errBody := r.Body.Close(); errBody != nil {
h.reqLogger(r.Context()).Warn(logs.CouldNotCloseRequestBody, zap.Error(errBody)) h.reqLogger(ctx).Warn(logs.CouldNotCloseRequestBody, zap.Error(errBody))
} }
}() }()
written, err := io.Copy(io.Discard, r.Body) written, err := io.Copy(io.Discard, r.Body)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't read request body", reqInfo, err) h.logAndSendError(ctx, w, "couldn't read request body", reqInfo, err)
return return
} }
if written != 0 || len(r.Header.Get(api.AmzACL)) == 0 { if written != 0 || len(r.Header.Get(api.AmzACL)) == 0 {
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported)) h.logAndSendError(ctx, w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported))
return return
} }
cannedACL, err := parseCannedACL(r.Header) cannedACL, err := parseCannedACL(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse canned ACL", reqInfo, err) h.logAndSendError(ctx, w, "could not parse canned ACL", reqInfo, err)
return return
} }
chainRules := bucketCannedACLToAPERules(cannedACL, reqInfo, bktInfo.CID) chainRules := bucketCannedACLToAPERules(cannedACL, reqInfo, bktInfo.CID)
if err = h.ape.SaveACLChains(bktInfo.CID.EncodeToString(), chainRules); err != nil { if err = h.ape.SaveACLChains(bktInfo.CID.EncodeToString(), chainRules); err != nil {
h.logAndSendError(w, "failed to add morph rule chains", reqInfo, err) h.logAndSendError(ctx, w, "failed to add morph rule chains", reqInfo, err)
return return
} }
@ -184,7 +185,7 @@ func (h *handler) putBucketACLAPEHandler(w http.ResponseWriter, r *http.Request,
} }
if err = h.obj.PutBucketSettings(ctx, sp); err != nil { if err = h.obj.PutBucketSettings(ctx, sp); err != nil {
h.logAndSendError(w, "couldn't save bucket settings", reqInfo, err, h.logAndSendError(ctx, w, "couldn't save bucket settings", reqInfo, err,
zap.String("container_id", bktInfo.CID.EncodeToString())) zap.String("container_id", bktInfo.CID.EncodeToString()))
return return
} }
@ -198,18 +199,18 @@ func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get bucket settings", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, h.encodePrivateCannedACL(ctx, bktInfo, settings)); err != nil { if err = middleware.EncodeToResponse(w, h.encodePrivateCannedACL(ctx, bktInfo, settings)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
} }
@ -219,19 +220,20 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(ctx) reqInfo := middleware.GetReqInfo(ctx)
if _, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil { if _, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported)) h.logAndSendError(ctx, w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported))
} }
func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -240,13 +242,13 @@ func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Re
if strings.Contains(err.Error(), "not found") { if strings.Contains(err.Error(), "not found") {
err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error()) err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error())
} }
h.logAndSendError(w, "failed to get policy from storage", reqInfo, err) h.logAndSendError(ctx, w, "failed to get policy from storage", reqInfo, err)
return return
} }
var bktPolicy engineiam.Policy var bktPolicy engineiam.Policy
if err = json.Unmarshal(jsonPolicy, &bktPolicy); err != nil { if err = json.Unmarshal(jsonPolicy, &bktPolicy); err != nil {
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err) h.logAndSendError(ctx, w, "could not parse bucket policy", reqInfo, err)
return return
} }
@ -263,17 +265,18 @@ func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Re
} }
if err = middleware.EncodeToResponse(w, policyStatus); err != nil { if err = middleware.EncodeToResponse(w, policyStatus); err != nil {
h.logAndSendError(w, "encode and write response", reqInfo, err) h.logAndSendError(ctx, w, "encode and write response", reqInfo, err)
return return
} }
} }
func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -282,7 +285,7 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
if strings.Contains(err.Error(), "not found") { if strings.Contains(err.Error(), "not found") {
err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error()) err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error())
} }
h.logAndSendError(w, "failed to get policy from storage", reqInfo, err) h.logAndSendError(ctx, w, "failed to get policy from storage", reqInfo, err)
return return
} }
@ -290,22 +293,23 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
if _, err = w.Write(jsonPolicy); err != nil { if _, err = w.Write(jsonPolicy); err != nil {
h.logAndSendError(w, "write json policy to client", reqInfo, err) h.logAndSendError(ctx, w, "write json policy to client", reqInfo, err)
} }
} }
func (h *handler) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
chainIDs := []chain.ID{getBucketChainID(chain.S3, bktInfo), getBucketChainID(chain.Ingress, bktInfo)} chainIDs := []chain.ID{getBucketChainID(chain.S3, bktInfo), getBucketChainID(chain.Ingress, bktInfo)}
if err = h.ape.DeleteBucketPolicy(reqInfo.Namespace, bktInfo.CID, chainIDs); err != nil { if err = h.ape.DeleteBucketPolicy(reqInfo.Namespace, bktInfo.CID, chainIDs); err != nil {
h.logAndSendError(w, "failed to delete policy from storage", reqInfo, err) h.logAndSendError(ctx, w, "failed to delete policy from storage", reqInfo, err)
return return
} }
} }
@ -324,40 +328,41 @@ func checkOwner(info *data.BucketInfo, owner string) error {
} }
func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
jsonPolicy, err := io.ReadAll(r.Body) jsonPolicy, err := io.ReadAll(r.Body)
if err != nil { if err != nil {
h.logAndSendError(w, "read body", reqInfo, err) h.logAndSendError(ctx, w, "read body", reqInfo, err)
return return
} }
var bktPolicy engineiam.Policy var bktPolicy engineiam.Policy
if err = json.Unmarshal(jsonPolicy, &bktPolicy); err != nil { if err = json.Unmarshal(jsonPolicy, &bktPolicy); err != nil {
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err) h.logAndSendError(ctx, w, "could not parse bucket policy", reqInfo, err)
return return
} }
for _, stat := range bktPolicy.Statement { for _, stat := range bktPolicy.Statement {
if len(stat.NotResource) != 0 { if len(stat.NotResource) != 0 {
h.logAndSendError(w, "policy resource mismatched bucket", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicy)) h.logAndSendError(ctx, w, "policy resource mismatched bucket", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicy))
return return
} }
if len(stat.NotPrincipal) != 0 && stat.Effect == engineiam.AllowEffect { if len(stat.NotPrincipal) != 0 && stat.Effect == engineiam.AllowEffect {
h.logAndSendError(w, "invalid NotPrincipal", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicyNotPrincipal)) h.logAndSendError(ctx, w, "invalid NotPrincipal", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicyNotPrincipal))
return return
} }
for _, resource := range stat.Resource { for _, resource := range stat.Resource {
if reqInfo.BucketName != strings.Split(strings.TrimPrefix(resource, arnAwsPrefix), "/")[0] { if reqInfo.BucketName != strings.Split(strings.TrimPrefix(resource, arnAwsPrefix), "/")[0] {
h.logAndSendError(w, "policy resource mismatched bucket", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicy)) h.logAndSendError(ctx, w, "policy resource mismatched bucket", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicy))
return return
} }
} }
@ -365,7 +370,7 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
s3Chain, err := engineiam.ConvertToS3Chain(bktPolicy, h.frostfsid) s3Chain, err := engineiam.ConvertToS3Chain(bktPolicy, h.frostfsid)
if err != nil { if err != nil {
h.logAndSendError(w, "could not convert s3 policy to chain policy", reqInfo, err) h.logAndSendError(ctx, w, "could not convert s3 policy to chain policy", reqInfo, err)
return return
} }
s3Chain.ID = getBucketChainID(chain.S3, bktInfo) s3Chain.ID = getBucketChainID(chain.S3, bktInfo)
@ -374,10 +379,10 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
if err == nil { if err == nil {
nativeChain.ID = getBucketChainID(chain.Ingress, bktInfo) nativeChain.ID = getBucketChainID(chain.Ingress, bktInfo)
} else if !stderrors.Is(err, engineiam.ErrActionsNotApplicable) { } else if !stderrors.Is(err, engineiam.ErrActionsNotApplicable) {
h.logAndSendError(w, "could not convert s3 policy to native chain policy", reqInfo, err) h.logAndSendError(ctx, w, "could not convert s3 policy to native chain policy", reqInfo, err)
return return
} else { } else {
h.reqLogger(r.Context()).Warn(logs.PolicyCouldntBeConvertedToNativeRules) h.reqLogger(ctx).Warn(logs.PolicyCouldntBeConvertedToNativeRules)
} }
chainsToSave := []*chain.Chain{s3Chain} chainsToSave := []*chain.Chain{s3Chain}
@ -386,7 +391,7 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
} }
if err = h.ape.PutBucketPolicy(reqInfo.Namespace, bktInfo.CID, jsonPolicy, chainsToSave); err != nil { if err = h.ape.PutBucketPolicy(reqInfo.Namespace, bktInfo.CID, jsonPolicy, chainsToSave); err != nil {
h.logAndSendError(w, "failed to update policy in contract", reqInfo, err) h.logAndSendError(ctx, w, "failed to update policy in contract", reqInfo, err)
return return
} }
} }

View file

@ -70,17 +70,18 @@ var validAttributes = map[string]struct{}{
} }
func (h *handler) GetObjectAttributesHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetObjectAttributesHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseGetObjectAttributeArgs(r) params, err := parseGetObjectAttributeArgs(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid request", reqInfo, err) h.logAndSendError(ctx, w, "invalid request", reqInfo, err)
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -90,44 +91,44 @@ func (h *handler) GetObjectAttributesHandler(w http.ResponseWriter, r *http.Requ
VersionID: params.VersionID, VersionID: params.VersionID,
} }
extendedInfo, err := h.obj.GetExtendedObjectInfo(r.Context(), p) extendedInfo, err := h.obj.GetExtendedObjectInfo(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not fetch object info", reqInfo, err) h.logAndSendError(ctx, w, "could not fetch object info", reqInfo, err)
return return
} }
info := extendedInfo.ObjectInfo info := extendedInfo.ObjectInfo
encryptionParams, err := formEncryptionParams(r) encryptionParams, err := formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
if err = encryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(info.Headers)); err != nil { if err = encryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(info.Headers)); err != nil {
h.logAndSendError(w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err)) h.logAndSendError(ctx, w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err))
return return
} }
if err = checkPreconditions(info, params.Conditional, h.cfg.MD5Enabled()); err != nil { if err = checkPreconditions(info, params.Conditional, h.cfg.MD5Enabled()); err != nil {
h.logAndSendError(w, "precondition failed", reqInfo, err) h.logAndSendError(ctx, w, "precondition failed", reqInfo, err)
return return
} }
bktSettings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
response, err := encodeToObjectAttributesResponse(info, params, h.cfg.MD5Enabled()) response, err := encodeToObjectAttributesResponse(info, params, h.cfg.MD5Enabled())
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't encode object info to response", reqInfo, err) h.logAndSendError(ctx, w, "couldn't encode object info to response", reqInfo, err)
return return
} }
writeAttributesHeaders(w.Header(), extendedInfo, bktSettings.Unversioned()) writeAttributesHeaders(w.Header(), extendedInfo, bktSettings.Unversioned())
if err = middleware.EncodeToResponse(w, response); err != nil { if err = middleware.EncodeToResponse(w, response); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }

View file

@ -65,7 +65,7 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
srcBucket, srcObject, err := path2BucketObject(src) srcBucket, srcObject, err := path2BucketObject(src)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid source copy", reqInfo, err) h.logAndSendError(ctx, w, "invalid source copy", reqInfo, err)
return return
} }
@ -75,74 +75,74 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
if srcObjPrm.BktInfo, err = h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner); err != nil { if srcObjPrm.BktInfo, err = h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner); err != nil {
h.logAndSendError(w, "couldn't get source bucket", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get source bucket", reqInfo, err)
return return
} }
dstBktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) dstBktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get target bucket", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get target bucket", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(ctx, dstBktInfo) settings, err := h.obj.GetBucketSettings(ctx, dstBktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
if cannedACLStatus == aclStatusYes { if cannedACLStatus == aclStatusYes {
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported)) h.logAndSendError(ctx, w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported))
return return
} }
extendedSrcObjInfo, err := h.obj.GetExtendedObjectInfo(ctx, srcObjPrm) extendedSrcObjInfo, err := h.obj.GetExtendedObjectInfo(ctx, srcObjPrm)
if err != nil { if err != nil {
h.logAndSendError(w, "could not find object", reqInfo, err) h.logAndSendError(ctx, w, "could not find object", reqInfo, err)
return return
} }
srcObjInfo := extendedSrcObjInfo.ObjectInfo srcObjInfo := extendedSrcObjInfo.ObjectInfo
srcEncryptionParams, err := formCopySourceEncryptionParams(r) srcEncryptionParams, err := formCopySourceEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
dstEncryptionParams, err := formEncryptionParams(r) dstEncryptionParams, err := formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
if err = srcEncryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(srcObjInfo.Headers)); err != nil { if err = srcEncryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(srcObjInfo.Headers)); err != nil {
if errors.IsS3Error(err, errors.ErrInvalidEncryptionParameters) || errors.IsS3Error(err, errors.ErrSSEEncryptedObject) || if errors.IsS3Error(err, errors.ErrInvalidEncryptionParameters) || errors.IsS3Error(err, errors.ErrSSEEncryptedObject) ||
errors.IsS3Error(err, errors.ErrInvalidSSECustomerParameters) { errors.IsS3Error(err, errors.ErrInvalidSSECustomerParameters) {
h.logAndSendError(w, "encryption doesn't match object", reqInfo, err, zap.Error(err)) h.logAndSendError(ctx, w, "encryption doesn't match object", reqInfo, err, zap.Error(err))
return return
} }
h.logAndSendError(w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err)) h.logAndSendError(ctx, w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err))
return return
} }
var dstSize uint64 var dstSize uint64
srcSize, err := layer.GetObjectSize(srcObjInfo) srcSize, err := layer.GetObjectSize(srcObjInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to get source object size", reqInfo, err) h.logAndSendError(ctx, w, "failed to get source object size", reqInfo, err)
return return
} else if srcSize > layer.UploadMaxSize { // https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html } else if srcSize > layer.UploadMaxSize { // https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html
h.logAndSendError(w, "too bid object to copy with single copy operation, use multipart upload copy instead", reqInfo, errors.GetAPIError(errors.ErrInvalidRequestLargeCopy)) h.logAndSendError(ctx, w, "too bid object to copy with single copy operation, use multipart upload copy instead", reqInfo, errors.GetAPIError(errors.ErrInvalidRequestLargeCopy))
return return
} }
dstSize = srcSize dstSize = srcSize
args, err := parseCopyObjectArgs(r.Header) args, err := parseCopyObjectArgs(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse request params", reqInfo, err) h.logAndSendError(ctx, w, "could not parse request params", reqInfo, err)
return return
} }
if isCopyingToItselfForbidden(reqInfo, srcBucket, srcObject, settings, args) { if isCopyingToItselfForbidden(reqInfo, srcBucket, srcObject, settings, args) {
h.logAndSendError(w, "copying to itself without changing anything", reqInfo, errors.GetAPIError(errors.ErrInvalidCopyDest)) h.logAndSendError(ctx, w, "copying to itself without changing anything", reqInfo, errors.GetAPIError(errors.ErrInvalidCopyDest))
return return
} }
@ -153,7 +153,7 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
if args.TaggingDirective == replaceDirective { if args.TaggingDirective == replaceDirective {
tagSet, err = parseTaggingHeader(r.Header) tagSet, err = parseTaggingHeader(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse tagging header", reqInfo, err) h.logAndSendError(ctx, w, "could not parse tagging header", reqInfo, err)
return return
} }
} else { } else {
@ -168,13 +168,13 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
_, tagSet, err = h.obj.GetObjectTagging(ctx, tagPrm) _, tagSet, err = h.obj.GetObjectTagging(ctx, tagPrm)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not get object tagging", reqInfo, err)
return return
} }
} }
if err = checkPreconditions(srcObjInfo, args.Conditional, h.cfg.MD5Enabled()); err != nil { if err = checkPreconditions(srcObjInfo, args.Conditional, h.cfg.MD5Enabled()); err != nil {
h.logAndSendError(w, "precondition failed", reqInfo, errors.GetAPIError(errors.ErrPreconditionFailed)) h.logAndSendError(ctx, w, "precondition failed", reqInfo, errors.GetAPIError(errors.ErrPreconditionFailed))
return return
} }
@ -202,20 +202,20 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
params.CopiesNumbers, err = h.pickCopiesNumbers(metadata, reqInfo.Namespace, dstBktInfo.LocationConstraint) params.CopiesNumbers, err = h.pickCopiesNumbers(metadata, reqInfo.Namespace, dstBktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
params.Lock, err = formObjectLock(ctx, dstBktInfo, settings.LockConfiguration, r.Header) params.Lock, err = formObjectLock(ctx, dstBktInfo, settings.LockConfiguration, r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not form object lock", reqInfo, err) h.logAndSendError(ctx, w, "could not form object lock", reqInfo, err)
return return
} }
additional := []zap.Field{zap.String("src_bucket_name", srcBucket), zap.String("src_object_name", srcObject)} additional := []zap.Field{zap.String("src_bucket_name", srcBucket), zap.String("src_object_name", srcObject)}
extendedDstObjInfo, err := h.obj.CopyObject(ctx, params) extendedDstObjInfo, err := h.obj.CopyObject(ctx, params)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't copy object", reqInfo, err, additional...) h.logAndSendError(ctx, w, "couldn't copy object", reqInfo, err, additional...)
return return
} }
dstObjInfo := extendedDstObjInfo.ObjectInfo dstObjInfo := extendedDstObjInfo.ObjectInfo
@ -224,7 +224,7 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
LastModified: dstObjInfo.Created.UTC().Format(time.RFC3339), LastModified: dstObjInfo.Created.UTC().Format(time.RFC3339),
ETag: data.Quote(dstObjInfo.ETag(h.cfg.MD5Enabled())), ETag: data.Quote(dstObjInfo.ETag(h.cfg.MD5Enabled())),
}); err != nil { }); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err, additional...) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err, additional...)
return return
} }
@ -239,7 +239,7 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
NodeVersion: extendedDstObjInfo.NodeVersion, NodeVersion: extendedDstObjInfo.NodeVersion,
} }
if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil { if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil {
h.logAndSendError(w, "could not upload object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not upload object tagging", reqInfo, err)
return return
} }
} }

View file

@ -20,32 +20,34 @@ const (
) )
func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
cors, err := h.obj.GetBucketCORS(r.Context(), bktInfo) cors, err := h.obj.GetBucketCORS(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get cors", reqInfo, err) h.logAndSendError(ctx, w, "could not get cors", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, cors); err != nil { if err = middleware.EncodeToResponse(w, cors); err != nil {
h.logAndSendError(w, "could not encode cors to response", reqInfo, err) h.logAndSendError(ctx, w, "could not encode cors to response", reqInfo, err)
return return
} }
} }
func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -57,32 +59,33 @@ func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
p.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint) p.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
if err = h.obj.PutBucketCORS(r.Context(), p); err != nil { if err = h.obj.PutBucketCORS(ctx, p); err != nil {
h.logAndSendError(w, "could not put cors configuration", reqInfo, err) h.logAndSendError(ctx, w, "could not put cors configuration", reqInfo, err)
return return
} }
if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil { if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil {
h.logAndSendError(w, "write response", reqInfo, err) h.logAndSendError(ctx, w, "write response", reqInfo, err)
return return
} }
} }
func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if err = h.obj.DeleteBucketCORS(r.Context(), bktInfo); err != nil { if err = h.obj.DeleteBucketCORS(ctx, bktInfo); err != nil {
h.logAndSendError(w, "could not delete cors", reqInfo, err) h.logAndSendError(ctx, w, "could not delete cors", reqInfo, err)
} }
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
@ -149,21 +152,22 @@ func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) {
} }
func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) { func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName) reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.obj.GetBucketInfo(ctx, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
origin := r.Header.Get(api.Origin) origin := r.Header.Get(api.Origin)
if origin == "" { if origin == "" {
h.logAndSendError(w, "origin request header needed", reqInfo, errors.GetAPIError(errors.ErrBadRequest)) h.logAndSendError(ctx, w, "origin request header needed", reqInfo, errors.GetAPIError(errors.ErrBadRequest))
} }
method := r.Header.Get(api.AccessControlRequestMethod) method := r.Header.Get(api.AccessControlRequestMethod)
if method == "" { if method == "" {
h.logAndSendError(w, "Access-Control-Request-Method request header needed", reqInfo, errors.GetAPIError(errors.ErrBadRequest)) h.logAndSendError(ctx, w, "Access-Control-Request-Method request header needed", reqInfo, errors.GetAPIError(errors.ErrBadRequest))
return return
} }
@ -173,9 +177,9 @@ func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) {
headers = strings.Split(requestHeaders, ", ") headers = strings.Split(requestHeaders, ", ")
} }
cors, err := h.obj.GetBucketCORS(r.Context(), bktInfo) cors, err := h.obj.GetBucketCORS(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get cors", reqInfo, err) h.logAndSendError(ctx, w, "could not get cors", reqInfo, err)
return return
} }
@ -204,7 +208,7 @@ func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) {
w.Header().Set(api.AccessControlAllowCredentials, "true") w.Header().Set(api.AccessControlAllowCredentials, "true")
} }
if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil { if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil {
h.logAndSendError(w, "write response", reqInfo, err) h.logAndSendError(ctx, w, "write response", reqInfo, err)
return return
} }
return return
@ -213,7 +217,7 @@ func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) {
} }
} }
} }
h.logAndSendError(w, "Forbidden", reqInfo, errors.GetAPIError(errors.ErrAccessDenied)) h.logAndSendError(ctx, w, "Forbidden", reqInfo, errors.GetAPIError(errors.ErrAccessDenied))
} }
func checkSubslice(slice []string, subSlice []string) bool { func checkSubslice(slice []string, subSlice []string) bool {

View file

@ -71,19 +71,19 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo) bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
networkInfo, err := h.obj.GetNetworkInfo(ctx) networkInfo, err := h.obj.GetNetworkInfo(ctx)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get network info", reqInfo, err) h.logAndSendError(ctx, w, "could not get network info", reqInfo, err)
return return
} }
@ -97,9 +97,9 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
deletedObject := deletedObjects[0] deletedObject := deletedObjects[0]
if deletedObject.Error != nil { if deletedObject.Error != nil {
if isErrObjectLocked(deletedObject.Error) { if isErrObjectLocked(deletedObject.Error) {
h.logAndSendError(w, "object is locked", reqInfo, errors.GetAPIError(errors.ErrAccessDenied)) h.logAndSendError(ctx, w, "object is locked", reqInfo, errors.GetAPIError(errors.ErrAccessDenied))
} else { } else {
h.logAndSendError(w, "could not delete object", reqInfo, deletedObject.Error) h.logAndSendError(ctx, w, "could not delete object", reqInfo, deletedObject.Error)
} }
return return
} }
@ -134,26 +134,26 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
// Content-Md5 is required and should be set // Content-Md5 is required and should be set
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
if _, ok := r.Header[api.ContentMD5]; !ok { if _, ok := r.Header[api.ContentMD5]; !ok {
h.logAndSendError(w, "missing Content-MD5", reqInfo, errors.GetAPIError(errors.ErrMissingContentMD5)) h.logAndSendError(ctx, w, "missing Content-MD5", reqInfo, errors.GetAPIError(errors.ErrMissingContentMD5))
return return
} }
// Content-Length is required and should be non-zero // Content-Length is required and should be non-zero
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
if r.ContentLength <= 0 { if r.ContentLength <= 0 {
h.logAndSendError(w, "missing Content-Length", reqInfo, errors.GetAPIError(errors.ErrMissingContentLength)) h.logAndSendError(ctx, w, "missing Content-Length", reqInfo, errors.GetAPIError(errors.ErrMissingContentLength))
return return
} }
// Unmarshal list of keys to be deleted. // Unmarshal list of keys to be deleted.
requested := &DeleteObjectsRequest{} requested := &DeleteObjectsRequest{}
if err := h.cfg.NewXMLDecoder(r.Body).Decode(requested); err != nil { if err := h.cfg.NewXMLDecoder(r.Body).Decode(requested); err != nil {
h.logAndSendError(w, "couldn't decode body", reqInfo, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrMalformedXML), err.Error())) h.logAndSendError(ctx, w, "couldn't decode body", reqInfo, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrMalformedXML), err.Error()))
return return
} }
if len(requested.Objects) == 0 || len(requested.Objects) > maxObjectsToDelete { if len(requested.Objects) == 0 || len(requested.Objects) > maxObjectsToDelete {
h.logAndSendError(w, "number of objects to delete must be greater than 0 and less or equal to 1000", reqInfo, errors.GetAPIError(errors.ErrMalformedXML)) h.logAndSendError(ctx, w, "number of objects to delete must be greater than 0 and less or equal to 1000", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
return return
} }
@ -178,19 +178,19 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo) bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
networkInfo, err := h.obj.GetNetworkInfo(ctx) networkInfo, err := h.obj.GetNetworkInfo(ctx)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get network info", reqInfo, err) h.logAndSendError(ctx, w, "could not get network info", reqInfo, err)
return return
} }
@ -231,22 +231,23 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
} }
if err = middleware.EncodeToResponse(w, response); err != nil { if err = middleware.EncodeToResponse(w, response); err != nil {
h.logAndSendError(w, "could not write response", reqInfo, err) h.logAndSendError(ctx, w, "could not write response", reqInfo, err)
return return
} }
} }
func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
var sessionToken *session.Container var sessionToken *session.Container
boxData, err := middleware.GetBoxData(r.Context()) boxData, err := middleware.GetBoxData(ctx)
if err == nil { if err == nil {
sessionToken = boxData.Gate.SessionTokenForDelete() sessionToken = boxData.Gate.SessionTokenForDelete()
} }
@ -259,12 +260,12 @@ func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
} }
} }
if err = h.obj.DeleteBucket(r.Context(), &layer.DeleteBucketParams{ if err = h.obj.DeleteBucket(ctx, &layer.DeleteBucketParams{
BktInfo: bktInfo, BktInfo: bktInfo,
SessionToken: sessionToken, SessionToken: sessionToken,
SkipCheck: skipObjCheck, SkipCheck: skipObjCheck,
}); err != nil { }); err != nil {
h.logAndSendError(w, "couldn't delete bucket", reqInfo, err) h.logAndSendError(ctx, w, "couldn't delete bucket", reqInfo, err)
return return
} }
@ -275,7 +276,7 @@ func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
getBucketCannedChainID(chain.Ingress, bktInfo.CID), getBucketCannedChainID(chain.Ingress, bktInfo.CID),
} }
if err = h.ape.DeleteBucketPolicy(reqInfo.Namespace, bktInfo.CID, chainIDs); err != nil { if err = h.ape.DeleteBucketPolicy(reqInfo.Namespace, bktInfo.CID, chainIDs); err != nil {
h.logAndSendError(w, "failed to delete policy from storage", reqInfo, err) h.logAndSendError(ctx, w, "failed to delete policy from storage", reqInfo, err)
return return
} }

View file

@ -129,18 +129,19 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
var ( var (
params *layer.RangeParams params *layer.RangeParams
reqInfo = middleware.GetReqInfo(r.Context()) ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
) )
conditional, err := parseConditionalHeaders(r.Header) conditional, err := parseConditionalHeaders(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse request params", reqInfo, err) h.logAndSendError(ctx, w, "could not parse request params", reqInfo, err)
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -150,37 +151,37 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
} }
extendedInfo, err := h.obj.GetExtendedObjectInfo(r.Context(), p) extendedInfo, err := h.obj.GetExtendedObjectInfo(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not find object", reqInfo, err) h.logAndSendError(ctx, w, "could not find object", reqInfo, err)
return return
} }
info := extendedInfo.ObjectInfo info := extendedInfo.ObjectInfo
if err = checkPreconditions(info, conditional, h.cfg.MD5Enabled()); err != nil { if err = checkPreconditions(info, conditional, h.cfg.MD5Enabled()); err != nil {
h.logAndSendError(w, "precondition failed", reqInfo, err) h.logAndSendError(ctx, w, "precondition failed", reqInfo, err)
return return
} }
encryptionParams, err := formEncryptionParams(r) encryptionParams, err := formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
if err = encryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(info.Headers)); err != nil { if err = encryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(info.Headers)); err != nil {
h.logAndSendError(w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err)) h.logAndSendError(ctx, w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err))
return return
} }
fullSize, err := layer.GetObjectSize(info) fullSize, err := layer.GetObjectSize(info)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid size header", reqInfo, errors.GetAPIError(errors.ErrBadRequest)) h.logAndSendError(ctx, w, "invalid size header", reqInfo, errors.GetAPIError(errors.ErrBadRequest))
return return
} }
if params, err = fetchRangeHeader(r.Header, fullSize); err != nil { if params, err = fetchRangeHeader(r.Header, fullSize); err != nil {
h.logAndSendError(w, "could not parse range header", reqInfo, err) h.logAndSendError(ctx, w, "could not parse range header", reqInfo, err)
return return
} }
@ -190,24 +191,24 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
VersionID: info.VersionID(), VersionID: info.VersionID(),
} }
tagSet, lockInfo, err := h.obj.GetObjectTaggingAndLock(r.Context(), t, extendedInfo.NodeVersion) tagSet, lockInfo, err := h.obj.GetObjectTaggingAndLock(ctx, t, extendedInfo.NodeVersion)
if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) { if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) {
h.logAndSendError(w, "could not get object meta data", reqInfo, err) h.logAndSendError(ctx, w, "could not get object meta data", reqInfo, err)
return return
} }
if layer.IsAuthenticatedRequest(r.Context()) { if layer.IsAuthenticatedRequest(ctx) {
overrideResponseHeaders(w.Header(), reqInfo.URL.Query()) overrideResponseHeaders(w.Header(), reqInfo.URL.Query())
} }
if err = h.setLockingHeaders(bktInfo, lockInfo, w.Header()); err != nil { if err = h.setLockingHeaders(bktInfo, lockInfo, w.Header()); err != nil {
h.logAndSendError(w, "could not get locking info", reqInfo, err) h.logAndSendError(ctx, w, "could not get locking info", reqInfo, err)
return return
} }
bktSettings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
@ -219,9 +220,9 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
Encryption: encryptionParams, Encryption: encryptionParams,
} }
objPayload, err := h.obj.GetObject(r.Context(), getPayloadParams) objPayload, err := h.obj.GetObject(ctx, getPayloadParams)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get object payload", reqInfo, err) h.logAndSendError(ctx, w, "could not get object payload", reqInfo, err)
return return
} }
@ -233,7 +234,7 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
if err = objPayload.StreamTo(w); err != nil { if err = objPayload.StreamTo(w); err != nil {
h.logAndSendError(w, "could not stream object payload", reqInfo, err) h.logAndSendError(ctx, w, "could not stream object payload", reqInfo, err)
return return
} }
} }

View file

@ -27,17 +27,18 @@ func getRangeToDetectContentType(maxSize uint64) *layer.RangeParams {
} }
func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
conditional, err := parseConditionalHeaders(r.Header) conditional, err := parseConditionalHeaders(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse request params", reqInfo, err) h.logAndSendError(ctx, w, "could not parse request params", reqInfo, err)
return return
} }
@ -47,26 +48,26 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
} }
extendedInfo, err := h.obj.GetExtendedObjectInfo(r.Context(), p) extendedInfo, err := h.obj.GetExtendedObjectInfo(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not find object", reqInfo, err) h.logAndSendError(ctx, w, "could not find object", reqInfo, err)
return return
} }
info := extendedInfo.ObjectInfo info := extendedInfo.ObjectInfo
encryptionParams, err := formEncryptionParams(r) encryptionParams, err := formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
if err = encryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(info.Headers)); err != nil { if err = encryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(info.Headers)); err != nil {
h.logAndSendError(w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err)) h.logAndSendError(ctx, w, "encryption doesn't match object", reqInfo, errors.GetAPIError(errors.ErrBadRequest), zap.Error(err))
return return
} }
if err = checkPreconditions(info, conditional, h.cfg.MD5Enabled()); err != nil { if err = checkPreconditions(info, conditional, h.cfg.MD5Enabled()); err != nil {
h.logAndSendError(w, "precondition failed", reqInfo, err) h.logAndSendError(ctx, w, "precondition failed", reqInfo, err)
return return
} }
@ -76,9 +77,9 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
VersionID: info.VersionID(), VersionID: info.VersionID(),
} }
tagSet, lockInfo, err := h.obj.GetObjectTaggingAndLock(r.Context(), t, extendedInfo.NodeVersion) tagSet, lockInfo, err := h.obj.GetObjectTaggingAndLock(ctx, t, extendedInfo.NodeVersion)
if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) { if err != nil && !errors.IsS3Error(err, errors.ErrNoSuchKey) {
h.logAndSendError(w, "could not get object meta data", reqInfo, err) h.logAndSendError(ctx, w, "could not get object meta data", reqInfo, err)
return return
} }
@ -91,15 +92,15 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
BucketInfo: bktInfo, BucketInfo: bktInfo,
} }
objPayload, err := h.obj.GetObject(r.Context(), getParams) objPayload, err := h.obj.GetObject(ctx, getParams)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get object", reqInfo, err, zap.Stringer("oid", info.ID)) h.logAndSendError(ctx, w, "could not get object", reqInfo, err, zap.Stringer("oid", info.ID))
return return
} }
buffer, err := io.ReadAll(objPayload) buffer, err := io.ReadAll(objPayload)
if err != nil { if err != nil {
h.logAndSendError(w, "could not partly read payload to detect content type", reqInfo, err, zap.Stringer("oid", info.ID)) h.logAndSendError(ctx, w, "could not partly read payload to detect content type", reqInfo, err, zap.Stringer("oid", info.ID))
return return
} }
@ -108,13 +109,13 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
if err = h.setLockingHeaders(bktInfo, lockInfo, w.Header()); err != nil { if err = h.setLockingHeaders(bktInfo, lockInfo, w.Header()); err != nil {
h.logAndSendError(w, "could not get locking info", reqInfo, err) h.logAndSendError(ctx, w, "could not get locking info", reqInfo, err)
return return
} }
bktSettings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
@ -123,11 +124,12 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -141,7 +143,7 @@ func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
} }
if err = middleware.WriteResponse(w, http.StatusOK, nil, middleware.MimeNone); err != nil { if err = middleware.WriteResponse(w, http.StatusOK, nil, middleware.MimeNone); err != nil {
h.logAndSendError(w, "write response", reqInfo, err) h.logAndSendError(ctx, w, "write response", reqInfo, err)
return return
} }
} }

View file

@ -7,15 +7,16 @@ import (
) )
func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, LocationResponse{Location: bktInfo.LocationConstraint}); err != nil { if err = middleware.EncodeToResponse(w, LocationResponse{Location: bktInfo.LocationConstraint}); err != nil {
h.logAndSendError(w, "couldn't encode bucket location response", reqInfo, err) h.logAndSendError(ctx, w, "couldn't encode bucket location response", reqInfo, err)
} }
} }

View file

@ -31,18 +31,18 @@ func (h *handler) GetBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
cfg, err := h.obj.GetBucketLifecycleConfiguration(ctx, bktInfo) cfg, err := h.obj.GetBucketLifecycleConfiguration(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket lifecycle configuration", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket lifecycle configuration", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, cfg); err != nil { if err = middleware.EncodeToResponse(w, cfg); err != nil {
h.logAndSendError(w, "could not encode GetBucketLifecycle response", reqInfo, err) h.logAndSendError(ctx, w, "could not encode GetBucketLifecycle response", reqInfo, err)
return return
} }
} }
@ -57,47 +57,47 @@ 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(ctx, w, "missing Content-MD5", reqInfo, apierr.GetAPIError(apierr.ErrMissingContentMD5))
return return
} }
headerMD5, err := base64.StdEncoding.DecodeString(r.Header.Get(api.ContentMD5)) headerMD5, err := base64.StdEncoding.DecodeString(r.Header.Get(api.ContentMD5))
if err != nil { if err != nil {
h.logAndSendError(w, "invalid Content-MD5", reqInfo, apierr.GetAPIError(apierr.ErrInvalidDigest)) h.logAndSendError(ctx, w, "invalid Content-MD5", reqInfo, apierr.GetAPIError(apierr.ErrInvalidDigest))
return return
} }
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(ctx, w, "could not decode body", reqInfo, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error()))
return return
} }
bodyMD5, err := getContentMD5(&buf) bodyMD5, err := getContentMD5(&buf)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get content md5", reqInfo, err) h.logAndSendError(ctx, w, "could not get content md5", reqInfo, err)
return return
} }
if !bytes.Equal(headerMD5, bodyMD5) { if !bytes.Equal(headerMD5, bodyMD5) {
h.logAndSendError(w, "Content-MD5 does not match", reqInfo, apierr.GetAPIError(apierr.ErrInvalidDigest)) h.logAndSendError(ctx, w, "Content-MD5 does not match", reqInfo, apierr.GetAPIError(apierr.ErrInvalidDigest))
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
networkInfo, err := h.obj.GetNetworkInfo(ctx) networkInfo, err := h.obj.GetNetworkInfo(ctx)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get network info", reqInfo, err) h.logAndSendError(ctx, w, "could not get network info", reqInfo, err)
return return
} }
if err = checkLifecycleConfiguration(ctx, cfg, &networkInfo); err != nil { if err = checkLifecycleConfiguration(ctx, cfg, &networkInfo); err != nil {
h.logAndSendError(w, "invalid lifecycle configuration", reqInfo, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error())) h.logAndSendError(ctx, w, "invalid lifecycle configuration", reqInfo, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrMalformedXML), err.Error()))
return return
} }
@ -108,12 +108,12 @@ func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque
params.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint) params.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
if err = h.obj.PutBucketLifecycleConfiguration(ctx, params); err != nil { if err = h.obj.PutBucketLifecycleConfiguration(ctx, params); err != nil {
h.logAndSendError(w, "could not put bucket lifecycle configuration", reqInfo, err) h.logAndSendError(ctx, w, "could not put bucket lifecycle configuration", reqInfo, err)
return return
} }
} }
@ -124,12 +124,12 @@ func (h *handler) DeleteBucketLifecycleHandler(w http.ResponseWriter, r *http.Re
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if err = h.obj.DeleteBucketLifecycleConfiguration(ctx, bktInfo); err != nil { if err = h.obj.DeleteBucketLifecycleConfiguration(ctx, bktInfo); err != nil {
h.logAndSendError(w, "could not delete bucket lifecycle configuration", reqInfo, err) h.logAndSendError(ctx, w, "could not delete bucket lifecycle configuration", reqInfo, err)
return return
} }

View file

@ -15,12 +15,13 @@ func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
var ( var (
own user.ID own user.ID
res *ListBucketsResponse res *ListBucketsResponse
reqInfo = middleware.GetReqInfo(r.Context()) ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
) )
list, err := h.obj.ListBuckets(r.Context()) list, err := h.obj.ListBuckets(ctx)
if err != nil { if err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
@ -43,6 +44,6 @@ func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
} }
if err = middleware.EncodeToResponse(w, res); err != nil { if err = middleware.EncodeToResponse(w, res); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }

View file

@ -26,34 +26,35 @@ const (
) )
func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "couldn't put object locking configuration", reqInfo, h.logAndSendError(ctx, w, "couldn't put object locking configuration", reqInfo,
apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotAllowed)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotAllowed))
return return
} }
lockingConf := &data.ObjectLockConfiguration{} lockingConf := &data.ObjectLockConfiguration{}
if err = h.cfg.NewXMLDecoder(r.Body).Decode(lockingConf); err != nil { if err = h.cfg.NewXMLDecoder(r.Body).Decode(lockingConf); err != nil {
h.logAndSendError(w, "couldn't parse locking configuration", reqInfo, err) h.logAndSendError(ctx, w, "couldn't parse locking configuration", reqInfo, err)
return return
} }
if err = checkLockConfiguration(lockingConf); err != nil { if err = checkLockConfiguration(lockingConf); err != nil {
h.logAndSendError(w, "invalid lock configuration", reqInfo, err) h.logAndSendError(ctx, w, "invalid lock configuration", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get bucket settings", reqInfo, err)
return return
} }
@ -66,30 +67,31 @@ func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
Settings: &newSettings, Settings: &newSettings,
} }
if err = h.obj.PutBucketSettings(r.Context(), sp); err != nil { if err = h.obj.PutBucketSettings(ctx, sp); err != nil {
h.logAndSendError(w, "couldn't put bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't put bucket settings", reqInfo, err)
return return
} }
} }
func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(ctx, w, "object lock disabled", reqInfo,
apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get bucket settings", reqInfo, err)
return return
} }
@ -101,33 +103,34 @@ func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
} }
if err = middleware.EncodeToResponse(w, settings.LockConfiguration); err != nil { if err = middleware.EncodeToResponse(w, settings.LockConfiguration); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(ctx, w, "object lock disabled", reqInfo,
apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
legalHold := &data.LegalHold{} legalHold := &data.LegalHold{}
if err = h.cfg.NewXMLDecoder(r.Body).Decode(legalHold); err != nil { if err = h.cfg.NewXMLDecoder(r.Body).Decode(legalHold); err != nil {
h.logAndSendError(w, "couldn't parse legal hold configuration", reqInfo, err) h.logAndSendError(ctx, w, "couldn't parse legal hold configuration", reqInfo, err)
return return
} }
if legalHold.Status != legalHoldOn && legalHold.Status != legalHoldOff { if legalHold.Status != legalHoldOn && legalHold.Status != legalHoldOff {
h.logAndSendError(w, "invalid legal hold status", reqInfo, h.logAndSendError(ctx, w, "invalid legal hold status", reqInfo,
fmt.Errorf("invalid status %s", legalHold.Status)) fmt.Errorf("invalid status %s", legalHold.Status))
return return
} }
@ -147,27 +150,28 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
p.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint) p.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
if err = h.obj.PutLockInfo(r.Context(), p); err != nil { if err = h.obj.PutLockInfo(ctx, p); err != nil {
h.logAndSendError(w, "couldn't head put legal hold", reqInfo, err) h.logAndSendError(ctx, w, "couldn't head put legal hold", reqInfo, err)
return return
} }
} }
func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(ctx, w, "object lock disabled", reqInfo,
apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -178,9 +182,9 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
} }
lockInfo, err := h.obj.GetLockInfo(r.Context(), p) lockInfo, err := h.obj.GetLockInfo(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't head lock object", reqInfo, err) h.logAndSendError(ctx, w, "couldn't head lock object", reqInfo, err)
return return
} }
@ -190,33 +194,34 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
} }
if err = middleware.EncodeToResponse(w, legalHold); err != nil { if err = middleware.EncodeToResponse(w, legalHold); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(ctx, w, "object lock disabled", reqInfo,
apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
retention := &data.Retention{} retention := &data.Retention{}
if err = h.cfg.NewXMLDecoder(r.Body).Decode(retention); err != nil { if err = h.cfg.NewXMLDecoder(r.Body).Decode(retention); err != nil {
h.logAndSendError(w, "couldn't parse object retention", reqInfo, err) h.logAndSendError(ctx, w, "couldn't parse object retention", reqInfo, err)
return return
} }
lock, err := formObjectLockFromRetention(r.Context(), retention, r.Header) lock, err := formObjectLockFromRetention(ctx, retention, r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid retention configuration", reqInfo, err) h.logAndSendError(ctx, w, "invalid retention configuration", reqInfo, err)
return return
} }
@ -231,27 +236,28 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
p.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint) p.CopiesNumbers, err = h.pickCopiesNumbers(parseMetadata(r), reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
if err = h.obj.PutLockInfo(r.Context(), p); err != nil { if err = h.obj.PutLockInfo(ctx, p); err != nil {
h.logAndSendError(w, "couldn't put legal hold", reqInfo, err) h.logAndSendError(ctx, w, "couldn't put legal hold", reqInfo, err)
return return
} }
} }
func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if !bktInfo.ObjectLockEnabled { if !bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "object lock disabled", reqInfo, h.logAndSendError(ctx, w, "object lock disabled", reqInfo,
apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound)) apierr.GetAPIError(apierr.ErrObjectLockConfigurationNotFound))
return return
} }
@ -262,14 +268,14 @@ func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID), VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
} }
lockInfo, err := h.obj.GetLockInfo(r.Context(), p) lockInfo, err := h.obj.GetLockInfo(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't head lock object", reqInfo, err) h.logAndSendError(ctx, w, "couldn't head lock object", reqInfo, err)
return return
} }
if !lockInfo.IsRetentionSet() { if !lockInfo.IsRetentionSet() {
h.logAndSendError(w, "retention lock isn't set", reqInfo, apierr.GetAPIError(apierr.ErrNoSuchKey)) h.logAndSendError(ctx, w, "retention lock isn't set", reqInfo, apierr.GetAPIError(apierr.ErrNoSuchKey))
return return
} }
@ -282,7 +288,7 @@ func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
} }
if err = middleware.EncodeToResponse(w, retention); err != nil { if err = middleware.EncodeToResponse(w, retention); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }

View file

@ -104,19 +104,20 @@ const (
) )
func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
uploadID := uuid.New() uploadID := uuid.New()
cannedACLStatus := aclHeadersStatus(r) cannedACLStatus := aclHeadersStatus(r)
additional := []zap.Field{zap.String("uploadID", uploadID.String())} additional := []zap.Field{zap.String("uploadID", uploadID.String())}
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if cannedACLStatus == aclStatusYes { if cannedACLStatus == aclStatusYes {
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported)) h.logAndSendError(ctx, w, "acl not supported for this bucket", reqInfo, errors.GetAPIError(errors.ErrAccessControlListNotSupported))
return return
} }
@ -132,14 +133,14 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
if len(r.Header.Get(api.AmzTagging)) > 0 { if len(r.Header.Get(api.AmzTagging)) > 0 {
p.Data.TagSet, err = parseTaggingHeader(r.Header) p.Data.TagSet, err = parseTaggingHeader(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse tagging", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not parse tagging", reqInfo, err, additional...)
return return
} }
} }
p.Info.Encryption, err = formEncryptionParams(r) p.Info.Encryption, err = formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err, additional...) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err, additional...)
return return
} }
@ -153,12 +154,12 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
p.CopiesNumbers, err = h.pickCopiesNumbers(p.Header, reqInfo.Namespace, bktInfo.LocationConstraint) p.CopiesNumbers, err = h.pickCopiesNumbers(p.Header, reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err, additional...) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err, additional...)
return return
} }
if err = h.obj.CreateMultipartUpload(r.Context(), p); err != nil { if err = h.obj.CreateMultipartUpload(ctx, p); err != nil {
h.logAndSendError(w, "could create multipart upload", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could create multipart upload", reqInfo, err, additional...)
return return
} }
@ -173,17 +174,18 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
} }
if err = middleware.EncodeToResponse(w, resp); err != nil { if err = middleware.EncodeToResponse(w, resp); err != nil {
h.logAndSendError(w, "could not encode InitiateMultipartUploadResponse to response", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not encode InitiateMultipartUploadResponse to response", reqInfo, err, additional...)
return return
} }
} }
func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -196,13 +198,13 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
partNumber, err := strconv.Atoi(partNumStr) partNumber, err := strconv.Atoi(partNumStr)
if err != nil || partNumber < layer.UploadMinPartNumber || partNumber > layer.UploadMaxPartNumber { if err != nil || partNumber < layer.UploadMinPartNumber || partNumber > layer.UploadMaxPartNumber {
h.logAndSendError(w, "invalid part number", reqInfo, errors.GetAPIError(errors.ErrInvalidPartNumber), additional...) h.logAndSendError(ctx, w, "invalid part number", reqInfo, errors.GetAPIError(errors.ErrInvalidPartNumber), additional...)
return return
} }
body, err := h.getBodyReader(r) body, err := h.getBodyReader(r)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to get body reader", reqInfo, err, additional...) h.logAndSendError(ctx, w, "failed to get body reader", reqInfo, err, additional...)
return return
} }
@ -223,13 +225,13 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
p.Info.Encryption, err = formEncryptionParams(r) p.Info.Encryption, err = formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err, additional...) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err, additional...)
return return
} }
hash, err := h.obj.UploadPart(r.Context(), p) hash, err := h.obj.UploadPart(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not upload a part", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not upload a part", reqInfo, err, additional...)
return return
} }
@ -239,7 +241,7 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set(api.ETag, data.Quote(hash)) w.Header().Set(api.ETag, data.Quote(hash))
if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil { if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil {
h.logAndSendError(w, "write response", reqInfo, err) h.logAndSendError(ctx, w, "write response", reqInfo, err)
return return
} }
} }
@ -257,7 +259,7 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
partNumber, err := strconv.Atoi(partNumStr) partNumber, err := strconv.Atoi(partNumStr)
if err != nil || partNumber < layer.UploadMinPartNumber || partNumber > layer.UploadMaxPartNumber { if err != nil || partNumber < layer.UploadMinPartNumber || partNumber > layer.UploadMaxPartNumber {
h.logAndSendError(w, "invalid part number", reqInfo, errors.GetAPIError(errors.ErrInvalidPartNumber), additional...) h.logAndSendError(ctx, w, "invalid part number", reqInfo, errors.GetAPIError(errors.ErrInvalidPartNumber), additional...)
return return
} }
@ -268,26 +270,26 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
} }
srcBucket, srcObject, err := path2BucketObject(src) srcBucket, srcObject, err := path2BucketObject(src)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid source copy", reqInfo, err, additional...) h.logAndSendError(ctx, w, "invalid source copy", reqInfo, err, additional...)
return return
} }
srcRange, err := parseRange(r.Header.Get(api.AmzCopySourceRange)) srcRange, err := parseRange(r.Header.Get(api.AmzCopySourceRange))
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse copy range", reqInfo, h.logAndSendError(ctx, w, "could not parse copy range", reqInfo,
errors.GetAPIError(errors.ErrInvalidCopyPartRange), additional...) errors.GetAPIError(errors.ErrInvalidCopyPartRange), additional...)
return return
} }
srcBktInfo, err := h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner) srcBktInfo, err := h.getBucketAndCheckOwner(r, srcBucket, api.AmzSourceExpectedBucketOwner)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get source bucket info", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not get source bucket info", reqInfo, err, additional...)
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get target bucket info", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not get target bucket info", reqInfo, err, additional...)
return return
} }
@ -300,35 +302,35 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
srcInfo, err := h.obj.GetObjectInfo(ctx, headPrm) srcInfo, err := h.obj.GetObjectInfo(ctx, headPrm)
if err != nil { if err != nil {
if errors.IsS3Error(err, errors.ErrNoSuchKey) && versionID != "" { if errors.IsS3Error(err, errors.ErrNoSuchKey) && versionID != "" {
h.logAndSendError(w, "could not head source object version", reqInfo, h.logAndSendError(ctx, w, "could not head source object version", reqInfo,
errors.GetAPIError(errors.ErrBadRequest), additional...) errors.GetAPIError(errors.ErrBadRequest), additional...)
return return
} }
h.logAndSendError(w, "could not head source object", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not head source object", reqInfo, err, additional...)
return return
} }
args, err := parseCopyObjectArgs(r.Header) args, err := parseCopyObjectArgs(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse copy object args", reqInfo, h.logAndSendError(ctx, w, "could not parse copy object args", reqInfo,
errors.GetAPIError(errors.ErrInvalidCopyPartRange), additional...) errors.GetAPIError(errors.ErrInvalidCopyPartRange), additional...)
return return
} }
if err = checkPreconditions(srcInfo, args.Conditional, h.cfg.MD5Enabled()); err != nil { if err = checkPreconditions(srcInfo, args.Conditional, h.cfg.MD5Enabled()); err != nil {
h.logAndSendError(w, "precondition failed", reqInfo, errors.GetAPIError(errors.ErrPreconditionFailed), h.logAndSendError(ctx, w, "precondition failed", reqInfo, errors.GetAPIError(errors.ErrPreconditionFailed),
additional...) additional...)
return return
} }
srcEncryptionParams, err := formCopySourceEncryptionParams(r) srcEncryptionParams, err := formCopySourceEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
if err = srcEncryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(srcInfo.Headers)); err != nil { if err = srcEncryptionParams.MatchObjectEncryption(layer.FormEncryptionInfo(srcInfo.Headers)); err != nil {
h.logAndSendError(w, "encryption doesn't match object", reqInfo, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrBadRequest), err), additional...) h.logAndSendError(ctx, w, "encryption doesn't match object", reqInfo, fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrBadRequest), err), additional...)
return return
} }
@ -348,13 +350,13 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
p.Info.Encryption, err = formEncryptionParams(r) p.Info.Encryption, err = formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err, additional...) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err, additional...)
return return
} }
info, err := h.obj.UploadPartCopy(ctx, p) info, err := h.obj.UploadPartCopy(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not upload part copy", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not upload part copy", reqInfo, err, additional...)
return return
} }
@ -368,22 +370,23 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
} }
if err = middleware.EncodeToResponse(w, response); err != nil { if err = middleware.EncodeToResponse(w, response); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err, additional...) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err, additional...)
} }
} }
func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
@ -399,12 +402,12 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
reqBody := new(CompleteMultipartUpload) reqBody := new(CompleteMultipartUpload)
if err = h.cfg.NewXMLDecoder(r.Body).Decode(reqBody); err != nil { if err = h.cfg.NewXMLDecoder(r.Body).Decode(reqBody); err != nil {
h.logAndSendError(w, "could not read complete multipart upload xml", reqInfo, h.logAndSendError(ctx, w, "could not read complete multipart upload xml", reqInfo,
fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrMalformedXML), err.Error()), additional...) fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrMalformedXML), err.Error()), additional...)
return return
} }
if len(reqBody.Parts) == 0 { if len(reqBody.Parts) == 0 {
h.logAndSendError(w, "invalid xml with parts", reqInfo, errors.GetAPIError(errors.ErrMalformedXML), additional...) h.logAndSendError(ctx, w, "invalid xml with parts", reqInfo, errors.GetAPIError(errors.ErrMalformedXML), additional...)
return return
} }
@ -418,7 +421,7 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
objInfo, err := h.completeMultipartUpload(r, c, bktInfo) objInfo, err := h.completeMultipartUpload(r, c, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "complete multipart error", reqInfo, err, additional...) h.logAndSendError(ctx, w, "complete multipart error", reqInfo, err, additional...)
return return
} }
@ -434,7 +437,7 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
} }
if err = middleware.EncodeToResponse(w, response); err != nil { if err = middleware.EncodeToResponse(w, response); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err, additional...) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err, additional...)
} }
} }
@ -493,11 +496,12 @@ func (h *handler) completeMultipartUpload(r *http.Request, c *layer.CompleteMult
} }
func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -510,7 +514,7 @@ func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Req
if maxUploadsStr != "" { if maxUploadsStr != "" {
val, err := strconv.Atoi(maxUploadsStr) val, err := strconv.Atoi(maxUploadsStr)
if err != nil || val < 1 || val > 1000 { if err != nil || val < 1 || val > 1000 {
h.logAndSendError(w, "invalid maxUploads", reqInfo, errors.GetAPIError(errors.ErrInvalidMaxUploads)) h.logAndSendError(ctx, w, "invalid maxUploads", reqInfo, errors.GetAPIError(errors.ErrInvalidMaxUploads))
return return
} }
maxUploads = val maxUploads = val
@ -527,27 +531,28 @@ func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Req
} }
if p.EncodingType != "" && strings.ToLower(p.EncodingType) != urlEncodingType { if p.EncodingType != "" && strings.ToLower(p.EncodingType) != urlEncodingType {
h.logAndSendError(w, "invalid encoding type", reqInfo, errors.GetAPIError(errors.ErrInvalidEncodingMethod)) h.logAndSendError(ctx, w, "invalid encoding type", reqInfo, errors.GetAPIError(errors.ErrInvalidEncodingMethod))
return return
} }
list, err := h.obj.ListMultipartUploads(r.Context(), p) list, err := h.obj.ListMultipartUploads(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not list multipart uploads", reqInfo, err) h.logAndSendError(ctx, w, "could not list multipart uploads", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, encodeListMultipartUploadsToResponse(list, p)); err != nil { if err = middleware.EncodeToResponse(w, encodeListMultipartUploadsToResponse(list, p)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -556,14 +561,14 @@ func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
queryValues = reqInfo.URL.Query() queryValues = reqInfo.URL.Query()
uploadID = queryValues.Get(uploadIDHeaderName) uploadID = queryValues.Get(uploadIDHeaderName)
additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("Key", reqInfo.ObjectName)} additional = []zap.Field{zap.String("uploadID", uploadID)}
maxParts = layer.MaxSizePartsList maxParts = layer.MaxSizePartsList
) )
if queryValues.Get("max-parts") != "" { if queryValues.Get("max-parts") != "" {
val, err := strconv.Atoi(queryValues.Get("max-parts")) val, err := strconv.Atoi(queryValues.Get("max-parts"))
if err != nil || val < 0 { if err != nil || val < 0 {
h.logAndSendError(w, "invalid MaxParts", reqInfo, errors.GetAPIError(errors.ErrInvalidMaxParts), additional...) h.logAndSendError(ctx, w, "invalid MaxParts", reqInfo, errors.GetAPIError(errors.ErrInvalidMaxParts), additional...)
return return
} }
if val < layer.MaxSizePartsList { if val < layer.MaxSizePartsList {
@ -573,7 +578,7 @@ func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
if queryValues.Get("part-number-marker") != "" { if queryValues.Get("part-number-marker") != "" {
if partNumberMarker, err = strconv.Atoi(queryValues.Get("part-number-marker")); err != nil || partNumberMarker < 0 { if partNumberMarker, err = strconv.Atoi(queryValues.Get("part-number-marker")); err != nil || partNumberMarker < 0 {
h.logAndSendError(w, "invalid PartNumberMarker", reqInfo, err, additional...) h.logAndSendError(ctx, w, "invalid PartNumberMarker", reqInfo, err, additional...)
return return
} }
} }
@ -590,32 +595,33 @@ func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
p.Info.Encryption, err = formEncryptionParams(r) p.Info.Encryption, err = formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
list, err := h.obj.ListParts(r.Context(), p) list, err := h.obj.ListParts(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not list parts", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not list parts", reqInfo, err, additional...)
return return
} }
if err = middleware.EncodeToResponse(w, encodeListPartsToResponse(list, p)); err != nil { if err = middleware.EncodeToResponse(w, encodeListPartsToResponse(list, p)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
uploadID := reqInfo.URL.Query().Get(uploadIDHeaderName) uploadID := reqInfo.URL.Query().Get(uploadIDHeaderName)
additional := []zap.Field{zap.String("uploadID", uploadID), zap.String("Key", reqInfo.ObjectName)} additional := []zap.Field{zap.String("uploadID", uploadID)}
p := &layer.UploadInfoParams{ p := &layer.UploadInfoParams{
UploadID: uploadID, UploadID: uploadID,
@ -625,12 +631,12 @@ func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Req
p.Encryption, err = formEncryptionParams(r) p.Encryption, err = formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
if err = h.obj.AbortMultipartUpload(r.Context(), p); err != nil { if err = h.obj.AbortMultipartUpload(ctx, p); err != nil {
h.logAndSendError(w, "could not abort multipart upload", reqInfo, err, additional...) h.logAndSendError(ctx, w, "could not abort multipart upload", reqInfo, err, additional...)
return return
} }

View file

@ -8,5 +8,5 @@ import (
) )
func (h *handler) DeleteBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not supported", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotSupported)) h.logAndSendError(r.Context(), w, "not supported", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotSupported))
} }

View file

@ -17,26 +17,27 @@ import (
// ListObjectsV1Handler handles objects listing requests for API version 1. // ListObjectsV1Handler handles objects listing requests for API version 1.
func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseListObjectsArgsV1(reqInfo) params, err := parseListObjectsArgsV1(reqInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to parse arguments", reqInfo, err) h.logAndSendError(ctx, w, "failed to parse arguments", reqInfo, err)
return return
} }
if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil { if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
list, err := h.obj.ListObjectsV1(r.Context(), params) list, err := h.obj.ListObjectsV1(ctx, params)
if err != nil { if err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, h.encodeV1(params, list)); err != nil { if err = middleware.EncodeToResponse(w, h.encodeV1(params, list)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
@ -61,26 +62,27 @@ func (h *handler) encodeV1(p *layer.ListObjectsParamsV1, list *layer.ListObjects
// ListObjectsV2Handler handles objects listing requests for API version 2. // ListObjectsV2Handler handles objects listing requests for API version 2.
func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseListObjectsArgsV2(reqInfo) params, err := parseListObjectsArgsV2(reqInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to parse arguments", reqInfo, err) h.logAndSendError(ctx, w, "failed to parse arguments", reqInfo, err)
return return
} }
if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil { if params.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
list, err := h.obj.ListObjectsV2(r.Context(), params) list, err := h.obj.ListObjectsV2(ctx, params)
if err != nil { if err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, h.encodeV2(params, list)); err != nil { if err = middleware.EncodeToResponse(w, h.encodeV2(params, list)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
@ -219,27 +221,28 @@ func fillContents(src []*data.ExtendedNodeVersion, encode string, fetchOwner, md
} }
func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
p, err := parseListObjectVersionsRequest(reqInfo) p, err := parseListObjectVersionsRequest(reqInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to parse request", reqInfo, err) h.logAndSendError(ctx, w, "failed to parse request", reqInfo, err)
return return
} }
if p.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil { if p.BktInfo, err = h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
info, err := h.obj.ListObjectVersions(r.Context(), p) info, err := h.obj.ListObjectVersions(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
response := encodeListObjectVersionsToResponse(p, info, p.BktInfo.Name, h.cfg.MD5Enabled()) response := encodeListObjectVersionsToResponse(p, info, p.BktInfo.Name, h.cfg.MD5Enabled())
if err = middleware.EncodeToResponse(w, response); err != nil { if err = middleware.EncodeToResponse(w, response); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }

View file

@ -22,30 +22,30 @@ func (h *handler) PatchObjectHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(ctx) reqInfo := middleware.GetReqInfo(ctx)
if _, ok := r.Header[api.ContentRange]; !ok { if _, ok := r.Header[api.ContentRange]; !ok {
h.logAndSendError(w, "missing Content-Range", reqInfo, errors.GetAPIError(errors.ErrMissingContentRange)) h.logAndSendError(ctx, w, "missing Content-Range", reqInfo, errors.GetAPIError(errors.ErrMissingContentRange))
return return
} }
if _, ok := r.Header[api.ContentLength]; !ok { if _, ok := r.Header[api.ContentLength]; !ok {
h.logAndSendError(w, "missing Content-Length", reqInfo, errors.GetAPIError(errors.ErrMissingContentLength)) h.logAndSendError(ctx, w, "missing Content-Length", reqInfo, errors.GetAPIError(errors.ErrMissingContentLength))
return return
} }
conditional, err := parsePatchConditionalHeaders(r.Header) conditional, err := parsePatchConditionalHeaders(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse conditional headers", reqInfo, err) h.logAndSendError(ctx, w, "could not parse conditional headers", reqInfo, err)
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(ctx, bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
@ -57,40 +57,40 @@ func (h *handler) PatchObjectHandler(w http.ResponseWriter, r *http.Request) {
extendedSrcObjInfo, err := h.obj.GetExtendedObjectInfo(ctx, srcObjPrm) extendedSrcObjInfo, err := h.obj.GetExtendedObjectInfo(ctx, srcObjPrm)
if err != nil { if err != nil {
h.logAndSendError(w, "could not find object", reqInfo, err) h.logAndSendError(ctx, w, "could not find object", reqInfo, err)
return return
} }
srcObjInfo := extendedSrcObjInfo.ObjectInfo srcObjInfo := extendedSrcObjInfo.ObjectInfo
if err = checkPreconditions(srcObjInfo, conditional, h.cfg.MD5Enabled()); err != nil { if err = checkPreconditions(srcObjInfo, conditional, h.cfg.MD5Enabled()); err != nil {
h.logAndSendError(w, "precondition failed", reqInfo, err) h.logAndSendError(ctx, w, "precondition failed", reqInfo, err)
return return
} }
srcSize, err := layer.GetObjectSize(srcObjInfo) srcSize, err := layer.GetObjectSize(srcObjInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to get source object size", reqInfo, err) h.logAndSendError(ctx, w, "failed to get source object size", reqInfo, err)
return return
} }
byteRange, err := parsePatchByteRange(r.Header.Get(api.ContentRange), srcSize) byteRange, err := parsePatchByteRange(r.Header.Get(api.ContentRange), srcSize)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse byte range", reqInfo, errors.GetAPIError(errors.ErrInvalidRange), zap.Error(err)) h.logAndSendError(ctx, w, "could not parse byte range", reqInfo, errors.GetAPIError(errors.ErrInvalidRange), zap.Error(err))
return return
} }
if maxPatchSize < byteRange.End-byteRange.Start+1 { if maxPatchSize < byteRange.End-byteRange.Start+1 {
h.logAndSendError(w, "byte range length is longer than allowed", reqInfo, errors.GetAPIError(errors.ErrInvalidRange), zap.Error(err)) h.logAndSendError(ctx, w, "byte range length is longer than allowed", reqInfo, errors.GetAPIError(errors.ErrInvalidRange), zap.Error(err))
return return
} }
if uint64(r.ContentLength) != (byteRange.End - byteRange.Start + 1) { if uint64(r.ContentLength) != (byteRange.End - byteRange.Start + 1) {
h.logAndSendError(w, "content-length must be equal to byte range length", reqInfo, errors.GetAPIError(errors.ErrInvalidRangeLength)) h.logAndSendError(ctx, w, "content-length must be equal to byte range length", reqInfo, errors.GetAPIError(errors.ErrInvalidRangeLength))
return return
} }
if byteRange.Start > srcSize { if byteRange.Start > srcSize {
h.logAndSendError(w, "start byte is greater than object size", reqInfo, errors.GetAPIError(errors.ErrRangeOutOfBounds)) h.logAndSendError(ctx, w, "start byte is greater than object size", reqInfo, errors.GetAPIError(errors.ErrRangeOutOfBounds))
return return
} }
@ -104,16 +104,16 @@ func (h *handler) PatchObjectHandler(w http.ResponseWriter, r *http.Request) {
params.CopiesNumbers, err = h.pickCopiesNumbers(nil, reqInfo.Namespace, bktInfo.LocationConstraint) params.CopiesNumbers, err = h.pickCopiesNumbers(nil, reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
extendedObjInfo, err := h.obj.PatchObject(ctx, params) extendedObjInfo, err := h.obj.PatchObject(ctx, params)
if err != nil { if err != nil {
if isErrObjectLocked(err) { if isErrObjectLocked(err) {
h.logAndSendError(w, "object is locked", reqInfo, errors.GetAPIError(errors.ErrAccessDenied)) h.logAndSendError(ctx, w, "object is locked", reqInfo, errors.GetAPIError(errors.ErrAccessDenied))
} else { } else {
h.logAndSendError(w, "could not patch object", reqInfo, err) h.logAndSendError(ctx, w, "could not patch object", reqInfo, err)
} }
return return
} }
@ -132,7 +132,7 @@ func (h *handler) PatchObjectHandler(w http.ResponseWriter, r *http.Request) {
} }
if err = middleware.EncodeToResponse(w, resp); err != nil { if err = middleware.EncodeToResponse(w, resp); err != nil {
h.logAndSendError(w, "could not encode PatchObjectResult to response", reqInfo, err) h.logAndSendError(ctx, w, "could not encode PatchObjectResult to response", reqInfo, err)
return return
} }
} }

View file

@ -193,24 +193,24 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket objInfo", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket objInfo", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(ctx, bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
if cannedACLStatus == aclStatusYes { if cannedACLStatus == aclStatusYes {
h.logAndSendError(w, "acl not supported for this bucket", reqInfo, apierr.GetAPIError(apierr.ErrAccessControlListNotSupported)) h.logAndSendError(ctx, w, "acl not supported for this bucket", reqInfo, apierr.GetAPIError(apierr.ErrAccessControlListNotSupported))
return return
} }
tagSet, err := parseTaggingHeader(r.Header) tagSet, err := parseTaggingHeader(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse tagging header", reqInfo, err) h.logAndSendError(ctx, w, "could not parse tagging header", reqInfo, err)
return return
} }
@ -230,13 +230,13 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
encryptionParams, err := formEncryptionParams(r) encryptionParams, err := formEncryptionParams(r)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid sse headers", reqInfo, err) h.logAndSendError(ctx, w, "invalid sse headers", reqInfo, err)
return return
} }
body, err := h.getBodyReader(r) body, err := h.getBodyReader(r)
if err != nil { if err != nil {
h.logAndSendError(w, "failed to get body reader", reqInfo, err) h.logAndSendError(ctx, w, "failed to get body reader", reqInfo, err)
return return
} }
if encodings := r.Header.Get(api.ContentEncoding); len(encodings) > 0 { if encodings := r.Header.Get(api.ContentEncoding); len(encodings) > 0 {
@ -261,13 +261,13 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
params.CopiesNumbers, err = h.pickCopiesNumbers(metadata, reqInfo.Namespace, bktInfo.LocationConstraint) params.CopiesNumbers, err = h.pickCopiesNumbers(metadata, reqInfo.Namespace, bktInfo.LocationConstraint)
if err != nil { if err != nil {
h.logAndSendError(w, "invalid copies number", reqInfo, err) h.logAndSendError(ctx, w, "invalid copies number", reqInfo, err)
return return
} }
params.Lock, err = formObjectLock(ctx, bktInfo, settings.LockConfiguration, r.Header) params.Lock, err = formObjectLock(ctx, bktInfo, settings.LockConfiguration, r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not form object lock", reqInfo, err) h.logAndSendError(ctx, w, "could not form object lock", reqInfo, err)
return return
} }
@ -275,7 +275,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
_, err2 := io.Copy(io.Discard, body) _, err2 := io.Copy(io.Discard, body)
err3 := body.Close() err3 := body.Close()
h.logAndSendError(w, "could not upload object", reqInfo, err, zap.Errors("body close errors", []error{err2, err3})) h.logAndSendError(ctx, w, "could not upload object", reqInfo, err, zap.Errors("body close errors", []error{err2, err3}))
return return
} }
objInfo := extendedObjInfo.ObjectInfo objInfo := extendedObjInfo.ObjectInfo
@ -290,8 +290,8 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
TagSet: tagSet, TagSet: tagSet,
NodeVersion: extendedObjInfo.NodeVersion, NodeVersion: extendedObjInfo.NodeVersion,
} }
if err = h.obj.PutObjectTagging(r.Context(), tagPrm); err != nil { if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil {
h.logAndSendError(w, "could not upload object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not upload object tagging", reqInfo, err)
return return
} }
} }
@ -306,7 +306,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set(api.ETag, data.Quote(objInfo.ETag(h.cfg.MD5Enabled()))) w.Header().Set(api.ETag, data.Quote(objInfo.ETag(h.cfg.MD5Enabled())))
if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil { if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil {
h.logAndSendError(w, "write response", reqInfo, err) h.logAndSendError(ctx, w, "write response", reqInfo, err)
return return
} }
} }
@ -435,7 +435,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
policy, err := checkPostPolicy(r, reqInfo, metadata) policy, err := checkPostPolicy(r, reqInfo, metadata)
if err != nil { if err != nil {
h.logAndSendError(w, "failed check policy", reqInfo, err) h.logAndSendError(ctx, w, "failed check policy", reqInfo, err)
return return
} }
@ -443,31 +443,31 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
buffer := bytes.NewBufferString(tagging) buffer := bytes.NewBufferString(tagging)
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(ctx, w, "could not decode tag set", reqInfo,
fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.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)
if err != nil { if err != nil {
h.logAndSendError(w, "could not read tag set", reqInfo, err) h.logAndSendError(ctx, w, "could not read tag set", reqInfo, err)
return return
} }
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket objInfo", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket objInfo", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(ctx, bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
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, apierr.GetAPIError(apierr.ErrAccessControlListNotSupported)) h.logAndSendError(ctx, w, "acl not supported for this bucket", reqInfo, apierr.GetAPIError(apierr.ErrAccessControlListNotSupported))
return return
} }
@ -485,7 +485,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
if reqInfo.ObjectName == "" || strings.Contains(reqInfo.ObjectName, "${filename}") { if reqInfo.ObjectName == "" || strings.Contains(reqInfo.ObjectName, "${filename}") {
_, head, err := r.FormFile("file") _, head, err := r.FormFile("file")
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse file field", reqInfo, err) h.logAndSendError(ctx, w, "could not parse file field", reqInfo, err)
return return
} }
filename = head.Filename filename = head.Filename
@ -494,7 +494,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
var head *multipart.FileHeader var head *multipart.FileHeader
contentReader, head, err = r.FormFile("file") contentReader, head, err = r.FormFile("file")
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse file field", reqInfo, err) h.logAndSendError(ctx, w, "could not parse file field", reqInfo, err)
return return
} }
size = uint64(head.Size) size = uint64(head.Size)
@ -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, apierr.GetAPIError(apierr.ErrInvalidArgument)) h.logAndSendError(ctx, 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, apierr.GetAPIError(apierr.ErrInvalidArgument)) h.logAndSendError(ctx, w, "invalid content-length", reqInfo, apierr.GetAPIError(apierr.ErrInvalidArgument))
return return
} }
@ -527,7 +527,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
extendedObjInfo, err := h.obj.PutObject(ctx, params) extendedObjInfo, err := h.obj.PutObject(ctx, params)
if err != nil { if err != nil {
h.logAndSendError(w, "could not upload object", reqInfo, err) h.logAndSendError(ctx, w, "could not upload object", reqInfo, err)
return return
} }
objInfo := extendedObjInfo.ObjectInfo objInfo := extendedObjInfo.ObjectInfo
@ -543,7 +543,7 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
} }
if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil { if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil {
h.logAndSendError(w, "could not upload object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not upload object tagging", reqInfo, err)
return return
} }
} }
@ -571,10 +571,10 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(status) w.WriteHeader(status)
respData, err := middleware.EncodeResponse(resp) respData, err := middleware.EncodeResponse(resp)
if err != nil { if err != nil {
h.logAndSendError(w, "encode response", reqInfo, err) h.logAndSendError(ctx, w, "encode response", reqInfo, err)
} }
if _, err = w.Write(respData); err != nil { if _, err = w.Write(respData); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
return return
} }
@ -759,25 +759,25 @@ func (h *handler) createBucketHandlerPolicy(w http.ResponseWriter, r *http.Reque
boxData, err := middleware.GetBoxData(ctx) boxData, err := middleware.GetBoxData(ctx)
if err != nil { if err != nil {
h.logAndSendError(w, "get access box from request", reqInfo, err) h.logAndSendError(ctx, w, "get access box from request", reqInfo, err)
return return
} }
key, p, err := h.parseCommonCreateBucketParams(reqInfo, boxData, r) key, p, err := h.parseCommonCreateBucketParams(reqInfo, boxData, r)
if err != nil { if err != nil {
h.logAndSendError(w, "parse create bucket params", reqInfo, err) h.logAndSendError(ctx, w, "parse create bucket params", reqInfo, err)
return return
} }
cannedACL, err := parseCannedACL(r.Header) cannedACL, err := parseCannedACL(r.Header)
if err != nil { if err != nil {
h.logAndSendError(w, "could not parse canned ACL", reqInfo, err) h.logAndSendError(ctx, w, "could not parse canned ACL", reqInfo, err)
return return
} }
bktInfo, err := h.obj.CreateBucket(ctx, p) bktInfo, err := h.obj.CreateBucket(ctx, p)
if err != nil { if err != nil {
h.logAndSendError(w, "could not create bucket", reqInfo, err) h.logAndSendError(ctx, w, "could not create bucket", reqInfo, err)
return return
} }
h.reqLogger(ctx).Info(logs.BucketIsCreated, zap.Stringer("container_id", bktInfo.CID)) h.reqLogger(ctx).Info(logs.BucketIsCreated, zap.Stringer("container_id", bktInfo.CID))
@ -785,7 +785,7 @@ func (h *handler) createBucketHandlerPolicy(w http.ResponseWriter, r *http.Reque
chains := bucketCannedACLToAPERules(cannedACL, reqInfo, bktInfo.CID) chains := bucketCannedACLToAPERules(cannedACL, reqInfo, bktInfo.CID)
if err = h.ape.SaveACLChains(bktInfo.CID.EncodeToString(), chains); err != nil { if err = h.ape.SaveACLChains(bktInfo.CID.EncodeToString(), chains); err != nil {
cleanErr := h.cleanupBucketCreation(ctx, reqInfo, bktInfo, boxData, chains) cleanErr := h.cleanupBucketCreation(ctx, reqInfo, bktInfo, boxData, chains)
h.logAndSendError(w, "failed to add morph rule chain", reqInfo, err, zap.NamedError("cleanup_error", cleanErr)) h.logAndSendError(ctx, w, "failed to add morph rule chain", reqInfo, err, zap.NamedError("cleanup_error", cleanErr))
return return
} }
@ -807,13 +807,13 @@ func (h *handler) createBucketHandlerPolicy(w http.ResponseWriter, r *http.Reque
}, h.putBucketSettingsRetryer()) }, h.putBucketSettingsRetryer())
if err != nil { if err != nil {
cleanErr := h.cleanupBucketCreation(ctx, reqInfo, bktInfo, boxData, chains) cleanErr := h.cleanupBucketCreation(ctx, reqInfo, bktInfo, boxData, chains)
h.logAndSendError(w, "couldn't save bucket settings", reqInfo, err, h.logAndSendError(ctx, w, "couldn't save bucket settings", reqInfo, err,
zap.String("container_id", bktInfo.CID.EncodeToString()), zap.NamedError("cleanup_error", cleanErr)) zap.String("container_id", bktInfo.CID.EncodeToString()), zap.NamedError("cleanup_error", cleanErr))
return return
} }
if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil { if err = middleware.WriteSuccessResponseHeadersOnly(w); err != nil {
h.logAndSendError(w, "write response", reqInfo, err) h.logAndSendError(ctx, w, "write response", reqInfo, err)
return return
} }
} }

View file

@ -26,13 +26,13 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
tagSet, err := h.readTagSet(reqInfo.Tagging) tagSet, err := h.readTagSet(reqInfo.Tagging)
if err != nil { if err != nil {
h.logAndSendError(w, "could not read tag set", reqInfo, err) h.logAndSendError(ctx, w, "could not read tag set", reqInfo, err)
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -46,7 +46,7 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
} }
if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil { if err = h.obj.PutObjectTagging(ctx, tagPrm); err != nil {
h.logAndSendError(w, "could not put object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not put object tagging", reqInfo, err)
return return
} }
@ -54,17 +54,18 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
} }
func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
return return
} }
@ -76,9 +77,9 @@ func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request
}, },
} }
versionID, tagSet, err := h.obj.GetObjectTagging(r.Context(), tagPrm) versionID, tagSet, err := h.obj.GetObjectTagging(ctx, tagPrm)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not get object tagging", reqInfo, err)
return return
} }
@ -86,7 +87,7 @@ func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request
w.Header().Set(api.AmzVersionID, versionID) w.Header().Set(api.AmzVersionID, versionID)
} }
if err = middleware.EncodeToResponse(w, encodeTagging(tagSet)); err != nil { if err = middleware.EncodeToResponse(w, encodeTagging(tagSet)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }
@ -96,7 +97,7 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
@ -107,7 +108,7 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
} }
if err = h.obj.DeleteObjectTagging(ctx, p); err != nil { if err = h.obj.DeleteObjectTagging(ctx, p); err != nil {
h.logAndSendError(w, "could not delete object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not delete object tagging", reqInfo, err)
return return
} }
@ -115,58 +116,61 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
} }
func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
tagSet, err := h.readTagSet(reqInfo.Tagging) tagSet, err := h.readTagSet(reqInfo.Tagging)
if err != nil { if err != nil {
h.logAndSendError(w, "could not read tag set", reqInfo, err) h.logAndSendError(ctx, w, "could not read tag set", reqInfo, err)
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if err = h.obj.PutBucketTagging(r.Context(), bktInfo, tagSet); err != nil { if err = h.obj.PutBucketTagging(ctx, bktInfo, tagSet); err != nil {
h.logAndSendError(w, "could not put object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not put object tagging", reqInfo, err)
return return
} }
} }
func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
tagSet, err := h.obj.GetBucketTagging(r.Context(), bktInfo) tagSet, err := h.obj.GetBucketTagging(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get object tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not get object tagging", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, encodeTagging(tagSet)); err != nil { if err = middleware.EncodeToResponse(w, encodeTagging(tagSet)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
return return
} }
} }
func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
if err = h.obj.DeleteBucketTagging(r.Context(), bktInfo); err != nil { if err = h.obj.DeleteBucketTagging(ctx, bktInfo); err != nil {
h.logAndSendError(w, "could not delete bucket tagging", reqInfo, err) h.logAndSendError(ctx, w, "could not delete bucket tagging", reqInfo, err)
return return
} }
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)

View file

@ -8,53 +8,53 @@ import (
) )
func (h *handler) SelectObjectContentHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) SelectObjectContentHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketWebsiteHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketWebsiteHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketAccelerateHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketAccelerateHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketRequestPaymentHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketRequestPaymentHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketLoggingHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketLoggingHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketReplicationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketReplicationHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) DeleteBucketWebsiteHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) DeleteBucketWebsiteHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) ListObjectsV2MHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) ListObjectsV2MHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) PutBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }
func (h *handler) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
h.logAndSendError(w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented)) h.logAndSendError(r.Context(), w, "not implemented", middleware.GetReqInfo(r.Context()), errors.GetAPIError(errors.ErrNotImplemented))
} }

View file

@ -15,7 +15,6 @@ import (
"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"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -27,7 +26,7 @@ func (h *handler) reqLogger(ctx context.Context) *zap.Logger {
return h.log return h.log
} }
func (h *handler) logAndSendError(w http.ResponseWriter, logText string, reqInfo *middleware.ReqInfo, err error, additional ...zap.Field) { func (h *handler) logAndSendError(ctx context.Context, w http.ResponseWriter, logText string, reqInfo *middleware.ReqInfo, err error, additional ...zap.Field) {
err = handleDeleteMarker(w, err) err = handleDeleteMarker(w, err)
if code, wrErr := middleware.WriteErrorResponse(w, reqInfo, apierr.TransformToS3Error(err)); wrErr != nil { if code, wrErr := middleware.WriteErrorResponse(w, reqInfo, apierr.TransformToS3Error(err)); wrErr != nil {
additional = append(additional, zap.NamedError("write_response_error", wrErr)) additional = append(additional, zap.NamedError("write_response_error", wrErr))
@ -35,7 +34,6 @@ func (h *handler) logAndSendError(w http.ResponseWriter, logText string, reqInfo
additional = append(additional, zap.Int("status", code)) additional = append(additional, zap.Int("status", code))
} }
fields := []zap.Field{ fields := []zap.Field{
zap.String("request_id", reqInfo.RequestID),
zap.String("method", reqInfo.API), zap.String("method", reqInfo.API),
zap.String("bucket", reqInfo.BucketName), zap.String("bucket", reqInfo.BucketName),
zap.String("object", reqInfo.ObjectName), zap.String("object", reqInfo.ObjectName),
@ -43,10 +41,7 @@ func (h *handler) logAndSendError(w http.ResponseWriter, logText string, reqInfo
zap.String("user", reqInfo.User), zap.String("user", reqInfo.User),
zap.Error(err)} zap.Error(err)}
fields = append(fields, additional...) fields = append(fields, additional...)
if traceID, err := trace.TraceIDFromHex(reqInfo.TraceID); err == nil && traceID.IsValid() { h.reqLogger(ctx).Error(logs.RequestFailed, fields...)
fields = append(fields, zap.String("trace_id", reqInfo.TraceID))
}
h.log.Error(logs.RequestFailed, fields...) // consider using h.reqLogger (it requires accept context.Context or http.Request)
} }
func handleDeleteMarker(w http.ResponseWriter, err error) error { func handleDeleteMarker(w http.ResponseWriter, err error) error {

View file

@ -10,28 +10,29 @@ import (
) )
func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
configuration := new(VersioningConfiguration) configuration := new(VersioningConfiguration)
if err := h.cfg.NewXMLDecoder(r.Body).Decode(configuration); err != nil { if err := h.cfg.NewXMLDecoder(r.Body).Decode(configuration); err != nil {
h.logAndSendError(w, "couldn't decode versioning configuration", reqInfo, errors.GetAPIError(errors.ErrIllegalVersioningConfigurationException)) h.logAndSendError(ctx, w, "couldn't decode versioning configuration", reqInfo, errors.GetAPIError(errors.ErrIllegalVersioningConfigurationException))
return return
} }
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get bucket settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get bucket settings", reqInfo, err)
return return
} }
if configuration.Status != data.VersioningEnabled && configuration.Status != data.VersioningSuspended { if configuration.Status != data.VersioningEnabled && configuration.Status != data.VersioningSuspended {
h.logAndSendError(w, "invalid versioning configuration", reqInfo, errors.GetAPIError(errors.ErrMalformedXML)) h.logAndSendError(ctx, w, "invalid versioning configuration", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
return return
} }
@ -45,33 +46,34 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
} }
if p.Settings.VersioningSuspended() && bktInfo.ObjectLockEnabled { if p.Settings.VersioningSuspended() && bktInfo.ObjectLockEnabled {
h.logAndSendError(w, "couldn't suspend bucket versioning", reqInfo, errors.GetAPIError(errors.ErrObjectLockConfigurationVersioningCannotBeChanged)) h.logAndSendError(ctx, w, "couldn't suspend bucket versioning", reqInfo, errors.GetAPIError(errors.ErrObjectLockConfigurationVersioningCannotBeChanged))
return return
} }
if err = h.obj.PutBucketSettings(r.Context(), p); err != nil { if err = h.obj.PutBucketSettings(ctx, p); err != nil {
h.logAndSendError(w, "couldn't put update versioning settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't put update versioning settings", reqInfo, err)
} }
} }
// GetBucketVersioningHandler implements bucket versioning getter handler. // GetBucketVersioningHandler implements bucket versioning getter handler.
func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := middleware.GetReqInfo(r.Context()) ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil { if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err) h.logAndSendError(ctx, w, "could not get bucket info", reqInfo, err)
return return
} }
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(ctx, bktInfo)
if err != nil { if err != nil {
h.logAndSendError(w, "couldn't get version settings", reqInfo, err) h.logAndSendError(ctx, w, "couldn't get version settings", reqInfo, err)
return return
} }
if err = middleware.EncodeToResponse(w, formVersioningConfiguration(settings)); err != nil { if err = middleware.EncodeToResponse(w, formVersioningConfiguration(settings)); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err) h.logAndSendError(ctx, w, "something went wrong", reqInfo, err)
} }
} }

View file

@ -187,14 +187,21 @@ func Request(log *zap.Logger, settings RequestSettings) Func {
r = r.WithContext(treepool.SetRequestID(r.Context(), reqInfo.RequestID)) r = r.WithContext(treepool.SetRequestID(r.Context(), reqInfo.RequestID))
reqLogger := log.With(zap.String("request_id", reqInfo.RequestID)) fields := []zap.Field{zap.String("request_id", reqInfo.RequestID)}
r = r.WithContext(SetReqLogger(r.Context(), reqLogger)) ctx, span := StartHTTPServerSpan(r, "REQUEST S3")
if traceID := span.SpanContext().TraceID(); traceID.IsValid() {
fields = append(fields, zap.String("trace_id", traceID.String()))
}
lw := &traceResponseWriter{ResponseWriter: w, ctx: ctx, span: span}
reqLogger := log.With(fields...)
r = r.WithContext(SetReqLogger(ctx, reqLogger))
reqLogger.Info(logs.RequestStart, zap.String("host", r.Host), reqLogger.Info(logs.RequestStart, zap.String("host", r.Host),
zap.String("remote_host", reqInfo.RemoteHost), zap.String("namespace", reqInfo.Namespace)) zap.String("remote_host", reqInfo.RemoteHost), zap.String("namespace", reqInfo.Namespace))
// continue execution // continue execution
h.ServeHTTP(w, r) h.ServeHTTP(lw, r)
}) })
} }
} }

View file

@ -11,7 +11,6 @@ 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/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/version" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/version"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -332,10 +331,6 @@ func LogSuccessResponse(l *zap.Logger) Func {
fields = append(fields, zap.String("user", reqInfo.User)) fields = append(fields, zap.String("user", reqInfo.User))
} }
if traceID, err := trace.TraceIDFromHex(reqInfo.TraceID); err == nil && traceID.IsValid() {
fields = append(fields, zap.String("trace_id", reqInfo.TraceID))
}
reqLogger.Info(logs.RequestEnd, fields...) reqLogger.Info(logs.RequestEnd, fields...)
}) })
} }

View file

@ -11,20 +11,6 @@ import (
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
// Tracing adds tracing support for requests.
// Must be placed after prepareRequest middleware.
func Tracing() Func {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
appCtx, span := StartHTTPServerSpan(r, "REQUEST S3")
reqInfo := GetReqInfo(r.Context())
reqInfo.TraceID = span.SpanContext().TraceID().String()
lw := &traceResponseWriter{ResponseWriter: w, ctx: appCtx, span: span}
h.ServeHTTP(lw, r.WithContext(appCtx))
})
}
}
type traceResponseWriter struct { type traceResponseWriter struct {
sync.Once sync.Once
http.ResponseWriter http.ResponseWriter

View file

@ -134,7 +134,6 @@ func NewRouter(cfg Config) *chi.Mux {
s3middleware.Request(cfg.Log, cfg.MiddlewareSettings), s3middleware.Request(cfg.Log, cfg.MiddlewareSettings),
middleware.ThrottleWithOpts(cfg.Throttle), middleware.ThrottleWithOpts(cfg.Throttle),
middleware.Recoverer, middleware.Recoverer,
s3middleware.Tracing(),
s3middleware.Metrics(cfg.Log, cfg.Handler.ResolveCID, cfg.Metrics, cfg.MiddlewareSettings), s3middleware.Metrics(cfg.Log, cfg.Handler.ResolveCID, cfg.Metrics, cfg.MiddlewareSettings),
s3middleware.LogSuccessResponse(cfg.Log), s3middleware.LogSuccessResponse(cfg.Log),
s3middleware.Auth(cfg.Center, cfg.Log), s3middleware.Auth(cfg.Center, cfg.Log),