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

adoroszlai 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 377e8355bf6 HDDS-15694. Avoid String.replaceAll in 
StringToSignProducer.urlEncode() (#10619)
377e8355bf6 is described below

commit 377e8355bf65ab869486920d0f1b13bc4dcc0114
Author: fmorg-git <[email protected]>
AuthorDate: Sat Jun 27 01:21:08 2026 -0700

    HDDS-15694. Avoid String.replaceAll in StringToSignProducer.urlEncode() 
(#10619)
---
 .../ozone/s3/commontypes/ObjectKeyNameAdapter.java |  8 +++++--
 .../ozone/s3/signature/StringToSignProducer.java   |  8 +++----
 .../s3/signature/TestStringToSignProducer.java     | 28 ++++++++++++++++++++++
 .../hadoop/ozone/s3/signature/package-info.java    | 22 +++++++++++++++++
 4 files changed, 60 insertions(+), 6 deletions(-)

diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/commontypes/ObjectKeyNameAdapter.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/commontypes/ObjectKeyNameAdapter.java
index 092bc4ba509..2f3ee0bdcf7 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/commontypes/ObjectKeyNameAdapter.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/commontypes/ObjectKeyNameAdapter.java
@@ -19,6 +19,7 @@
 
 import java.io.UnsupportedEncodingException;
 import javax.xml.bind.annotation.adapters.XmlAdapter;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.ozone.s3.util.S3Utils;
 
 /**
@@ -27,6 +28,10 @@
  */
 public class ObjectKeyNameAdapter extends
     XmlAdapter<String, EncodingTypeObject> {
+
+  private static final String[] URL_ENCODE_SEARCH_CHARS = new String[] {"%2F"};
+  private static final String[] URL_ENCODE_REPLACE_CHARS = new String[] {"/"};
+
   @Override
   public EncodingTypeObject unmarshal(String s) {
     throw new UnsupportedOperationException();
@@ -36,8 +41,7 @@ public EncodingTypeObject unmarshal(String s) {
   public String marshal(EncodingTypeObject s)
       throws UnsupportedEncodingException {
     if (s.getEncodingType() != null && s.getEncodingType().equals("url")) {
-      return S3Utils.urlEncode(s.getName())
-          .replaceAll("%2F", "/");
+      return StringUtils.replaceEach(S3Utils.urlEncode(s.getName()), 
URL_ENCODE_SEARCH_CHARS, URL_ENCODE_REPLACE_CHARS);
     }
     return s.getName();
   }
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/signature/StringToSignProducer.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/signature/StringToSignProducer.java
index f308363133d..5e1ae4d89cd 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/signature/StringToSignProducer.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/signature/StringToSignProducer.java
@@ -62,6 +62,9 @@ public final class StringToSignProducer {
   private static final Charset UTF_8 = StandardCharsets.UTF_8;
   private static final String NEWLINE = "\n";
   public static final String HOST = "host";
+
+  private static final String[] URL_ENCODE_SEARCH_CHARS = new String[] {"+", 
"*", "%7E"};
+  private static final String[] URL_ENCODE_REPLACE_CHARS = new String[] 
{"%20", "%2A", "~"};
   /**
    * Seconds in a week, which is the max expiration time Sig-v4 accepts.
    */
@@ -282,10 +285,7 @@ private static Iterable<String> split(String regex, String 
whole) {
 
   private static String urlEncode(String str) {
     try {
-      return S3Utils.urlEncode(str)
-          .replaceAll("\\+", "%20")
-          .replaceAll("\\*", "%2A")
-          .replaceAll("%7E", "~");
+      return StringUtils.replaceEach(S3Utils.urlEncode(str), 
URL_ENCODE_SEARCH_CHARS, URL_ENCODE_REPLACE_CHARS);
     } catch (UnsupportedEncodingException e) {
       throw new RuntimeException(e);
     }
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/TestStringToSignProducer.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/TestStringToSignProducer.java
index cbce030ef69..9a2ce5bce82 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/TestStringToSignProducer.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/TestStringToSignProducer.java
@@ -19,6 +19,7 @@
 
 import static 
org.apache.hadoop.ozone.s3.exception.S3ErrorTable.S3_AUTHINFO_CREATION_ERROR;
 import static 
org.apache.hadoop.ozone.s3.signature.SignatureProcessor.DATE_FORMATTER;
+import static org.apache.hadoop.ozone.s3.util.S3Consts.UNSIGNED_PAYLOAD;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.params.provider.Arguments.arguments;
 import static org.mockito.Mockito.mock;
@@ -116,6 +117,33 @@ public void validateDateRange(Credential credentialObj) {
         signatureBase, "String to sign is invalid");
   }
 
+  @Test
+  public void testUrlEncodeInCanonicalRequest() {
+    final Map<String, String> headers = new HashMap<>();
+    headers.put("host", "example.com");
+    headers.put("x-amz-content-sha256", UNSIGNED_PAYLOAD);
+    headers.put("x-amz-date", DATETIME);
+
+    final Map<String, String> queryParams = new HashMap<>();
+    queryParams.put("q+1*2~3", "v 4*5~6");
+
+    final String canonicalRequest = StringToSignProducer.buildCanonicalRequest(
+        "https", "GET", "/bucket/a+b*c~d/foo bar", 
"host;x-amz-content-sha256;x-amz-date",
+        headers, queryParams, true);
+
+    assertEquals(
+        "GET\n"
+            + "/bucket/a%2Bb%2Ac~d/foo%20bar\n"
+            + "q%2B1%2A2~3=v%204%2A5~6\n"
+            + "host:example.com\n"
+            + "x-amz-content-sha256:" + UNSIGNED_PAYLOAD + "\n"
+            + "x-amz-date:" + DATETIME + "\n"
+            + "\n"
+            + "host;x-amz-content-sha256;x-amz-date\n"
+            + UNSIGNED_PAYLOAD,
+        canonicalRequest);
+  }
+
   private ContainerRequestContext setupContext(
       URI uri,
       String method,
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/package-info.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/package-info.java
new file mode 100644
index 00000000000..152b1b85c78
--- /dev/null
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/signature/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * Unit tests for AWS Signature V4 request canonicalization and signature base 
creation used by the S3 Gateway.
+ */
+package org.apache.hadoop.ozone.s3.signature;
+


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

Reply via email to