You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2012/06/12 11:27:15 UTC

svn commit: r1349208 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/util/UnsafeUriCharactersEncoder.java test/java/org/apache/camel/util/UnsafeCharactersEncoderTest.java

Author: davsclaus
Date: Tue Jun 12 09:27:14 2012
New Revision: 1349208

URL: http://svn.apache.org/viewvc?rev=1349208&view=rev
Log:
CAMEL-5357: Fixed uri normalization to support % sign itself to be encoded as %25. Added explict % decimal encoding to normalization logic.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/UnsafeUriCharactersEncoder.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/util/UnsafeCharactersEncoderTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/UnsafeUriCharactersEncoder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/UnsafeUriCharactersEncoder.java?rev=1349208&r1=1349207&r2=1349208&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/UnsafeUriCharactersEncoder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/UnsafeUriCharactersEncoder.java Tue Jun 12 09:27:14 2012
@@ -20,6 +20,8 @@ import java.util.BitSet;
 
 /**
  * Encoder for unsafe URI characters.
+ * <p/>
+ * A good source for details is <a href="http://en.wikipedia.org/wiki/Url_encode">wikipedia url encode</a> article.
  */
 public final class UnsafeUriCharactersEncoder {
     private static BitSet unsafeCharacters;   
@@ -33,7 +35,7 @@ public final class UnsafeUriCharactersEn
         unsafeCharacters.set('<');
         unsafeCharacters.set('>');
         unsafeCharacters.set('#');
-        // unsafeCharacters.set('%');
+        unsafeCharacters.set('%');
         unsafeCharacters.set('{');
         unsafeCharacters.set('}');
         unsafeCharacters.set('|');
@@ -70,16 +72,32 @@ public final class UnsafeUriCharactersEn
         }
 
         // okay there are some unsafe characters so we do need to encode
+        // see details at: http://en.wikipedia.org/wiki/Url_encode
         StringBuilder sb = new StringBuilder();
-        for (char ch : chars) {
+        for (int i = 0; i < chars.length; i++) {
+            char ch = chars[i];
             if (ch > 0 && ch < 128 && unsafeCharacters.get(ch)) {
-                appendEscape(sb, (byte)ch);
+                // special for % sign as it may be a decimal encoded value
+                if (ch == '%') {
+                    char next = i + 1 < chars.length ? chars[i + 1] : ' ';
+                    char next2 = i + 2 < chars.length ? chars[i + 2] : ' ';
+
+                    if (isHexDigit(next) && isHexDigit(next2)) {
+                        // its already encoded (decimal encoded) so just append as is
+                        sb.append(ch);
+                    } else {
+                        // must escape then, as its an unsafe character
+                        appendEscape(sb, (byte)ch);
+                    }
+                } else {
+                    // must escape then, as its an unsafe character
+                    appendEscape(sb, (byte)ch);
+                }
             } else {
                 sb.append(ch);
             }
         }
         return sb.toString();
-
     }
 
     private static void appendEscape(StringBuilder sb, byte b) {
@@ -88,4 +106,13 @@ public final class UnsafeUriCharactersEn
         sb.append(HEX_DIGITS[(b >> 0) & 0x0f]);
     }
 
+    private static boolean isHexDigit(char ch) {
+        for (char hex : HEX_DIGITS) {
+            if (hex == ch) {
+                return true;
+            }
+        }
+        return false;
+    }
+
 }

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/UnsafeCharactersEncoderTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/UnsafeCharactersEncoderTest.java?rev=1349208&r1=1349207&r2=1349208&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/util/UnsafeCharactersEncoderTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/UnsafeCharactersEncoderTest.java Tue Jun 12 09:27:14 2012
@@ -19,9 +19,10 @@ package org.apache.camel.util;
 import junit.framework.TestCase;
 
 public class UnsafeCharactersEncoderTest extends TestCase {
+
     private void testEncoding(String before, String after) {
         String result = UnsafeUriCharactersEncoder.encode(before);
-        assertEquals("Get the wrong encoding result", result, after);
+        assertEquals("Get the wrong encoding result", after, result);
     }
     
     public void testQnameEncoder() {
@@ -39,4 +40,41 @@ public class UnsafeCharactersEncoderTest
         String noEncoding = "http://test.com/\uFD04";
         testEncoding(noEncoding, noEncoding);
     }
+
+    public void testPercentEncode() {
+        String beforeEncoding = "sql:select * from foo where bar like '%A'";
+        String afterEncoding = "sql:select%20*%20from%20foo%20where%20bar%20like%20'%25A'";
+        testEncoding(beforeEncoding, afterEncoding);
+    }
+
+    public void testPercentEncodeAlready() {
+        String beforeEncoding = "sql:select * from foo where bar like '%25A'";
+        String afterEncoding = "sql:select%20*%20from%20foo%20where%20bar%20like%20'%25A'";
+        testEncoding(beforeEncoding, afterEncoding);
+    }
+
+    public void testPercentEncodeDanishChar() {
+        String beforeEncoding = "http://localhost:{{port}}/myapp/mytest?columns=claus,s\u00F8ren&username=apiuser";
+        String afterEncoding = "http://localhost:%7B%7Bport%7D%7D/myapp/mytest?columns=claus,s\u00F8ren&username=apiuser";
+        testEncoding(beforeEncoding, afterEncoding);
+    }
+
+    public void testPercentEncodeDanishCharEncoded() {
+        String beforeEncoding = "http://localhost:{{port}}/myapp/mytest?columns=claus,s%C3%B8ren&username=apiuser";
+        String afterEncoding = "http://localhost:%7B%7Bport%7D%7D/myapp/mytest?columns=claus,s%C3%B8ren&username=apiuser";
+        testEncoding(beforeEncoding, afterEncoding);
+    }
+
+    public void testAlreadyEncoded() {
+        String beforeEncoding = "http://www.example.com?query=foo%20bar";
+        String afterEncoding = "http://www.example.com?query=foo%20bar";
+        testEncoding(beforeEncoding, afterEncoding);
+    }
+
+    public void testPercentEncodedLast() {
+        String beforeEncoding = "http://www.example.com?like=foo%25";
+        String afterEncoding = "http://www.example.com?like=foo%25";
+        testEncoding(beforeEncoding, afterEncoding);
+    }
+
 }