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 2016/03/04 10:45:37 UTC
[2/2] camel git commit: CAMEL-9658 - Path gets decoded when bridging
HTTP endpoints
CAMEL-9658 - Path gets decoded when bridging HTTP endpoints
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/8f11babb
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/8f11babb
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/8f11babb
Branch: refs/heads/camel-2.16.x
Commit: 8f11babb72927f2b88e3c87b1b81d1acc621b29a
Parents: 5d84ac7
Author: Tadayoshi Sato <sa...@gmail.com>
Authored: Tue Mar 1 22:04:59 2016 +0900
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Mar 4 10:44:47 2016 +0100
----------------------------------------------------------------------
.../camel/http/common/DefaultHttpBinding.java | 14 ++++++--
.../jetty/CamelContinuationServlet.java | 22 +++++++-----
.../jetty/HttpBridgeEncodedPathTest.java | 37 +++++++++++++++++---
.../netty/http/DefaultNettyHttpBinding.java | 2 +-
.../http/NettyHttpBridgeEncodedPathTest.java | 36 +++++++++++++++++--
.../netty4/http/DefaultNettyHttpBinding.java | 2 +-
.../http/NettyHttpBridgeEncodedPathTest.java | 36 +++++++++++++++++--
7 files changed, 128 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
index 04f5851..ad9adfe 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
@@ -137,11 +137,12 @@ public class DefaultHttpBinding implements HttpBinding {
}
// store the method and query and other info in headers as String types
+ String rawPath = getRawPath(request);
headers.put(Exchange.HTTP_METHOD, request.getMethod());
headers.put(Exchange.HTTP_QUERY, request.getQueryString());
headers.put(Exchange.HTTP_URL, request.getRequestURL().toString());
headers.put(Exchange.HTTP_URI, request.getRequestURI());
- headers.put(Exchange.HTTP_PATH, request.getPathInfo());
+ headers.put(Exchange.HTTP_PATH, rawPath);
headers.put(Exchange.CONTENT_TYPE, request.getContentType());
if (LOG.isTraceEnabled()) {
@@ -149,7 +150,7 @@ public class DefaultHttpBinding implements HttpBinding {
LOG.trace("HTTP query {}", request.getQueryString());
LOG.trace("HTTP url {}", request.getRequestURL());
LOG.trace("HTTP uri {}", request.getRequestURI());
- LOG.trace("HTTP path {}", request.getPathInfo());
+ LOG.trace("HTTP path {}", rawPath);
LOG.trace("HTTP content-type {}", request.getContentType());
}
@@ -224,7 +225,14 @@ public class DefaultHttpBinding implements HttpBinding {
}
}
}
-
+
+ private String getRawPath(HttpServletRequest request) {
+ String uri = request.getRequestURI();
+ String contextPath = request.getContextPath();
+ String servletPath = request.getServletPath();
+ return uri.substring(contextPath.length() + servletPath.length());
+ }
+
protected void populateAttachments(HttpServletRequest request, HttpMessage message) {
// check if there is multipart files, if so will put it into DataHandler
Enumeration<?> names = request.getAttributeNames();
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
index a6a2e9c..9e77b29 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
@@ -35,6 +35,7 @@ import org.apache.camel.http.common.HttpHelper;
import org.apache.camel.http.common.HttpMessage;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;
@@ -161,14 +162,8 @@ public class CamelContinuationServlet extends CamelServlet {
// set context path as header
String contextPath = consumer.getEndpoint().getPath();
exchange.getIn().setHeader("CamelServletContextPath", contextPath);
-
- String httpPath = (String)exchange.getIn().getHeader(Exchange.HTTP_PATH);
- // here we just remove the CamelServletContextPath part from the HTTP_PATH
- if (contextPath != null
- && httpPath.startsWith(contextPath)) {
- exchange.getIn().setHeader(Exchange.HTTP_PATH,
- httpPath.substring(contextPath.length()));
- }
+
+ updateHttpPath(exchange, contextPath);
if (log.isTraceEnabled()) {
log.trace("Suspending continuation of exchangeId: {}", exchange.getExchangeId());
@@ -241,6 +236,17 @@ public class CamelContinuationServlet extends CamelServlet {
}
}
+ private void updateHttpPath(Exchange exchange, String contextPath) {
+ String httpPath = (String) exchange.getIn().getHeader(Exchange.HTTP_PATH);
+ // encode context path in case it contains unsafe chars, because HTTP_PATH isn't decoded at this moment
+ String encodedContextPath = UnsafeUriCharactersEncoder.encodeHttpURI(contextPath);
+
+ // here we just remove the CamelServletContextPath part from the HTTP_PATH
+ if (contextPath != null && httpPath.startsWith(encodedContextPath)) {
+ exchange.getIn().setHeader(Exchange.HTTP_PATH, httpPath.substring(encodedContextPath.length()));
+ }
+ }
+
@Override
public void destroy() {
expiredExchanges.clear();
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeEncodedPathTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeEncodedPathTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeEncodedPathTest.java
index d1e3410..2ad8ca8 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeEncodedPathTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeEncodedPathTest.java
@@ -17,29 +17,55 @@
package org.apache.camel.component.jetty;
import java.io.ByteArrayInputStream;
+import java.net.URLEncoder;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
import org.junit.Test;
public class HttpBridgeEncodedPathTest extends BaseJettyTest {
private int port1;
private int port2;
+ private int port3;
+ private int port4;
@Test
- public void testHttpClient() throws Exception {
+ public void testEncodedQuery() throws Exception {
String response = template.requestBodyAndHeader("http://localhost:" + port2 + "/test/hello?param1=%2B447777111222",
new ByteArrayInputStream("This is a test".getBytes()), "Content-Type", "text/plain", String.class);
assertEquals("Get a wrong response", "param1=+447777111222", response);
}
+ @Test
+ public void testEncodedPath() throws Exception {
+ String path = URLEncoder.encode(" :/?#[]@!$", "UTF-8") + "/" + URLEncoder.encode("&'()+,;=", "UTF-8");
+ MockEndpoint mock = getMockEndpoint("mock:encodedPath");
+ mock.message(0).header(Exchange.HTTP_URI).isEqualTo("/" + path);
+ mock.message(0).header(Exchange.HTTP_PATH).isEqualTo(path);
+ mock.message(0).header(Exchange.HTTP_QUERY).isNull();
+ mock.message(0).header(Exchange.HTTP_RAW_QUERY).isNull();
+
+ // cannot use template as it automatically decodes some chars in the path
+ HttpClient httpClient = new HttpClient();
+ GetMethod httpGet = new GetMethod("http://localhost:" + port4 + "/test/" + path);
+ int status = httpClient.executeMethod(httpGet);
+
+ assertEquals("Get a wrong response status", 200, status);
+ assertMockEndpointsSatisfied();
+ }
+
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() {
port1 = getPort();
- port2 = getNextPort();
+ port2 = getPort2();
+ port3 = getNextPort();
+ port4 = getNextPort();
errorHandler(noErrorHandler());
@@ -56,8 +82,11 @@ public class HttpBridgeEncodedPathTest extends BaseJettyTest {
};
from("jetty:http://localhost:" + port2 + "/test/hello")
.to("http://localhost:" + port1 + "?throwExceptionOnFailure=false&bridgeEndpoint=true");
-
- from("jetty://http://localhost:" + port1 + "?matchOnUriPrefix=true").process(serviceProc);
+ from("jetty:http://localhost:" + port1 + "?matchOnUriPrefix=true").process(serviceProc);
+
+ from("jetty:http://localhost:" + port4 + "/test?matchOnUriPrefix=true")
+ .to("http://localhost:" + port3 + "?throwExceptionOnFailure=false&bridgeEndpoint=true");
+ from("jetty:http://localhost:" + port3 + "?matchOnUriPrefix=true").to("mock:encodedPath");
}
};
}
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/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 05bd551..192d4c1 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
@@ -132,7 +132,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable {
headers.put(Exchange.HTTP_RAW_QUERY, uri.getRawQuery());
// strip the starting endpoint path so the path is relative to the endpoint uri
- String path = uri.getPath();
+ String path = uri.getRawPath();
if (configuration.getPath() != null) {
// need to match by lower case as we want to ignore case on context-path
String matchPath = path.toLowerCase(Locale.US);
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBridgeEncodedPathTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBridgeEncodedPathTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBridgeEncodedPathTest.java
index 25a3bff..4c51795 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBridgeEncodedPathTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBridgeEncodedPathTest.java
@@ -16,28 +16,54 @@
*/
package org.apache.camel.component.netty.http;
+import java.net.URLEncoder;
+
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
import org.junit.Test;
public class NettyHttpBridgeEncodedPathTest extends BaseNettyTest {
private int port1;
private int port2;
+ private int port3;
+ private int port4;
@Test
- public void testHttpClient() throws Exception {
+ public void testEncodedQuery() throws Exception {
String response = template.requestBody("http://localhost:" + port2 + "/nettyTestRouteA?param1=%2B447777111222", null, String.class);
assertEquals("Get a wrong response", "param1=+447777111222", response);
}
+ @Test
+ public void testEncodedPath() throws Exception {
+ String path = URLEncoder.encode(" :/?#[]@!$", "UTF-8") + "/" + URLEncoder.encode("&'()+,;=", "UTF-8");
+ MockEndpoint mock = getMockEndpoint("mock:encodedPath");
+ mock.message(0).header(Exchange.HTTP_PATH).isEqualTo("/" + path);
+ mock.message(0).header(Exchange.HTTP_QUERY).isNull();
+ mock.message(0).header(Exchange.HTTP_RAW_QUERY).isNull();
+
+ // cannot use template as it automatically decodes some chars in the path
+ HttpClient httpClient = new HttpClient();
+ GetMethod httpGet = new GetMethod("http://localhost:" + port4 + "/nettyTestRouteC/" + path);
+ int status = httpClient.executeMethod(httpGet);
+
+ assertEquals("Get a wrong response status", 200, status);
+ assertMockEndpointsSatisfied();
+ }
+
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() {
port1 = getPort();
port2 = getNextPort();
+ port3 = getNextPort();
+ port4 = getNextPort();
errorHandler(noErrorHandler());
@@ -55,10 +81,16 @@ public class NettyHttpBridgeEncodedPathTest extends BaseNettyTest {
from("netty-http:http://localhost:" + port2 + "/nettyTestRouteA?matchOnUriPrefix=true")
.log("Using NettyTestRouteA route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
.to("netty-http:http://localhost:" + port1 + "/nettyTestRouteB?throwExceptionOnFailure=false&bridgeEndpoint=true");
-
from("netty-http:http://localhost:" + port1 + "/nettyTestRouteB?matchOnUriPrefix=true")
.log("Using NettyTestRouteB route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
.process(serviceProc);
+
+ from("netty-http:http://localhost:" + port4 + "/nettyTestRouteC?matchOnUriPrefix=true")
+ .log("Using NettyTestRouteC route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
+ .to("netty-http:http://localhost:" + port3 + "/nettyTestRouteD?throwExceptionOnFailure=false&bridgeEndpoint=true");
+ from("netty-http:http://localhost:" + port3 + "/nettyTestRouteD?matchOnUriPrefix=true")
+ .log("Using NettyTestRouteD route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
+ .to("mock:encodedPath");
}
};
}
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/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 0a183a3..552f5de 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
@@ -134,7 +134,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable {
headers.put(Exchange.HTTP_RAW_QUERY, uri.getRawQuery());
// strip the starting endpoint path so the path is relative to the endpoint uri
- String path = uri.getPath();
+ String path = uri.getRawPath();
if (configuration.getPath() != null) {
// need to match by lower case as we want to ignore case on context-path
String matchPath = path.toLowerCase(Locale.US);
http://git-wip-us.apache.org/repos/asf/camel/blob/8f11babb/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBridgeEncodedPathTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBridgeEncodedPathTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBridgeEncodedPathTest.java
index a2c9b3c..76d02ee 100644
--- a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBridgeEncodedPathTest.java
+++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBridgeEncodedPathTest.java
@@ -16,28 +16,54 @@
*/
package org.apache.camel.component.netty4.http;
+import java.net.URLEncoder;
+
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
import org.junit.Test;
public class NettyHttpBridgeEncodedPathTest extends BaseNettyTest {
private int port1;
private int port2;
+ private int port3;
+ private int port4;
@Test
- public void testHttpClient() throws Exception {
+ public void testEncodedQuery() throws Exception {
String response = template.requestBody("http://localhost:" + port2 + "/nettyTestRouteA?param1=%2B447777111222", null, String.class);
assertEquals("Get a wrong response", "param1=+447777111222", response);
}
+ @Test
+ public void testEncodedPath() throws Exception {
+ String path = URLEncoder.encode(" :/?#[]@!$", "UTF-8") + "/" + URLEncoder.encode("&'()+,;=", "UTF-8");
+ MockEndpoint mock = getMockEndpoint("mock:encodedPath");
+ mock.message(0).header(Exchange.HTTP_PATH).isEqualTo("/" + path);
+ mock.message(0).header(Exchange.HTTP_QUERY).isNull();
+ mock.message(0).header(Exchange.HTTP_RAW_QUERY).isNull();
+
+ // cannot use template as it automatically decodes some chars in the path
+ HttpClient httpClient = new HttpClient();
+ GetMethod httpGet = new GetMethod("http://localhost:" + port4 + "/nettyTestRouteC/" + path);
+ int status = httpClient.executeMethod(httpGet);
+
+ assertEquals("Get a wrong response status", 200, status);
+ assertMockEndpointsSatisfied();
+ }
+
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() {
port1 = getPort();
port2 = getNextPort();
+ port3 = getNextPort();
+ port4 = getNextPort();
errorHandler(noErrorHandler());
@@ -55,10 +81,16 @@ public class NettyHttpBridgeEncodedPathTest extends BaseNettyTest {
from("netty4-http:http://localhost:" + port2 + "/nettyTestRouteA?matchOnUriPrefix=true")
.log("Using NettyTestRouteA route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
.to("netty4-http:http://localhost:" + port1 + "/nettyTestRouteB?throwExceptionOnFailure=false&bridgeEndpoint=true");
-
from("netty4-http:http://localhost:" + port1 + "/nettyTestRouteB?matchOnUriPrefix=true")
.log("Using NettyTestRouteB route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
.process(serviceProc);
+
+ from("netty4-http:http://localhost:" + port4 + "/nettyTestRouteC?matchOnUriPrefix=true")
+ .log("Using NettyTestRouteC route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
+ .to("netty4-http:http://localhost:" + port3 + "/nettyTestRouteD?throwExceptionOnFailure=false&bridgeEndpoint=true");
+ from("netty4-http:http://localhost:" + port3 + "/nettyTestRouteD?matchOnUriPrefix=true")
+ .log("Using NettyTestRouteD route: CamelHttpPath=[${header.CamelHttpPath}], CamelHttpUri=[${header.CamelHttpUri}]")
+ .to("mock:encodedPath");
}
};
}