CAMEL-8693: HTTP related component should parse query lenient to ignore 
trailing & markers which can happen when using HTTP


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

Branch: refs/heads/camel-2.15.x
Commit: f51e06167a230c7da6a248b0e7b941bda3d1406c
Parents: 29f7fad
Author: Claus Ibsen <davscl...@apache.org>
Authored: Fri Apr 24 07:41:19 2015 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Fri Apr 24 07:44:39 2015 +0200

----------------------------------------------------------------------
 .../java/org/apache/camel/util/URISupport.java  | 30 ++++++++++++++++----
 .../org/apache/camel/util/URISupportTest.java   | 15 ++++++++++
 .../camel/component/gae/http/GHttpEndpoint.java |  2 +-
 .../camel/component/http/HttpProducer.java      |  2 +-
 .../camel/component/http4/HttpProducer.java     |  2 +-
 .../component/jetty/JettyHttpProducer.java      |  2 +-
 .../netty/http/DefaultNettyHttpBinding.java     |  4 +--
 .../netty4/http/DefaultNettyHttpBinding.java    |  4 +--
 .../component/netty4/http/NettyHttpBinding.java |  6 ++--
 9 files changed, 50 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/camel-core/src/main/java/org/apache/camel/util/URISupport.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/URISupport.java 
b/camel-core/src/main/java/org/apache/camel/util/URISupport.java
index 45f831c..90229a6 100644
--- a/camel-core/src/main/java/org/apache/camel/util/URISupport.java
+++ b/camel-core/src/main/java/org/apache/camel/util/URISupport.java
@@ -22,7 +22,6 @@ import java.net.URISyntaxException;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -148,13 +147,34 @@ public final class URISupport {
      * @see #RAW_TOKEN_END
      */
     public static Map<String, Object> parseQuery(String uri, boolean useRaw) 
throws URISyntaxException {
+        return parseQuery(uri, useRaw, false);
+    }
+
+    /**
+     * Parses the query part of the uri (eg the parameters).
+     * <p/>
+     * The URI parameters will by default be URI encoded. However you can 
define a parameter
+     * values with the syntax: <tt>key=RAW(value)</tt> which tells Camel to 
not encode the value,
+     * and use the value as is (eg key=value) and the value has <b>not</b> 
been encoded.
+     *
+     * @param uri the uri
+     * @param useRaw whether to force using raw values
+     * @param lenient whether to parse lenient and ignore trailing & markers 
which has no key or value which can happen when using HTTP components
+     * @return the parameters, or an empty map if no parameters (eg never null)
+     * @throws URISyntaxException is thrown if uri has invalid syntax.
+     * @see #RAW_TOKEN_START
+     * @see #RAW_TOKEN_END
+     */
+    public static Map<String, Object> parseQuery(String uri, boolean useRaw, 
boolean lenient) throws URISyntaxException {
         // must check for trailing & as the uri.split("&") will ignore those
-        if (uri != null && uri.endsWith("&")) {
-            throw new URISyntaxException(uri, "Invalid uri syntax: Trailing & 
marker found. "
-                    + "Check the uri and remove the trailing & marker.");
+        if (!lenient) {
+            if (uri != null && uri.endsWith("&")) {
+                throw new URISyntaxException(uri, "Invalid uri syntax: 
Trailing & marker found. "
+                        + "Check the uri and remove the trailing & marker.");
+            }
         }
 
-        if (ObjectHelper.isEmpty(uri)) {
+        if (uri == null || ObjectHelper.isEmpty(uri)) {
             // return an empty map
             return new LinkedHashMap<String, Object>(0);
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java 
b/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java
index 4291f3c..1b8d5a4 100644
--- a/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java
@@ -17,6 +17,7 @@
 package org.apache.camel.util;
 
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -280,6 +281,20 @@ public class URISupportTest extends ContextTestSupport {
         assertEquals("somechat", map.get("serviceName"));
     }
 
+    public void testParseQueryLenient() throws Exception {
+        try {
+            URISupport.parseQuery("password=secret&serviceName=somechat&", 
false, false);
+            fail("Should have thrown exception");
+        } catch (URISyntaxException e) {
+            // expected
+        }
+
+        Map<String, Object> map = 
URISupport.parseQuery("password=secret&serviceName=somechat&", false, true);
+        assertEquals(2, map.size());
+        assertEquals("secret", map.get("password"));
+        assertEquals("somechat", map.get("serviceName"));
+    }
+
     public void testResolveRawParameterValues() throws Exception {
         Map<String, Object> map = 
URISupport.parseQuery("password=secret&serviceName=somechat");
         URISupport.resolveRawParameterValues(map);

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-gae/src/main/java/org/apache/camel/component/gae/http/GHttpEndpoint.java
----------------------------------------------------------------------
diff --git 
a/components/camel-gae/src/main/java/org/apache/camel/component/gae/http/GHttpEndpoint.java
 
b/components/camel-gae/src/main/java/org/apache/camel/component/gae/http/GHttpEndpoint.java
index 6eddc5b..a054b6d 100644
--- 
a/components/camel-gae/src/main/java/org/apache/camel/component/gae/http/GHttpEndpoint.java
+++ 
b/components/camel-gae/src/main/java/org/apache/camel/component/gae/http/GHttpEndpoint.java
@@ -88,7 +88,7 @@ public class GHttpEndpoint extends ServletEndpoint implements 
OutboundBindingSup
         if (query == null) {
             parameters = URISupport.parseParameters(uriObj);
         } else {
-            parameters = URISupport.parseQuery(query);
+            parameters = URISupport.parseQuery(query, false, true);
         }
         if (uriObj.getScheme().equals(GHTTPS_SCHEME)) {
             uriObj = new URI(HTTPS_SCHEME + ":" + 
uriObj.getRawSchemeSpecificPart());

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
index 9774118..ebef9e7 100644
--- 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
+++ 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
@@ -83,7 +83,7 @@ public class HttpProducer extends DefaultProducer {
             exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
             String queryString = 
exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
             if (queryString != null) {
-                skipRequestHeaders = URISupport.parseQuery(queryString);
+                skipRequestHeaders = URISupport.parseQuery(queryString, false, 
true);
             }
             // Need to remove the Host key as it should be not used 
             exchange.getIn().getHeaders().remove("host");

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
 
b/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
index 01709eb..53f9221 100644
--- 
a/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
+++ 
b/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
@@ -98,7 +98,7 @@ public class HttpProducer extends DefaultProducer {
             exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
             String queryString = 
exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
             if (queryString != null) {
-                skipRequestHeaders = URISupport.parseQuery(queryString);
+                skipRequestHeaders = URISupport.parseQuery(queryString, false, 
true);
             }
             // Need to remove the Host key as it should be not used 
             exchange.getIn().getHeaders().remove("host");

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
 
b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
index 88e2204..6eda222 100644
--- 
a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
+++ 
b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
@@ -181,7 +181,7 @@ public class JettyHttpProducer extends DefaultAsyncProducer 
implements AsyncProc
             exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
             String queryString = 
exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
             if (queryString != null) {
-                skipRequestHeaders = URISupport.parseQuery(queryString);
+                skipRequestHeaders = URISupport.parseQuery(queryString, false, 
true);
             }
             // Need to remove the Host key as it should be not used 
             exchange.getIn().getHeaders().remove("host");

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
----------------------------------------------------------------------
diff --git 
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
 
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
index 85395b8..bbdbfc3 100644
--- 
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
+++ 
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
@@ -177,7 +177,7 @@ public class DefaultNettyHttpBinding implements 
NettyHttpBinding, Cloneable {
         // add uri parameters as headers to the Camel message
         if (request.getUri().contains("?")) {
             String query = ObjectHelper.after(request.getUri(), "?");
-            Map<String, Object> uriParameters = URISupport.parseQuery(query);
+            Map<String, Object> uriParameters = URISupport.parseQuery(query, 
false, true);
 
             for (Map.Entry<String, Object> entry : uriParameters.entrySet()) {
                 String name = entry.getKey();
@@ -445,7 +445,7 @@ public class DefaultNettyHttpBinding implements 
NettyHttpBinding, Cloneable {
         if (configuration.isBridgeEndpoint()) {
             String queryString = message.getHeader(Exchange.HTTP_QUERY, 
String.class);
             if (queryString != null) {
-                skipRequestHeaders = URISupport.parseQuery(queryString);
+                skipRequestHeaders = URISupport.parseQuery(queryString, false, 
true);
             }
             // Need to remove the Host key as it should be not used
             message.getHeaders().remove("host");

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/DefaultNettyHttpBinding.java
----------------------------------------------------------------------
diff --git 
a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/DefaultNettyHttpBinding.java
 
b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/DefaultNettyHttpBinding.java
index 39d6888..29f6bdf 100644
--- 
a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/DefaultNettyHttpBinding.java
+++ 
b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/DefaultNettyHttpBinding.java
@@ -179,7 +179,7 @@ public class DefaultNettyHttpBinding implements 
NettyHttpBinding, Cloneable {
         // add uri parameters as headers to the Camel message
         if (request.getUri().contains("?")) {
             String query = ObjectHelper.after(request.getUri(), "?");
-            Map<String, Object> uriParameters = URISupport.parseQuery(query);
+            Map<String, Object> uriParameters = URISupport.parseQuery(query, 
false, true);
 
             for (Map.Entry<String, Object> entry : uriParameters.entrySet()) {
                 String name = entry.getKey();
@@ -483,7 +483,7 @@ public class DefaultNettyHttpBinding implements 
NettyHttpBinding, Cloneable {
         if (configuration.isBridgeEndpoint()) {
             String queryString = message.getHeader(Exchange.HTTP_QUERY, 
String.class);
             if (queryString != null) {
-                skipRequestHeaders = URISupport.parseQuery(queryString);
+                skipRequestHeaders = URISupport.parseQuery(queryString, false, 
true);
             }
             // Need to remove the Host key as it should be not used
             message.getHeaders().remove("host");

http://git-wip-us.apache.org/repos/asf/camel/blob/f51e0616/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpBinding.java
----------------------------------------------------------------------
diff --git 
a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpBinding.java
 
b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpBinding.java
index 7b86ed7..55d657f 100644
--- 
a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpBinding.java
+++ 
b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpBinding.java
@@ -34,8 +34,7 @@ public interface NettyHttpBinding {
     /**
      * Binds from Netty {@link HttpRequest} to Camel {@link Message}.
      * <p/>
-     * Will use {@link 
#populateCamelHeaders(io.netty.handler.codec.http.HttpRequest, java.util.Map, 
org.apache.camel.Exchange, NettyHttpConfiguration)}
-     * for populating the headers.
+     * Will use the <tt>populateCamelHeaders</tt> method for populating the 
headers.
      *
      * @param request       the netty http request
      * @param exchange      the exchange that should contain the returned 
message.
@@ -59,8 +58,7 @@ public interface NettyHttpBinding {
     /**
      * Binds from Netty {@link HttpResponse} to Camel {@link Message}.
      * <p/>
-     * Will use {@link 
#populateCamelHeaders(io.netty.handler.codec.http.HttpResponse, java.util.Map, 
org.apache.camel.Exchange, NettyHttpConfiguration)}
-     * for populating the headers.
+     * Will use the <tt>populateCamelHeaders</tt> method for populating the 
headers.
      *
      * @param response      the netty http response
      * @param exchange      the exchange that should contain the returned 
message.

Reply via email to