Repository: brooklyn-server
Updated Branches:
  refs/heads/master 5c5d578f4 -> 422e025ea


Urls.encode(String) specifies UTF-8

Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/fa387821
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/fa387821
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/fa387821

Branch: refs/heads/master
Commit: fa387821a0594fbd107f0edcb1ee73144a30987b
Parents: 5c5d578
Author: Aled Sage <aled.s...@gmail.com>
Authored: Mon Feb 6 12:55:03 2017 +0000
Committer: Aled Sage <aled.s...@gmail.com>
Committed: Mon Feb 6 13:08:44 2017 +0000

----------------------------------------------------------------------
 .../java/org/apache/brooklyn/util/net/Urls.java | 36 +++++++++++++++---
 .../org/apache/brooklyn/util/net/UrlsTest.java  | 40 +++++++++++++++++++-
 2 files changed, 68 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fa387821/utils/common/src/main/java/org/apache/brooklyn/util/net/Urls.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/net/Urls.java 
b/utils/common/src/main/java/org/apache/brooklyn/util/net/Urls.java
index 717e8a2..ac60c96 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/net/Urls.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/net/Urls.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.util.net;
 
 import java.io.File;
+import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -30,6 +31,7 @@ import java.util.List;
 
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;
 
 import com.google.common.base.Function;
@@ -177,16 +179,38 @@ public class Urls {
         return result.toString();
     }
 
-    /** encodes the string suitable for use in a URL, using default character 
set
-     * (non-deprecated version of URLEncoder.encode) */
-    @SuppressWarnings("deprecation")
+    /**
+     * Encodes the string suitable for use in a URL, using default UTF-8 
+     * (version of URLEncoder.encode that does not throw checked exception)
+     */
     public static String encode(String text) {
-        return URLEncoder.encode(text);
+        /*
+         * TODO URLEncoder.encode is a HTML encoder, to make strings safe to 
use in 
+         * x-www-form-urlencoded. There is huge overlap between that and 
url-encoding, but
+         * they are not the same (e.g. space is converted to "+" rather than 
"%20", and
+         * "*" is not converted to "%2A").
+         * 
+         * Correct URL-encoding depends on which part of the URL it is. For 
example, guava's 
+         * UrlEscapers has separate escapers for path and fragment. Neither of 
these is 
+         * appropriate for escaping the password in 
"http://myusername@mypassword:myhost";.
+         * 
+         * org.apache.commons.codec.net.URLCodec behaves the same as 
java.net.URLEncoder: it 
+         * is for "www-form-urlencoded".
+         */
+        try {
+            return URLEncoder.encode(text, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw Exceptions.propagate(e);
+        }
     }
+    
     /** As {@link #encode(String)} */
-    @SuppressWarnings("deprecation")
     public static String decode(String text) {
-        return URLDecoder.decode(text);
+        try {
+            return URLDecoder.decode(text, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw Exceptions.propagate(e);
+        }
     }
 
     /** returns the protocol (e.g. http) if one appears to be specified, or 
else null;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fa387821/utils/common/src/test/java/org/apache/brooklyn/util/net/UrlsTest.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/test/java/org/apache/brooklyn/util/net/UrlsTest.java 
b/utils/common/src/test/java/org/apache/brooklyn/util/net/UrlsTest.java
index f775826..285fd8a 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/net/UrlsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/net/UrlsTest.java
@@ -32,7 +32,7 @@ public class UrlsTest {
         Assert.assertEquals(Urls.toUrl(u).toString(), u);
         Assert.assertEquals(Urls.toUri(u).toString(), u);
         Assert.assertEquals(Urls.toUri(Urls.toUrl(u)).toString(), u);
-        Assert.assertEquals(Urls.toUrl(Urls.toUri(u)).toString(), u);        
+        Assert.assertEquals(Urls.toUrl(Urls.toUri(u)).toString(), u);
     }
     
     @Test
@@ -50,7 +50,29 @@ public class UrlsTest {
 
     @Test
     public void testPathEncode() throws Exception {
-        assertEquals(Urls.encode("name_with/%!"), "name_with%2F%25%21");
+        encodeAndDecodeUrl("simple", "simple");
+        encodeAndDecodeUrl("name_with/%!", "name_with%2F%25%21");
+
+        StringBuilder allcharsBuilder = new StringBuilder();
+        for (int i = 1; i < 128; i++) {
+            if (i == 32 || i == 42) continue; // See 
testUserOrPasswordOrHostEncode()
+            allcharsBuilder.append((char)i);
+        }
+        String allchars = allcharsBuilder.toString();
+        encodeAndDecodeUrl(allchars, 
"%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%21%22%23%24%25%26%27%28%29%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F");
+    }
+
+    // TODO java.net.URLEncoder.encode() gets it wrong for:
+    //  " " (i.e. space - char %20). It turns that into "+" in the url.
+    //  "*" (i.e char %2A) is not escaped - this is wrong according to 
https://en.wikipedia.org/wiki/Percent-encoding (RFC 3986).
+    @Test(groups="Broken")
+    public void testUserOrPasswordOrHostEncode() throws Exception {
+        StringBuilder passwordBuilder = new StringBuilder();
+        for (int i = 1; i < 128; i++) {
+            passwordBuilder.append((char)i);
+        }
+        String allchars = passwordBuilder.toString();
+        encodeAndDecodeUrl(allchars, 
"%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F");
     }
 
     @Test
@@ -88,4 +110,18 @@ public class UrlsTest {
         // tests for parsing are in core in ResourceUtilsTest
     }
 
+
+    @Test
+    public void testEncodeAndDecodeUrl() throws Exception {
+        encodeAndDecodeUrl("simple", "simple");
+        encodeAndDecodeUrl("!@#$%^&*", "%21%40%23%24%25%5E%26*"); // TODO "*" 
should really be encoded!
+        encodeAndDecodeUrl("a/b", "a%2Fb");
+    }
+    
+    private void encodeAndDecodeUrl(String val, String expectedEncoding) {
+        String actualEncoding = Urls.encode(val);
+        String actualDecoded = Urls.decode(actualEncoding);
+        assertEquals(actualDecoded, val, "Encode+decode does not match 
original: orig="+val+"; decoded="+actualDecoded);
+        assertEquals(actualEncoding, expectedEncoding, "Does not match 
expected encoding: orig="+val+"; decoded="+actualDecoded);
+    }
 }

Reply via email to