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]