This is an automated email from the ASF dual-hosted git repository.

peterxcli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new b8a63126881 HDDS-15304. DeleteObjects should enforce the request key 
limit (#10309)
b8a63126881 is described below

commit b8a631268816056b3378d8f8a987b199a18a66f9
Author: sreejasahithi <[email protected]>
AuthorDate: Wed Jun 17 22:12:47 2026 +0530

    HDDS-15304. DeleteObjects should enforce the request key limit (#10309)
    
    Co-authored-by: Peter Lee <[email protected]>
---
 .../hadoop/ozone/s3/endpoint/BucketEndpoint.java   |  6 ++++
 .../org/apache/hadoop/ozone/s3/util/S3Consts.java  |  3 ++
 .../ozone/s3/endpoint/TestObjectMultiDelete.java   | 39 ++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
index 9301c235f40..d35da257cd0 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
@@ -62,6 +62,7 @@
 import org.apache.hadoop.ozone.s3.exception.OS3Exception;
 import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
 import org.apache.hadoop.ozone.s3.util.ContinueToken;
+import org.apache.hadoop.ozone.s3.util.S3Consts;
 import org.apache.hadoop.ozone.s3.util.S3Consts.QueryParams;
 import org.apache.hadoop.ozone.s3.util.S3StorageType;
 import org.apache.hadoop.util.Time;
@@ -337,6 +338,11 @@ public MultiDeleteResponse multiDelete(
   ) throws OS3Exception, IOException {
     S3GAction s3GAction = S3GAction.MULTI_DELETE;
 
+    if (request.getObjects() != null
+        && request.getObjects().size() > S3Consts.S3_DELETE_OBJECTS_MAX_KEYS) {
+      throw newError(S3ErrorTable.MALFORMED_XML, bucketName);
+    }
+
     OzoneBucket bucket = getVolume().getBucket(bucketName);
     MultiDeleteResponse result = new MultiDeleteResponse();
     List<String> deleteKeys = new ArrayList<>();
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Consts.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Consts.java
index c898ea78e4a..abc654f916e 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Consts.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Consts.java
@@ -95,6 +95,9 @@ public final class S3Consts {
   public static final Pattern TAG_REGEX_PATTERN = 
Pattern.compile("^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$");
   public static final String MP_PARTS_COUNT = "x-amz-mp-parts-count";
 
+  /** AWS S3 maximum number of keys per DeleteObjects request. */
+  public static final int S3_DELETE_OBJECTS_MAX_KEYS = 1000;
+
   // Bucket owner condition headers
   // See 
https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-owner-condition.html
   public static final String EXPECTED_BUCKET_OWNER_HEADER = 
"x-amz-expected-bucket-owner";
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectMultiDelete.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectMultiDelete.java
index 8b6c869b5d9..1d657460346 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectMultiDelete.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectMultiDelete.java
@@ -18,6 +18,8 @@
 package org.apache.hadoop.ozone.s3.endpoint;
 
 import static java.util.Collections.singleton;
+import static 
org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertErrorResponse;
+import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.MALFORMED_XML;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import com.google.common.collect.Sets;
@@ -32,6 +34,7 @@
 import org.apache.hadoop.ozone.client.OzoneKey;
 import org.apache.hadoop.ozone.s3.endpoint.MultiDeleteRequest.DeleteObject;
 import org.apache.hadoop.ozone.s3.exception.OS3Exception;
+import org.apache.hadoop.ozone.s3.util.S3Consts;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -101,6 +104,42 @@ public void deleteQuiet() throws IOException, 
OS3Exception, JAXBException {
     assertEquals(0, response.getErrors().size());
   }
 
+  @Test
+  public void multiDeleteRejectsMoreThanMaxKeysPerRequest() throws Exception {
+    OzoneClient client = new OzoneClientStub();
+    BucketEndpoint rest = EndpointBuilder.newBucketEndpointBuilder()
+        .setClient(client)
+        .build();
+
+    MultiDeleteRequest mdr = new MultiDeleteRequest();
+    for (int i = 0; i < S3Consts.S3_DELETE_OBJECTS_MAX_KEYS + 1; i++) {
+      mdr.getObjects().add(new DeleteObject("key-" + i));
+    }
+
+    assertErrorResponse(MALFORMED_XML, () -> rest.multiDelete("b1", "", mdr));
+  }
+
+  @Test
+  public void multiDeleteAllowsMaxKeysPerRequest() throws Exception {
+    OzoneClient client = new OzoneClientStub();
+    OzoneBucket bucket = initTestData(client);
+    BucketEndpoint rest = EndpointBuilder.newBucketEndpointBuilder()
+        .setClient(client)
+        .build();
+
+    MultiDeleteRequest mdr = new MultiDeleteRequest();
+    mdr.setQuiet(true);
+    for (int i = 0; i < S3Consts.S3_DELETE_OBJECTS_MAX_KEYS; i++) {
+      mdr.getObjects().add(new DeleteObject("missing-" + i));
+    }
+
+    MultiDeleteResponse response = rest.multiDelete("b1", "", mdr);
+    assertEquals(0, response.getDeletedObjects().size());
+    assertEquals(0, response.getErrors().size());
+
+    assertEquals(3, Sets.newHashSet(bucket.listKeys("")).size());
+  }
+
   private OzoneBucket initTestData(OzoneClient client) throws IOException {
     client.getObjectStore().createS3Bucket("b1");
 


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

Reply via email to