camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [1/4] camel git commit: Fixed catalog to handle uris with property placeholders and other unsafe charachters
Date Wed, 11 Nov 2015 09:33:14 GMT
Repository: camel
Updated Branches:
  refs/heads/camel-2.16.x c73de90d2 -> af94e7839
  refs/heads/master 0589a1490 -> 19771345d


Fixed catalog to handle uris with property placeholders and other unsafe charachters


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

Branch: refs/heads/master
Commit: ed574cbd7faf246e02c775a2ff6101a775963f0f
Parents: 0589a14
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Wed Nov 11 10:36:01 2015 +0100
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Wed Nov 11 10:36:01 2015 +0100

----------------------------------------------------------------------
 .../camel/catalog/DefaultCamelCatalog.java      |   5 +-
 .../org/apache/camel/catalog/URISupport.java    |  11 +
 .../catalog/UnsafeUriCharactersEncoder.java     | 206 +++++++++++++++++++
 .../apache/camel/catalog/CamelCatalogTest.java  |  11 +
 4 files changed, 232 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ed574cbd/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
index 2471bb7..0cf52f0 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
@@ -44,6 +44,7 @@ import static org.apache.camel.catalog.CatalogHelper.after;
 import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyDefaultValue;
 import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyRequired;
 import static org.apache.camel.catalog.URISupport.createQueryString;
+import static org.apache.camel.catalog.URISupport.normalizeUri;
 import static org.apache.camel.catalog.URISupport.stripQuery;
 
 /**
@@ -464,8 +465,10 @@ public class DefaultCamelCatalog implements CamelCatalog {
         // NOTICE: This logic is similar to org.apache.camel.util.EndpointHelper#endpointProperties
         // as the catalog also offers similar functionality (without having camel-core on
classpath)
 
+        // need to normalize uri first
+
         // parse the uri
-        URI u = new URI(uri);
+        URI u = normalizeUri(uri);
         String scheme = u.getScheme();
 
         String json = componentJSonSchema(scheme);

http://git-wip-us.apache.org/repos/asf/camel/blob/ed574cbd/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java
index 3c09d41..2742d0c 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java
@@ -41,6 +41,17 @@ public final class URISupport {
     }
 
     /**
+     * Normalizes the URI so unsafe charachters is encoded
+     *
+     * @param uri the input uri
+     * @return as URI instance
+     * @throws URISyntaxException is thrown if syntax error in the input uri
+     */
+    public static URI normalizeUri(String uri) throws URISyntaxException {
+        return new URI(UnsafeUriCharactersEncoder.encode(uri, true));
+    }
+
+    /**
      * Strips the query parameters from the uri
      *
      * @param uri  the uri

http://git-wip-us.apache.org/repos/asf/camel/blob/ed574cbd/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java
b/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java
new file mode 100644
index 0000000..1d137d2
--- /dev/null
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java
@@ -0,0 +1,206 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.catalog;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 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 unsafeCharactersRfc1738;
+    private static BitSet unsafeCharactersHttp;
+    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C',
+            'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    static {
+        unsafeCharactersRfc1738 = new BitSet(256);
+        unsafeCharactersRfc1738.set(' ');
+        unsafeCharactersRfc1738.set('"');
+        unsafeCharactersRfc1738.set('<');
+        unsafeCharactersRfc1738.set('>');
+        unsafeCharactersRfc1738.set('#');
+        unsafeCharactersRfc1738.set('%');
+        unsafeCharactersRfc1738.set('{');
+        unsafeCharactersRfc1738.set('}');
+        unsafeCharactersRfc1738.set('|');
+        unsafeCharactersRfc1738.set('\\');
+        unsafeCharactersRfc1738.set('^');
+        unsafeCharactersRfc1738.set('~');
+        unsafeCharactersRfc1738.set('[');
+        unsafeCharactersRfc1738.set(']');
+        unsafeCharactersRfc1738.set('`');
+    }
+
+    static {
+        unsafeCharactersHttp = new BitSet(256);
+        unsafeCharactersHttp.set(' ');
+        unsafeCharactersHttp.set('"');
+        unsafeCharactersHttp.set('<');
+        unsafeCharactersHttp.set('>');
+        unsafeCharactersHttp.set('#');
+        unsafeCharactersHttp.set('%');
+        unsafeCharactersHttp.set('{');
+        unsafeCharactersHttp.set('}');
+        unsafeCharactersHttp.set('|');
+        unsafeCharactersHttp.set('\\');
+        unsafeCharactersHttp.set('^');
+        unsafeCharactersHttp.set('~');
+        unsafeCharactersHttp.set('`');
+    }
+
+    private UnsafeUriCharactersEncoder() {
+        // util class
+    }
+
+    public static String encode(String s) {
+        return encode(s, unsafeCharactersRfc1738);
+    }
+
+    public static String encodeHttpURI(String s) {
+        return encode(s, unsafeCharactersHttp);
+    }
+
+    public static String encode(String s, BitSet unsafeCharacters) {
+        return encode(s, unsafeCharacters, false);
+    }
+
+    public static String encode(String s, boolean checkRaw) {
+        return encode(s, unsafeCharactersRfc1738, checkRaw);
+    }
+
+    public static String encodeHttpURI(String s, boolean checkRaw) {
+        return encode(s, unsafeCharactersHttp, checkRaw);
+    }
+
+    private static List<Pair> checkRAW(String s) {
+        Pattern pattern = Pattern.compile("RAW\\([^\\)]+\\)");
+        Matcher matcher = pattern.matcher(s);
+        List<Pair> answer = new ArrayList<Pair>();
+        // Check all occurrences
+        while (matcher.find()) {
+            answer.add(new Pair(matcher.start(), matcher.end()));
+        }
+        return answer;
+    }
+
+    private static boolean isRaw(int index, List<Pair> pairs) {
+        for (Pair pair : pairs) {
+            if (index < pair.left) {
+                return false;
+            } else {
+                if (index >= pair.left) {
+                    if (index <= pair.right) {
+                        return true;
+                    } else {
+                        continue;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private static class Pair {
+        int left;
+        int right;
+
+        public Pair(int left, int right) {
+            this.left = left;
+            this.right = right;
+        }
+    }
+
+    // Just skip the encode for isRAW part
+    public static String encode(String s, BitSet unsafeCharacters, boolean checkRaw) {
+        List<Pair> rawPairs;
+        if (checkRaw) {
+            rawPairs = checkRAW(s);
+        } else {
+            rawPairs = new ArrayList<Pair>();
+        }
+
+        int n = s == null ? 0 : s.length();
+        if (n == 0) {
+            return s;
+        }
+
+        // First check whether we actually need to encode
+        char chars[] = s.toCharArray();
+        for (int i = 0; ; ) {
+            // just deal with the ascii character
+            if (chars[i] > 0 && chars[i] < 128) {
+                if (unsafeCharacters.get(chars[i])) {
+                    break;
+                }
+            }
+            if (++i >= chars.length) {
+                return s;
+            }
+        }
+
+        // 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 (int i = 0; i < chars.length; i++) {
+            char ch = chars[i];
+            if (ch > 0 && ch < 128 && unsafeCharacters.get(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) && !isRaw(i,
rawPairs)) {
+                        // 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) {
+        sb.append('%');
+        sb.append(HEX_DIGITS[(b >> 4) & 0x0f]);
+        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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ed574cbd/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index 4bc8fee..eb7e8bf 100644
--- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -228,6 +228,17 @@ public class CamelCatalogTest {
     }
 
     @Test
+    public void testEndpointPropertiesPlaceholders() throws Exception {
+        Map<String, String> map = catalog.endpointProperties("timer:foo?period={{howoften}}&repeatCount=5");
+        assertNotNull(map);
+        assertEquals(3, map.size());
+
+        assertEquals("foo", map.get("timerName"));
+        assertEquals("{{howoften}}", map.get("period"));
+        assertEquals("5", map.get("repeatCount"));
+    }
+
+    @Test
     public void testEndpointPropertiesNetty4http() throws Exception {
         Map<String, String> map = catalog.endpointProperties("netty4-http:http:localhost:8080/foo/bar?disconnect=true&keepAlive=false");
         assertNotNull(map);


Mime
View raw message