This is an automated email from the ASF dual-hosted git repository.
chungen0126 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 9ff43fef43f HDDS-16004. Return NotImplemented for GetObjectTorrent
instead of GetObject body (#10899)
9ff43fef43f is described below
commit 9ff43fef43f6d65ac56d1afe82c8746a64ff6fa6
Author: Mark Tsai <[email protected]>
AuthorDate: Thu Aug 6 10:49:24 2026 +0800
HDDS-16004. Return NotImplemented for GetObjectTorrent instead of GetObject
body (#10899)
---
.../ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java | 30 ++++++++++++
.../ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java | 20 ++++++++
.../org/apache/hadoop/ozone/audit/S3GAction.java | 1 +
.../hadoop/ozone/s3/endpoint/ObjectEndpoint.java | 1 +
.../ozone/s3/endpoint/ObjectGetTorrentHandler.java | 48 +++++++++++++++++++
.../org/apache/hadoop/ozone/s3/util/S3Consts.java | 2 +
.../ozone/s3/endpoint/TestObjectGetTorrent.java | 54 ++++++++++++++++++++++
7 files changed, 156 insertions(+)
diff --git
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
index 8ef4bdcd83a..f95d7de9bb9 100644
---
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
+++
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
@@ -2454,6 +2454,36 @@ public void testPresignedUrlGet() throws IOException {
}
}
+ @Test
+ public void testPresignedUrlGetObjectTorrentNotImplemented() throws
Exception {
+ final String keyName = getKeyName();
+
+ InputStream is = new
ByteArrayInputStream(CONTENT.getBytes(StandardCharsets.UTF_8));
+ s3Client.putObject(BUCKET_NAME, keyName, is, new ObjectMetadata());
+
+ // AmazonS3 (SDK v1) has no getObjectTorrent API, so exercise the same
HTTP behavior
+ // via a presigned URL with the torrent query parameter, as with other
request shapes
+ // the typed v1 API doesn't expose.
+ GeneratePresignedUrlRequest generatePresignedUrlRequest =
+ new GeneratePresignedUrlRequest(BUCKET_NAME,
keyName).withMethod(HttpMethod.GET).withExpiration(expiration);
+ generatePresignedUrlRequest.addRequestParameter("torrent", "");
+ URL presignedUrl =
s3Client.generatePresignedUrl(generatePresignedUrlRequest);
+
+ HttpURLConnection connection = null;
+ try {
+ connection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, "GET",
null, null);
+ assertEquals(HttpURLConnection.HTTP_NOT_IMPLEMENTED,
connection.getResponseCode());
+ } finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+
+ // object must be untouched
+ ObjectMetadata metadata = s3Client.getObjectMetadata(BUCKET_NAME,
keyName);
+ assertEquals(CONTENT.length(), metadata.getContentLength());
+ }
+
@Test
public void testPresignedUrlHead() throws IOException {
final String keyName = getKeyName();
diff --git
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
index 096c154bf66..dfe570d23c4 100644
---
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
+++
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
@@ -640,6 +640,26 @@ public void testGetObjectUnreadableKey() {
assertEquals(S3ErrorTable.INVALID_URI.getErrorMessage(),
exception.awsErrorDetails().errorMessage());
}
+ @Test
+ public void testGetObjectTorrentNotImplemented() {
+ final String bucketName = getBucketName();
+ final String keyName = getKeyName();
+ final String content = "bar";
+ s3Client.createBucket(b -> b.bucket(bucketName));
+ s3Client.putObject(b -> b.bucket(bucketName).key(keyName),
RequestBody.fromString(content));
+
+ S3Exception exception = assertThrows(S3Exception.class,
+ () -> s3Client.getObjectTorrent(b ->
b.bucket(bucketName).key(keyName)));
+
+ assertEquals(501, exception.statusCode());
+ assertEquals(S3ErrorTable.NOT_IMPLEMENTED.getCode(),
exception.awsErrorDetails().errorCode());
+ assertEquals(S3ErrorTable.NOT_IMPLEMENTED.getErrorMessage(),
exception.awsErrorDetails().errorMessage());
+
+ // object must be untouched
+ HeadObjectResponse headObjectResponse = s3Client.headObject(b ->
b.bucket(bucketName).key(keyName));
+ assertEquals(content.length(), headObjectResponse.contentLength());
+ }
+
@Test
public void testHeadObjectIfMatch() {
final String bucketName = getBucketName();
diff --git
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
index e46f4d53f9f..11efd4e9064 100644
---
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
+++
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
@@ -55,6 +55,7 @@ public enum S3GAction implements AuditAction {
CREATE_DIRECTORY,
GENERATE_SECRET,
REVOKE_SECRET,
+ GET_OBJECT_TORRENT,
GET_OBJECT_TAGGING,
PUT_OBJECT_TAGGING,
DELETE_OBJECT_TAGGING,
diff --git
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
index ad798e36989..0fa629764e5 100644
---
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
+++
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
@@ -149,6 +149,7 @@ public ObjectEndpoint() {
protected void init() {
super.init();
ObjectOperationHandler chain = ObjectOperationHandlerChain.newBuilder(this)
+ .add(new ObjectGetTorrentHandler())
.add(new ObjectAclHandler())
.add(new ObjectTaggingHandler())
.add(new MultipartKeyHandler())
diff --git
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectGetTorrentHandler.java
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectGetTorrentHandler.java
new file mode 100644
index 00000000000..312d323d803
--- /dev/null
+++
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectGetTorrentHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3.endpoint;
+
+import static
org.apache.hadoop.ozone.s3.exception.S3ErrorTable.NOT_IMPLEMENTED;
+import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.newError;
+
+import java.io.IOException;
+import javax.ws.rs.core.Response;
+import org.apache.hadoop.ozone.audit.S3GAction;
+import org.apache.hadoop.ozone.s3.endpoint.ObjectEndpoint.ObjectRequestContext;
+import org.apache.hadoop.ozone.s3.exception.OS3Exception;
+import org.apache.hadoop.ozone.s3.util.S3Consts.QueryParams;
+
+/**
+ * Handles GET object {@code ?torrent} ({@code GetObjectTorrent}).
+ * <p>
+ * This operation is not implemented; previously the request incorrectly fell
+ * through to GetObject and returned the raw object body.
+ */
+class ObjectGetTorrentHandler extends ObjectOperationHandler {
+
+ @Override
+ Response handleGetRequest(ObjectRequestContext context, String keyName)
+ throws IOException, OS3Exception {
+ if (queryParams().get(QueryParams.TORRENT) == null) {
+ return null;
+ }
+
+ context.setAction(S3GAction.GET_OBJECT_TORRENT);
+ throw newError(NOT_IMPLEMENTED, "GetObjectTorrent");
+ }
+}
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 0d2122d999a..c8a2f7f4809 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
@@ -164,6 +164,8 @@ public static final class QueryParams {
public static final String PREFIX = "prefix";
public static final String START_AFTER = "start-after";
public static final String TAGGING = "tagging";
+ // GetObjectTorrent is not implemented
+ public static final String TORRENT = "torrent";
public static final String UPLOAD_ID = "uploadId";
public static final String UPLOAD_ID_MARKER = "upload-id-marker";
public static final String UPLOADS = "uploads";
diff --git
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectGetTorrent.java
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectGetTorrent.java
new file mode 100644
index 00000000000..4791d7cf006
--- /dev/null
+++
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectGetTorrent.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3.endpoint;
+
+import static
org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertErrorResponse;
+import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.get;
+
+import java.io.IOException;
+import org.apache.hadoop.ozone.client.OzoneClient;
+import org.apache.hadoop.ozone.client.OzoneClientStub;
+import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
+import org.apache.hadoop.ozone.s3.util.S3Consts.QueryParams;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/** Tests for {@code GET /{bucket}/{key}?torrent} ({@code GetObjectTorrent}).
*/
+public class TestObjectGetTorrent {
+
+ private static final String BUCKET_NAME = "b1";
+ private static final String KEY_NAME = "key1";
+ private ObjectEndpoint objectEndpoint;
+
+ @BeforeEach
+ public void setup() throws IOException {
+ final OzoneClient clientStub = new OzoneClientStub();
+ clientStub.getObjectStore().createS3Bucket(BUCKET_NAME);
+
+ objectEndpoint = EndpointBuilder.newObjectEndpointBuilder()
+ .setClient(clientStub)
+ .build();
+ }
+
+ @Test
+ public void getObjectTorrentIsNotImplemented() {
+ objectEndpoint.queryParamsForTest().set(QueryParams.TORRENT, "");
+
+ assertErrorResponse(S3ErrorTable.NOT_IMPLEMENTED, () ->
get(objectEndpoint, BUCKET_NAME, KEY_NAME));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]