Repository: camel Updated Branches: refs/heads/master 4dfdc8414 -> 97634ae69
CAMEL-8169 Camel Jetty/Http4 producers should respect Content-Length/Transfer-Encoding:Chunked headers Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/97634ae6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/97634ae6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/97634ae6 Branch: refs/heads/master Commit: 97634ae69587f4327dcefae3b54672d3914ce7ac Parents: cefb210 Author: Willem Jiang <willem.ji...@gmail.com> Authored: Mon Dec 22 08:56:13 2014 +0800 Committer: Willem Jiang <willem.ji...@gmail.com> Committed: Mon Dec 22 09:08:30 2014 +0800 ---------------------------------------------------------------------- .../component/http4/HttpEntityConverter.java | 11 ++- .../camel/component/http4/HttpProducer.java | 8 +- .../component/jetty/JettyHttpProducer.java | 5 ++ .../itest/http/HttpRouteContentLengthTest.java | 91 ++++++++++++++++++++ .../http/JettyHttpRouteContentLengthTest.java | 25 ++++++ 5 files changed, 138 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/97634ae6/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEntityConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEntityConverter.java b/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEntityConverter.java index 8236da8..bcbe502 100644 --- a/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEntityConverter.java +++ b/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEntityConverter.java @@ -22,8 +22,10 @@ import java.io.InputStream; import org.apache.camel.Converter; import org.apache.camel.Exchange; +import org.apache.camel.Message; import org.apache.camel.util.ExchangeHelper; import org.apache.camel.util.GZIPHelper; +import org.apache.camel.util.ObjectHelper; import org.apache.http.HttpEntity; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.ByteArrayEntity; @@ -67,7 +69,14 @@ public final class HttpEntityConverter { entity = new InputStreamEntity(stream, stream instanceof ByteArrayInputStream ? stream.available() != 0 ? stream.available() : -1 : -1); } else { - entity = new InputStreamEntity(in, -1); + Message inMessage = exchange.getIn(); + String length = inMessage.getHeader(Exchange.CONTENT_LENGTH, String.class); + + if (ObjectHelper.isEmpty(length)) { + entity = new InputStreamEntity(in, -1); + } else { + entity = new InputStreamEntity(in, Long.parseLong(length)); + } } if (exchange != null) { String contentEncoding = exchange.getIn().getHeader(Exchange.CONTENT_ENCODING, String.class); http://git-wip-us.apache.org/repos/asf/camel/blob/97634ae6/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 d41dbe1..01709eb 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 @@ -464,7 +464,13 @@ public class HttpProducer extends DefaultProducer { if (answer == null) { // force the body as an input stream since this is the fallback InputStream is = in.getMandatoryBody(InputStream.class); - InputStreamEntity entity = new InputStreamEntity(is, -1); + String length = in.getHeader(Exchange.CONTENT_LENGTH, String.class); + InputStreamEntity entity = null; + if (ObjectHelper.isEmpty(length)) { + entity = new InputStreamEntity(is, -1); + } else { + entity = new InputStreamEntity(is, Long.parseLong(length)); + } if (contentType != null) { entity.setContentType(contentType.toString()); } http://git-wip-us.apache.org/repos/asf/camel/blob/97634ae6/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java index 93f4380..17132af 100644 --- a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java +++ b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java @@ -154,6 +154,11 @@ public class JettyHttpProducer extends DefaultAsyncProducer implements AsyncProc // then fallback to input stream InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, exchange.getIn().getBody()); httpExchange.setRequestContent(is); + // setup the content length if it is possible + String length = exchange.getIn().getHeader(Exchange.CONTENT_LENGTH, String.class); + if (ObjectHelper.isNotEmpty(length)) { + httpExchange.addRequestHeader(Exchange.CONTENT_LENGTH, length); + } } } } http://git-wip-us.apache.org/repos/asf/camel/blob/97634ae6/tests/camel-itest/src/test/java/org/apache/camel/itest/http/HttpRouteContentLengthTest.java ---------------------------------------------------------------------- diff --git a/tests/camel-itest/src/test/java/org/apache/camel/itest/http/HttpRouteContentLengthTest.java b/tests/camel-itest/src/test/java/org/apache/camel/itest/http/HttpRouteContentLengthTest.java new file mode 100644 index 0000000..b4c8918 --- /dev/null +++ b/tests/camel-itest/src/test/java/org/apache/camel/itest/http/HttpRouteContentLengthTest.java @@ -0,0 +1,91 @@ +/** + * 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.itest.http; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class HttpRouteContentLengthTest extends CamelTestSupport { + + private int port1; + private int port2; + + @Test + public void testHttpClientContentLength() throws Exception { + invokeService(port1, true); + } + + @Test + public void testHttpRouteContentLength() throws Exception { + invokeService(port2, false); + } + + private void invokeService(int port, boolean checkChunkedHeader) { + Exchange out = template.request("http://localhost:" + port + "/test", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("Camel request."); + } + }); + + assertNotNull(out); + assertEquals("Bye Camel request.: 14", out.getOut().getBody(String.class)); + + + + } + + protected String getHttpEndpointScheme() { + return "http4://localhost:"; + } + + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + port1 = AvailablePortFinder.getNextAvailable(8000); + port2 = AvailablePortFinder.getNextAvailable(9000); + + // use jetty as server as it supports sending response as chunked encoding + from("jetty:http://localhost:" + port1 + "/test") + .process(new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + String contentLength = exchange.getIn().getHeader(Exchange.CONTENT_LENGTH, String.class); + String request = exchange.getIn().getBody(String.class); + exchange.getOut().setBody(request + ": " + contentLength); + } + + }) + .transform().simple("Bye ${body}"); + + // set up a netty http proxy + from("jetty:http://localhost:" + port2 + "/test") + .to(getHttpEndpointScheme() + port1 + "/test?bridgeEndpoint=true&throwExceptionOnFailure=false"); + + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/97634ae6/tests/camel-itest/src/test/java/org/apache/camel/itest/http/JettyHttpRouteContentLengthTest.java ---------------------------------------------------------------------- diff --git a/tests/camel-itest/src/test/java/org/apache/camel/itest/http/JettyHttpRouteContentLengthTest.java b/tests/camel-itest/src/test/java/org/apache/camel/itest/http/JettyHttpRouteContentLengthTest.java new file mode 100644 index 0000000..db21146 --- /dev/null +++ b/tests/camel-itest/src/test/java/org/apache/camel/itest/http/JettyHttpRouteContentLengthTest.java @@ -0,0 +1,25 @@ +/** + * 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.itest.http; + +public class JettyHttpRouteContentLengthTest extends HttpRouteContentLengthTest { + + protected String getHttpEndpointScheme() { + return "jetty://http://localhost:"; + } + +}