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]