Skip to content

Commit d2086e8

Browse files
pavel-ptashytscodex
andcommitted
Avoid rebuilding clean query strings
Add a lazy query-string encoder that mirrors the existing path encoder fast path. When a query contains only pass-through characters, UriEncoder now reuses the original String instead of allocating a pooled StringBuilder and an equal replacement String. The append-based path is unchanged for URLs with additional query params. Existing escaping behavior is preserved for queries that need percent-encoding. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex <codex@openai.com>
1 parent c8071b5 commit d2086e8

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

client/src/main/java/org/asynchttpclient/util/UriEncoder.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ protected String withQueryWithParams(final String query, final List<Param> query
6262
@Override
6363
protected String withQueryWithoutParams(final String query) {
6464
// encode query
65-
StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder();
66-
encodeAndAppendQuery(sb, query);
67-
return sb.toString();
65+
return Utf8UrlEncoder.encodeQuery(query);
6866
}
6967

7068
@Override

client/src/main/java/org/asynchttpclient/util/Utf8UrlEncoder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ public static String encodePath(String input) {
129129
return sb == null ? input : sb.toString();
130130
}
131131

132+
public static String encodeQuery(String input) {
133+
StringBuilder sb = lazyAppendEncoded(null, input, BUILT_QUERY_UNTOUCHED_CHARS, false);
134+
return sb == null ? input : sb.toString();
135+
}
136+
132137
public static StringBuilder encodeAndAppendQuery(StringBuilder sb, String query) {
133138
return appendEncoded(sb, query, BUILT_QUERY_UNTOUCHED_CHARS, false);
134139
}

client/src/test/java/org/asynchttpclient/util/Utf8UrlEncoderTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import io.github.artsok.RepeatedIfExceptionsTest;
1919

2020
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertNotSame;
22+
import static org.junit.jupiter.api.Assertions.assertSame;
2123

2224
public class Utf8UrlEncoderTest {
2325

@@ -28,6 +30,22 @@ public void testBasics() {
2830
assertEquals("a%2Bb", Utf8UrlEncoder.encodeQueryElement("a+b"));
2931
}
3032

33+
@RepeatedIfExceptionsTest(repeats = 5)
34+
public void encodeQueryReusesInputWhenNothingNeedsEscaping() {
35+
String query = "a=1&b=/two?c%20d";
36+
37+
assertSame(query, Utf8UrlEncoder.encodeQuery(query));
38+
}
39+
40+
@RepeatedIfExceptionsTest(repeats = 5)
41+
public void encodeQueryEscapesWhenNeeded() {
42+
String query = "a=one two";
43+
String encoded = Utf8UrlEncoder.encodeQuery(query);
44+
45+
assertNotSame(query, encoded);
46+
assertEquals("a=one%20two", encoded);
47+
}
48+
3149
@RepeatedIfExceptionsTest(repeats = 5)
3250
public void testPercentageEncoding() {
3351
assertEquals("foobar", Utf8UrlEncoder.percentEncodeQueryElement("foobar"));

0 commit comments

Comments
 (0)