diff --git a/core/src/main/java/org/jclouds/http/Uris.java b/core/src/main/java/org/jclouds/http/Uris.java index abab52b096..facc181583 100644 --- a/core/src/main/java/org/jclouds/http/Uris.java +++ b/core/src/main/java/org/jclouds/http/Uris.java @@ -28,17 +28,13 @@ import static org.jclouds.util.Strings2.urlEncode; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; -import java.util.Collection; import java.util.Map; import org.jclouds.javax.annotation.Nullable; import com.google.common.annotations.Beta; -import com.google.common.base.Function; -import com.google.common.collect.ForwardingMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; @@ -103,7 +99,7 @@ public final class Uris { private String host; private Integer port; private String path; - private Multimap query = DecodingMultimap.create(); + private Multimap query = LinkedHashMultimap.create(); /** * override default of {@code / : ; =} @@ -274,10 +270,12 @@ public final class Uris { this.scheme = uri.getScheme(); this.host = uri.getHost(); this.port = uri.getPort() == -1 ? null : uri.getPort(); - if (uri.getPath() != null) - path(unescapeSpecialChars(uri.getPath())); - if (uri.getQuery() != null) - query(queryParser().apply(unescapeSpecialChars(uri.getQuery()))); + if (uri.getRawPath() != null) + // path decodes the string, so we need to get at the raw (encoded) string + path(unescapeSpecialChars(uri.getRawPath())); + if (uri.getRawQuery() != null) + // The query parser decodes the strings that are passed to it; we should pass raw (encoded) queries + query(queryParser().apply(unescapeSpecialChars(uri.getRawQuery()))); } public URI build() { @@ -372,53 +370,4 @@ public final class Uris { return new StringBuilder().append('/').append(in).toString(); return in; } - - /** - * Mutable and permits null values. Url decodes all mutations except {@link Multimap#putAll(Multimap)} - * - * - */ - static final class DecodingMultimap extends ForwardingMultimap { - - private static Multimap create() { - return new DecodingMultimap(); - } - - private final Multimap delegate = LinkedHashMultimap.create(); - private final Function urlDecoder = new Function() { - public Object apply(Object in) { - if (in == null) { - return null; - } - return urlDecode(in.toString()); - } - }; - - @Override - public boolean put(String key, Object value) { - return super.put(urlDecode(key), urlDecoder.apply(value)); - } - - @Override - public boolean putAll(String key, Iterable values) { - return super.putAll(urlDecode(key), Iterables.transform(values, urlDecoder)); - } - - @Override - public boolean putAll(Multimap multimap) { - return super.putAll(multimap); - } - - @Override - public Collection replaceValues(String key, Iterable values) { - return super.replaceValues(urlDecode(key), Iterables.transform(values, urlDecoder)); - } - - @Override - protected Multimap delegate() { - return delegate; - } - - } - } diff --git a/core/src/main/java/org/jclouds/util/Strings2.java b/core/src/main/java/org/jclouds/util/Strings2.java index e58e0a2d31..28ba26c279 100644 --- a/core/src/main/java/org/jclouds/util/Strings2.java +++ b/core/src/main/java/org/jclouds/util/Strings2.java @@ -88,12 +88,6 @@ public class Strings2 { public static boolean isCidrFormat(String in) { return CIDR_PATTERN.matcher(in).matches(); } - - private static final Pattern URL_ENCODED_PATTERN = Pattern.compile(".*%[a-fA-F0-9][a-fA-F0-9].*"); - - public static boolean isUrlEncoded(String in) { - return URL_ENCODED_PATTERN.matcher(in).matches(); - } /** * url decodes the input param, if set. @@ -107,9 +101,6 @@ public class Strings2 { public static String urlDecode(@Nullable String in) { if (in == null) return null; - if (!isUrlEncoded(in)) { - return in; - } String input = in.toString(); try { return URLDecoder.decode(input, "UTF-8"); diff --git a/core/src/test/java/org/jclouds/http/HttpRequestTest.java b/core/src/test/java/org/jclouds/http/HttpRequestTest.java index 73ad8b53e4..ffdaadfbc0 100644 --- a/core/src/test/java/org/jclouds/http/HttpRequestTest.java +++ b/core/src/test/java/org/jclouds/http/HttpRequestTest.java @@ -23,6 +23,7 @@ import java.net.URI; import org.jclouds.io.Payload; import org.jclouds.io.Payloads; +import org.jclouds.util.Strings2; import org.testng.annotations.Test; import com.google.common.collect.ImmutableMultimap; @@ -67,8 +68,8 @@ public class HttpRequestTest { // note that + ends up encoded as %2B (plus) and %2F converts back into slash public void testAddBase64AndUrlEncodedQueryParams() { - String base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%2B%2F%3D"; - URI uri = URI.create("http://goo.com:443?header1=" + base64Chars); + String base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + URI uri = URI.create("http://goo.com:443?header1=" + Strings2.urlEncode(base64Chars)); HttpRequest request = HttpRequest.builder() .method("GET") .endpoint(uri) diff --git a/core/src/test/java/org/jclouds/util/Strings2Test.java b/core/src/test/java/org/jclouds/util/Strings2Test.java index 125e0eb4fa..bbfbfee848 100644 --- a/core/src/test/java/org/jclouds/util/Strings2Test.java +++ b/core/src/test/java/org/jclouds/util/Strings2Test.java @@ -27,16 +27,6 @@ import com.google.common.collect.ImmutableMap; @Test(groups = "unit") public class Strings2Test { - public void testIsEncoded() { - assert Strings2.isUrlEncoded("/read-tests/%73%6f%6d%65%20%66%69%6c%65"); - assert !Strings2.isUrlEncoded("/read-tests/ tep"); - } - - public void testNoDoubleDecode() { - assertEquals(urlDecode("foo%20bar%2Bbaz"), "foo bar+baz"); - assertEquals(urlDecode("foo bar+baz"), "foo bar+baz"); - } - public void testReplaceTokens() { assertEquals(Strings2.replaceTokens("hello {where}", ImmutableMap.of("where", "world")), "hello world"); }