diff --git a/client/src/main/java/org/asynchttpclient/util/UriEncoder.java b/client/src/main/java/org/asynchttpclient/util/UriEncoder.java index d205aed6f..d94d0770b 100644 --- a/client/src/main/java/org/asynchttpclient/util/UriEncoder.java +++ b/client/src/main/java/org/asynchttpclient/util/UriEncoder.java @@ -62,9 +62,7 @@ protected String withQueryWithParams(final String query, final List query @Override protected String withQueryWithoutParams(final String query) { // encode query - StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder(); - encodeAndAppendQuery(sb, query); - return sb.toString(); + return Utf8UrlEncoder.encodeQuery(query); } @Override diff --git a/client/src/main/java/org/asynchttpclient/util/Utf8UrlEncoder.java b/client/src/main/java/org/asynchttpclient/util/Utf8UrlEncoder.java index fe01e3208..cd7a7801c 100644 --- a/client/src/main/java/org/asynchttpclient/util/Utf8UrlEncoder.java +++ b/client/src/main/java/org/asynchttpclient/util/Utf8UrlEncoder.java @@ -129,6 +129,12 @@ public static String encodePath(String input) { return sb == null ? input : sb.toString(); } + // package-private: only UriEncoder (same package) needs this; keep API surface minimal + static String encodeQuery(String input) { + StringBuilder sb = lazyAppendEncoded(null, input, BUILT_QUERY_UNTOUCHED_CHARS, false); + return sb == null ? input : sb.toString(); + } + public static StringBuilder encodeAndAppendQuery(StringBuilder sb, String query) { return appendEncoded(sb, query, BUILT_QUERY_UNTOUCHED_CHARS, false); } diff --git a/client/src/test/java/org/asynchttpclient/util/Utf8UrlEncoderTest.java b/client/src/test/java/org/asynchttpclient/util/Utf8UrlEncoderTest.java index ee3966cf0..83268fc13 100644 --- a/client/src/test/java/org/asynchttpclient/util/Utf8UrlEncoderTest.java +++ b/client/src/test/java/org/asynchttpclient/util/Utf8UrlEncoderTest.java @@ -15,20 +15,39 @@ */ package org.asynchttpclient.util; -import io.github.artsok.RepeatedIfExceptionsTest; +import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; public class Utf8UrlEncoderTest { - @RepeatedIfExceptionsTest(repeats = 5) + @Test public void testBasics() { assertEquals("foobar", Utf8UrlEncoder.encodeQueryElement("foobar")); assertEquals("a%26b", Utf8UrlEncoder.encodeQueryElement("a&b")); assertEquals("a%2Bb", Utf8UrlEncoder.encodeQueryElement("a+b")); } - @RepeatedIfExceptionsTest(repeats = 5) + @Test + public void encodeQueryReusesInputWhenNothingNeedsEscaping() { + String query = "a=1&b=/two?c%20d"; + + assertSame(query, Utf8UrlEncoder.encodeQuery(query)); + } + + @Test + public void encodeQueryEscapesWhenNeeded() { + String query = "a=one two"; + String encoded = Utf8UrlEncoder.encodeQuery(query); + + assertNotSame(query, encoded); + assertEquals("a=one%20two", encoded); + assertEquals("a=%C3%A9", Utf8UrlEncoder.encodeQuery("a=\u00e9")); + } + + @Test public void testPercentageEncoding() { assertEquals("foobar", Utf8UrlEncoder.percentEncodeQueryElement("foobar")); assertEquals("foo%2Abar", Utf8UrlEncoder.percentEncodeQueryElement("foo*bar"));