Ritesh Shukla created HDDS-17599:
------------------------------------

             Summary: S3G: DELETE with an empty uploadId deletes the object 
instead of failing as an abort
                 Key: HDDS-17599
                 URL: https://issues.apache.org/jira/browse/HDDS-17599
             Project: Apache Ozone
          Issue Type: Bug
          Components: S3
            Reporter: Ritesh Shukla
            Assignee: Ritesh Shukla


h3. Problem

An S3 {{DELETE}} on an object key means one of two things:
* {{DELETE /bucket/key?uploadId=<id>}} aborts a multipart upload 
(AbortMultipartUpload).
* {{DELETE /bucket/key}} deletes the object (DeleteObject).

When {{uploadId}} is present but empty, the S3 Gateway treats it as absent and 
deletes the committed object:

{code}
PUT    /bucket/key            -> 200, key created
DELETE /bucket/key?uploadId=  -> 204, key deleted
{code}

The request names an abort, so the client asked for no data to be removed, but 
the object is gone.

h3. Cause

{{MultipartKeyHandler#handleDeleteRequest}} returns {{null}} (not a multipart 
request, let the next handler run) when {{StringUtils.isEmpty(uploadId)}}. The 
chain then reaches {{ObjectEndpoint#handleDeleteRequest}}, which calls 
{{deleteKey}}.

The GET path in the same class already checks only for {{null}}, so {{GET 
/bucket/key?uploadId=}} is handled as ListParts rather than as a GetObject. The 
DELETE path is the inconsistent one. Ozone 2.0.0 had the same behaviour in the 
inline check in {{ObjectEndpoint#delete}}.

h3. Proposed fix

Treat only a missing {{uploadId}} as "not a multipart request". An empty 
{{uploadId}} names no upload, so fail with {{NoSuchUpload}}, recorded as a 
failed AbortMultipartUpload, and leave the key untouched.

h3. Testing

* Unit: {{TestObjectDelete}} puts a key, sends DELETE with an empty 
{{uploadId}}, and checks {{NoSuchUpload}} and that the key still exists. It 
fails before the fix, because the key is deleted.
* Acceptance: a new case in {{s3/objectdelete.robot}} does the same through a 
presigned AbortMultipartUpload URL ({{presigned_url_helper.py}} gains the 
helper; the AWS CLI rejects an empty upload ID). On the {{ozone}} compose 
cluster, it fails on master (the DELETE returns {{204 No Content}} and the 
object is gone) and passes with the fix.

----
🤖 Generated with [Claude Code|https://claude.com/claude-code]




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to