CAMEL-9086 - add support for relative path in HTTP requests Conflicts: components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/acd568bd Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/acd568bd Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/acd568bd Branch: refs/heads/camel-2.15.x Commit: acd568bd89f2444cb7671a92576f2ac75e1ec4eb Parents: 11c439a Author: Jonathan Anstey <jans...@gmail.com> Authored: Tue Aug 18 11:19:47 2015 -0230 Committer: Jonathan Anstey <jans...@gmail.com> Committed: Tue Aug 18 11:44:04 2015 -0230 ---------------------------------------------------------------------- .../netty/http/DefaultNettyHttpBinding.java | 10 ++- .../netty/http/NettyHttpConfiguration.java | 12 ++++ ...ndingPreservePostFormUrlEncodedBodyTest.java | 6 ++ ...ttyHttpBindingUseRelativePathInPostTest.java | 74 ++++++++++++++++++++ .../netty4/http/DefaultNettyHttpBinding.java | 12 +++- .../netty4/http/NettyHttpConfiguration.java | 14 +++- ...ndingPreservePostFormUrlEncodedBodyTest.java | 8 +++ ...ttyHttpBindingUseRelativePathInPostTest.java | 74 ++++++++++++++++++++ 8 files changed, 206 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/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 f451e67..cb5b142 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 @@ -439,8 +439,16 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { return (HttpRequest) message.getBody(); } + String uriForRequest = uri; + if (configuration.isUseRelativePath()) { + int indexOfPath = uri.indexOf((new URI(uri)).getPath()); + if (indexOfPath > 0) { + uriForRequest = uri.substring(indexOfPath); + } + } + // just assume GET for now, we will later change that to the actual method to use - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri); + HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriForRequest); TypeConverter tc = message.getExchange().getContext().getTypeConverter(); http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java index 9fbf2d5..aeed8d7 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java @@ -59,6 +59,8 @@ public class NettyHttpConfiguration extends NettyConfiguration { private boolean chunked = true; @UriParam(label = "consumer", defaultValue = "8192") private int maxHeaderSize = 8192; + @UriParam(label = "producer", defaultValue = "false") + private boolean useRelativePath; public NettyHttpConfiguration() { // we need sync=true as http is request/reply by nature @@ -201,4 +203,14 @@ public class NettyHttpConfiguration extends NettyConfiguration { throw new UnsupportedOperationException("You cannot setAllowDefaultCodec here."); } + /** + * Sets whether to use a relative path in HTTP requests. + */ + public void setUseRelativePath(boolean useRelativePath) { + this.useRelativePath = useRelativePath; + } + + public boolean isUseRelativePath() { + return this.useRelativePath; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java index e49bfd3..2939351 100644 --- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java +++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java @@ -20,6 +20,8 @@ import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.http.HttpMethods; +import org.jboss.netty.channel.UpstreamMessageEvent; +import org.jboss.netty.handler.codec.http.DefaultHttpRequest; import org.junit.Test; public class NettyHttpBindingPreservePostFormUrlEncodedBodyTest extends BaseNettyTest { @@ -55,6 +57,10 @@ public class NettyHttpBindingPreservePostFormUrlEncodedBodyTest extends BaseNett assertEquals("Get a wrong form parameter from the message header", "x", exchange.getIn().getHeader("b1")); assertEquals("Get a wrong form parameter from the message header", "y", exchange.getIn().getHeader("b2")); + UpstreamMessageEvent event = (UpstreamMessageEvent) exchange.getIn().getHeader("CamelNettyMessageEvent"); + DefaultHttpRequest request = (DefaultHttpRequest) event.getMessage(); + assertNotEquals("Relative path should NOT be used in POST", "/myapp/myservice?query1=a&query2=b", request.getUri()); + // send a response exchange.getOut().getHeaders().clear(); exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "text/plain"); http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingUseRelativePathInPostTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingUseRelativePathInPostTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingUseRelativePathInPostTest.java new file mode 100644 index 0000000..3dcecd4 --- /dev/null +++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingUseRelativePathInPostTest.java @@ -0,0 +1,74 @@ +/** + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.component.netty.http; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.http.HttpMethods; +import org.jboss.netty.channel.UpstreamMessageEvent; +import org.jboss.netty.handler.codec.http.DefaultHttpRequest; +import org.junit.Test; + +public class NettyHttpBindingUseRelativePathInPostTest extends BaseNettyTest { + + @Test + public void testSendToNetty() throws Exception { + Exchange exchange = template.request("netty-http:http://localhost:{{port}}/myapp/myservice?query1=a&query2=b&useRelativePath=true", new Processor() { + + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("b1=x&b2=y"); + exchange.getIn().setHeader("content-type", "application/x-www-form-urlencoded"); + exchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.POST); + } + + }); + // convert the response to a String + String body = exchange.getOut().getBody(String.class); + assertEquals("Request message is OK", body); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from("netty-http:http://localhost:{{port}}/myapp/myservice").process(new Processor() { + public void process(Exchange exchange) throws Exception { + String body = exchange.getIn().getBody(String.class); + + // for unit testing make sure we got right message + assertEquals("The body message is wrong", "b1=x&b2=y", body); + assertEquals("Get a wrong query parameter from the message header", "a", exchange.getIn().getHeader("query1")); + assertEquals("Get a wrong query parameter from the message header", "b", exchange.getIn().getHeader("query2")); + assertEquals("Get a wrong form parameter from the message header", "x", exchange.getIn().getHeader("b1")); + assertEquals("Get a wrong form parameter from the message header", "y", exchange.getIn().getHeader("b2")); + + UpstreamMessageEvent event = (UpstreamMessageEvent) exchange.getIn().getHeader("CamelNettyMessageEvent"); + DefaultHttpRequest request = (DefaultHttpRequest) event.getMessage(); + assertEquals("Relative path not used in POST", "/myapp/myservice?query1=a&query2=b", request.getUri()); + + // send a response + exchange.getOut().getHeaders().clear(); + exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "text/plain"); + exchange.getOut().setBody("Request message is OK"); + } + }); + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/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 3a0c2c9..0ff12cd 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 @@ -446,8 +446,16 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { return (HttpRequest) message.getBody(); } + String uriForRequest = uri; + if (configuration.isUseRelativePath()) { + int indexOfPath = uri.indexOf((new URI(uri)).getPath()); + if (indexOfPath > 0) { + uriForRequest = uri.substring(indexOfPath); + } + } + // just assume GET for now, we will later change that to the actual method to use - HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri); + HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriForRequest); Object body = message.getBody(); if (body != null) { @@ -465,7 +473,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { } } if (buffer != null) { - request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri, buffer); + request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriForRequest, buffer); int len = buffer.readableBytes(); // set content-length request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, len); http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java index 5618aba..d73d194 100644 --- a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java +++ b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java @@ -58,7 +58,9 @@ public class NettyHttpConfiguration extends NettyConfiguration { private boolean chunked = true; @UriParam(label = "consumer", defaultValue = "8192") private int maxHeaderSize = 8192; - + @UriParam(label = "producer", defaultValue = "false") + private boolean useRelativePath; + public NettyHttpConfiguration() { // we need sync=true as http is request/reply by nature setSync(true); @@ -200,4 +202,14 @@ public class NettyHttpConfiguration extends NettyConfiguration { throw new UnsupportedOperationException("You cannot setAllowDefaultCodec here."); } + /** + * Sets whether to use a relative path in HTTP requests. + */ + public void setUseRelativePath(boolean useRelativePath) { + this.useRelativePath = useRelativePath; + } + + public boolean isUseRelativePath() { + return this.useRelativePath; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java index 3f96d39..01c2627 100644 --- a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java +++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java @@ -17,11 +17,14 @@ package org.apache.camel.component.netty4.http; import org.apache.camel.Exchange; +import org.apache.camel.Message; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.http.HttpMethods; import org.junit.Test; +import io.netty.handler.codec.http.FullHttpRequest; + public class NettyHttpBindingPreservePostFormUrlEncodedBodyTest extends BaseNettyTest { @Test @@ -55,6 +58,11 @@ public class NettyHttpBindingPreservePostFormUrlEncodedBodyTest extends BaseNett assertEquals("Get a wrong form parameter from the message header", "x", exchange.getIn().getHeader("b1")); assertEquals("Get a wrong form parameter from the message header", "y", exchange.getIn().getHeader("b2")); + NettyHttpMessage in = (NettyHttpMessage) exchange.getIn(); + FullHttpRequest request = in.getHttpRequest(); + assertNotEquals("Relative path should NOT be used in POST", "/myapp/myservice?query1=a&query2=b", request.getUri()); + + // send a response exchange.getOut().getHeaders().clear(); exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "text/plain"); http://git-wip-us.apache.org/repos/asf/camel/blob/acd568bd/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingUseRelativePathInPostTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingUseRelativePathInPostTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingUseRelativePathInPostTest.java new file mode 100644 index 0000000..2fae960 --- /dev/null +++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpBindingUseRelativePathInPostTest.java @@ -0,0 +1,74 @@ +/** + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.component.netty4.http; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.http.HttpMethods; +import org.junit.Test; + +import io.netty.handler.codec.http.FullHttpRequest; + +public class NettyHttpBindingUseRelativePathInPostTest extends BaseNettyTest { + + @Test + public void testSendToNetty() throws Exception { + Exchange exchange = template.request("netty4-http:http://localhost:{{port}}/myapp/myservice?query1=a&query2=b&useRelativePath=true", new Processor() { + + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("b1=x&b2=y"); + exchange.getIn().setHeader("content-type", "application/x-www-form-urlencoded"); + exchange.getIn().setHeader(Exchange.HTTP_METHOD, HttpMethods.POST); + } + + }); + // convert the response to a String + String body = exchange.getOut().getBody(String.class); + assertEquals("Request message is OK", body); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from("netty4-http:http://localhost:{{port}}/myapp/myservice").process(new Processor() { + public void process(Exchange exchange) throws Exception { + String body = exchange.getIn().getBody(String.class); + + // for unit testing make sure we got right message + assertEquals("The body message is wrong", "b1=x&b2=y", body); + assertEquals("Get a wrong query parameter from the message header", "a", exchange.getIn().getHeader("query1")); + assertEquals("Get a wrong query parameter from the message header", "b", exchange.getIn().getHeader("query2")); + assertEquals("Get a wrong form parameter from the message header", "x", exchange.getIn().getHeader("b1")); + assertEquals("Get a wrong form parameter from the message header", "y", exchange.getIn().getHeader("b2")); + + NettyHttpMessage in = (NettyHttpMessage) exchange.getIn(); + FullHttpRequest request = in.getHttpRequest(); + assertEquals("Relative path not used in POST", "/myapp/myservice?query1=a&query2=b", request.getUri()); + + // send a response + exchange.getOut().getHeaders().clear(); + exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "text/plain"); + exchange.getOut().setBody("Request message is OK"); + } + }); + } + }; + } + +}