From 968ea3a608db8d7763c03c1dc9f5af7f9c2d87b1 Mon Sep 17 00:00:00 2001 From: Evgenii Baidakov Date: Mon, 28 Oct 2024 14:30:20 +0400 Subject: [PATCH] layer: Return error if previous part is missing Closes #1015. The error code copied from https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList. Signed-off-by: Evgenii Baidakov --- api/layer/multipart_upload.go | 5 +++++ api/s3errors/errors.go | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/api/layer/multipart_upload.go b/api/layer/multipart_upload.go index 5c39e58b..902be1d2 100644 --- a/api/layer/multipart_upload.go +++ b/api/layer/multipart_upload.go @@ -267,6 +267,11 @@ func (n *layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf return nil, fmt.Errorf("getLastPart: %w", err) } + // The previous part is not uploaded yet. + if lastPart == nil { + return nil, s3errors.GetAPIError(s3errors.ErrOperationAborted) + } + // try to restore hash state from the last part. // the required interface is guaranteed according to the docs, so just cast without checks. binaryUnmarshaler := multipartHash.(encoding.BinaryUnmarshaler) diff --git a/api/s3errors/errors.go b/api/s3errors/errors.go index 36421cea..b83d613d 100644 --- a/api/s3errors/errors.go +++ b/api/s3errors/errors.go @@ -268,6 +268,7 @@ const ( ErrEvaluatorBindingDoesNotExist ErrMissingHeaders ErrInvalidColumnIndex + ErrOperationAborted ErrPostPolicyConditionInvalidFormat @@ -1682,6 +1683,12 @@ var errorCodes = errorCodeMap{ Description: "Part number must be an integer between 1 and 10000, inclusive", HTTPStatusCode: http.StatusBadRequest, }, + ErrOperationAborted: { + ErrCode: ErrOperationAborted, + Code: "OperationAborted", + Description: "A conflicting conditional operation is currently in progress against this resource. Try again.", + HTTPStatusCode: http.StatusConflict, + }, // Add your error structure here. }