You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ozone.apache.org by "Gargi-jais11 (via GitHub)" <gi...@apache.org> on 2026/07/17 04:34:24 UTC

[PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) end-to-end in S3 Gateway [ozone]

Gargi-jais11 opened a new pull request, #10786:
URL: https://github.com/apache/ozone/pull/10786

   ## What changes were proposed in this pull request?
   Ozone does not persist standard S3 object headers on PUT or return them on HEAD/GET. s3-tests fail for:
   
   - Cache-Control (no-cache from NoCacheFilter instead of stored value) - test_object_write_cache_control,
   - Expires (off by 6000s because filter sets Expires=now) - test_object_write_expires, and
   - Content-Encoding (KeyError on HEAD) -test_object_content_encoding_aws_chunked.
   
   Implement persist-on-PUT and return-on-HEAD/GET for these headers, strip aws-chunked from Content-Encoding per AWS semantics, and ensure object headers override HDDS NoCacheFilter defaults on S3 object responses.
   
   ## What is the link to the Apache JIRA
   
   https://issues.apache.org/jira/browse/HDDS-15606
   
   ## How was this patch tested?
   
   Added IT and UT.
   
   **Before Fix:**
   ```
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object \
     --bucket testbucket \
     --key foo \
     --body /tmp/foo-body \
     --cache-control "public, max-age=14400"
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api head-object \
     --bucket testbucket \
     --key foo \
     --query 'CacheControl'
   "no-cache"                    <---------------- wrong output
   
   
   bash-5.1$ EXPIRES=$(date -u -v+6000S '+%a, %d %b %Y %H:%M:%S GMT' 2>/dev/null \
     || date -u -d '+6000 seconds' '+%a, %d %b %Y %H:%M:%S GMT')
   aws --endpoint-url $ENDPOINT s3api put-object \
     --bucket testbucket \
     --key foo-expires \
     --body /tmp/foo-body \
     --expires "$EXPIRES"
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api head-object \
     --bucket testbucket \
     --key foo-expires \
     --query 'Expires'
   "Thu, 16 Jul 2026 11:58:46 GMT"                     <---------------- wrong output
   
   
   bash-5.1$ KEY=encoding
   aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding gzip
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   null                     <---------------- wrong output
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding "deflate, gzip"
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   null                    <---------------- wrong output
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding "gzip, aws-chunked"
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   null                    <---------------- wrong output
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding "aws-chunked"
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   null
   ```
   **After Fix:**
   ```
   bash-5.1$ ozone sh bucket create /s3v/testbucket
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object \
     --bucket testbucket \
     --key foo \
     --body /tmp/foo-body \
     --cache-control "public, max-age=14400"
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api head-object \
     --bucket testbucket \
     --key foo \
     --query 'CacheControl'
   "public, max-age=14400"                <-------------Fixed
   
   ------------
   ------------
   
   bash-5.1$ aws --endpoint-url http://s3g:9878/ s3api put-object   --bucket testbucket --key foo --body /tmp/foo-body   --expires "Wed, 21 Oct 2026 07:50:00 GMT"
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   bash-5.1$ aws --endpoint-url http://s3g:9878/ s3api head-object \
     --bucket testbucket --key foo --query Expires
   "Wed, 21 Oct 2026 07:50:00 GMT"                <-------------Fixed
   
   ----------
   ----------
   
   bash-5.1$ KEY=encoding
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding gzip
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   "gzip"                <-------------Fixed
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding "deflate, gzip"
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   "deflate, gzip"                <-------------Fixed
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding "gzip, aws-chunked"
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   "gzip"                <-------------Fixed
   
   bash-5.1$ aws --endpoint-url $ENDPOINT s3api put-object --bucket testbucket --key $KEY --body /tmp/foo-body --content-encoding "aws-chunked"
   aws --endpoint-url $ENDPOINT s3api head-object --bucket testbucket --key $KEY --query 'ContentEncoding'
   {
       "ETag": "\"c157a79031e1c40f85931829bc5fc552\""
   }
   null                <-------------Fixed
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) [ozone]

Posted by "Gargi-jais11 (via GitHub)" <gi...@apache.org>.
Gargi-jais11 commented on code in PR #10786:
URL: https://github.com/apache/ozone/pull/10786#discussion_r3628063656


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java:
##########
@@ -120,15 +120,26 @@ public abstract class EndpointBase {
 
   protected static final String ETAG_CUSTOM = "etag-custom";
   protected static final String CONTENT_TYPE_CUSTOM = "content-type-custom";
+  protected static final String CACHE_CONTROL_CUSTOM = "cache-control-custom";

Review Comment:
   Good catch! Will change it.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) [ozone]

Posted by "Gargi-jais11 (via GitHub)" <gi...@apache.org>.
Gargi-jais11 commented on PR #10786:
URL: https://github.com/apache/ozone/pull/10786#issuecomment-5129141516

   Thanks @ArafatKhan2198 and @chungen0126 for reviewing the PR.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) [ozone]

Posted by "ArafatKhan2198 (via GitHub)" <gi...@apache.org>.
ArafatKhan2198 commented on code in PR #10786:
URL: https://github.com/apache/ozone/pull/10786#discussion_r3620479039


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Utils.java:
##########
@@ -73,6 +74,22 @@ public static String s3urlEncode(String str)
     return urlEncode(str).replace("+", "%20");
   }
 
+  /**
+   * Returns the persisted S3 {@code Content-Encoding} value, with {@code aws-chunked}

Review Comment:
   Handle `aws-chunked` without case sensitivity
   
   Currently, only this exact value is removed:
   
   ```
   aws-chunked
   ```
   
   These would not be removed:
   
   ```
   AWS-CHUNKED
   Aws-Chunked
   ```
   
   HTTP encoding names are case-insensitive, so the code should use:
   
   ```
   equalsIgnoreCase()
   ```



##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java:
##########
@@ -120,15 +120,26 @@ public abstract class EndpointBase {
 
   protected static final String ETAG_CUSTOM = "etag-custom";
   protected static final String CONTENT_TYPE_CUSTOM = "content-type-custom";
+  protected static final String CACHE_CONTROL_CUSTOM = "cache-control-custom";

Review Comment:
   The PR internally renames:
   
   ```
   x-amz-meta-cache-control
   ```
   
   to:
   
   ```
   cache-control-custom
   ```
   
   But a user can also provide:
   
   ```
   x-amz-meta-cache-control-custom
   ```
   
   Both values then use the same internal key, so one value can overwrite the other.
   The internal storage key should use a reserved namespace that users cannot create.



##########
hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectGet.java:
##########
@@ -221,12 +221,12 @@ public void getKeyWithTag() throws IOException, OS3Exception {
   }
 
   @Test
-  public void inheritRequestHeader() throws IOException, OS3Exception {
+  public void storedObjectHeadersOnGetAndHead() throws IOException, OS3Exception {

Review Comment:
   Add tests for copy and multipart upload
   
   The code changes normal upload, multipart upload, and object-copy behaviour.
   
   However, the integration tests mainly verify normal `PutObject`.
   
   Tests should also confirm that headers work correctly when:
   
   - uploading through multipart upload;
   - copying metadata with `COPY`;
   - replacing metadata with `REPLACE`.
   
   Overall, the main feature is implemented correctly, but these edge cases could cause incorrect headers or lost metadata.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) [ozone]

Posted by "chungen0126 (via GitHub)" <gi...@apache.org>.
chungen0126 commented on code in PR #10786:
URL: https://github.com/apache/ozone/pull/10786#discussion_r3649813032


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java:
##########
@@ -323,6 +342,10 @@ protected Map<String, String> getCustomMetadataFromHeaders(
       for (String key : customMetadataKeys) {
         String mapKey =
             key.substring(CUSTOM_METADATA_HEADER_PREFIX.length());
+        if (mapKey.regionMatches(true, 0, RESERVED_USER_METADATA_KEY_PREFIX, 0,
+            RESERVED_USER_METADATA_KEY_PREFIX.length())) {
+          throw newError(INVALID_ARGUMENT, key);

Review Comment:
   It would be better to add an error message to the exception so the client knows what went wrong.



##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Utils.java:
##########
@@ -162,7 +179,7 @@ public static void validateMultiChunksUpload(HttpHeaders headers, String amzDeco
       // We are only interested on "aws-chunked"
       boolean containsAwsChunked = Arrays.stream(contentEncoding.split(","))
           .map(String::trim)
-          .anyMatch(AWS_CHUNKED::equals);
+          .anyMatch(value -> AWS_CHUNKED.equalsIgnoreCase(value));

Review Comment:
   ```suggestion
             .anyMatch(AWS_CHUNKED::equalsIgnoreCase);
   ```



##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java:
##########
@@ -526,6 +522,46 @@ private void putContentType(Map<String, String> metadata) {
     }
   }
 
+  /**
+   * Store standard S3 object headers from the PUT request in key metadata.
+   */
+  private void putStandardObjectHeaders(Map<String, String> metadata) {
+    for (Map.Entry<String, String> entry : overrideQueryParameter.entrySet()) {
+      String headerName = entry.getKey();
+      String value = getHeaders().getHeaderString(headerName);
+      if (HttpHeaders.CONTENT_ENCODING.equals(headerName)) {
+        value = normalizeContentEncoding(value);
+      }
+      if (value != null) {
+        metadata.put(headerName, value);
+      }
+    }
+  }

Review Comment:
   ```suggestion
     private void putStandardObjectHeaders(Map<String, String> metadata) {
       for (String headerName : overrideQueryParameter.keySet()) {
         String value = getHeaders().getHeaderString(headerName);
         if (HttpHeaders.CONTENT_ENCODING.equals(headerName)) {
           value = normalizeContentEncoding(value);
         }
         if (value != null) {
           metadata.put(headerName, value);
         }
       }
     }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) [ozone]

Posted by "Gargi-jais11 (via GitHub)" <gi...@apache.org>.
Gargi-jais11 merged PR #10786:
URL: https://github.com/apache/ozone/pull/10786


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-15606. Support S3 object metadata headers (Cache-Control, Expires, Content-Encoding) [ozone]

Posted by "Gargi-jais11 (via GitHub)" <gi...@apache.org>.
Gargi-jais11 commented on PR #10786:
URL: https://github.com/apache/ozone/pull/10786#issuecomment-5113312594

   @ArafatKhan2198 and @chungen0126 I have updated both of ur review comments. Please take a look once.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org