CAMEL-8461 Fixed the issue that camel-netty-http does not respect client's keep-alive setting
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/48b961b6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/48b961b6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/48b961b6 Branch: refs/heads/camel-2.15.x Commit: 48b961b6b8532aad4b1d72f73aa2a51894346b3e Parents: edfe515 Author: Willem Jiang <[email protected]> Authored: Mon Mar 9 18:08:13 2015 +0800 Committer: Willem Jiang <[email protected]> Committed: Mon Mar 9 18:37:02 2015 +0800 ---------------------------------------------------------------------- .../netty4/http/DefaultNettyHttpBinding.java | 4 +++ .../http/handlers/HttpServerChannelHandler.java | 10 ++++++-- .../http/NettyHttpProducerKeepAliveTest.java | 26 +++++++++++++++++--- 3 files changed, 35 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/48b961b6/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 ceb64c4..39d6888 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 @@ -410,6 +410,10 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // configure connection to accordingly to keep alive configuration // favor using the header from the message String connection = message.getHeader(HttpHeaders.Names.CONNECTION, String.class); + // Read the connection header from the exchange property + if (connection == null) { + connection = message.getExchange().getProperty(HttpHeaders.Names.CONNECTION, String.class); + } if (connection == null) { // fallback and use the keep alive from the configuration if (configuration.isKeepAlive()) { http://git-wip-us.apache.org/repos/asf/camel/blob/48b961b6/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/handlers/HttpServerChannelHandler.java ---------------------------------------------------------------------- diff --git a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/handlers/HttpServerChannelHandler.java b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/handlers/HttpServerChannelHandler.java index 18770b1..9645dc0 100644 --- a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/handlers/HttpServerChannelHandler.java +++ b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/handlers/HttpServerChannelHandler.java @@ -31,7 +31,6 @@ import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; - import org.apache.camel.Exchange; import org.apache.camel.LoggingLevel; import org.apache.camel.component.netty4.NettyConverter; @@ -43,9 +42,9 @@ import org.apache.camel.component.netty4.http.NettyHttpSecurityConfiguration; import org.apache.camel.component.netty4.http.SecurityAuthenticator; import org.apache.camel.util.CamelLogger; import org.apache.camel.util.ObjectHelper; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST; import static io.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED; import static io.netty.handler.codec.http.HttpResponseStatus.OK; @@ -275,6 +274,13 @@ public class HttpServerChannelHandler extends ServerChannelHandler { exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE); exchange.setProperty(Exchange.SKIP_WWW_FORM_URLENCODED, Boolean.TRUE); } + HttpRequest request = (HttpRequest) message; + // setup the connection property in case of the message header is removed + boolean keepAlive = HttpHeaders.isKeepAlive(request); + if (!keepAlive) { + // Just make sure we close the connection this time. + exchange.setProperty(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + } } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/48b961b6/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpProducerKeepAliveTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpProducerKeepAliveTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpProducerKeepAliveTest.java index 26c0835..e4c22f1 100644 --- a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpProducerKeepAliveTest.java +++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpProducerKeepAliveTest.java @@ -16,8 +16,10 @@ */ package org.apache.camel.component.netty4.http; +import io.netty.handler.codec.http.HttpHeaders; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; -import org.junit.Ignore; import org.junit.Test; public class NettyHttpProducerKeepAliveTest extends BaseNettyTest { @@ -36,7 +38,6 @@ public class NettyHttpProducerKeepAliveTest extends BaseNettyTest { } @Test - @Ignore("Can fail on some CI servers") public void testHttpKeepAliveFalse() throws Exception { getMockEndpoint("mock:input").expectedBodiesReceived("Hello World", "Hello Again"); @@ -48,17 +49,36 @@ public class NettyHttpProducerKeepAliveTest extends BaseNettyTest { assertMockEndpointsSatisfied(); } + + @Test + public void testConnectionClosed() throws Exception { + getMockEndpoint("mock:input").expectedBodiesReceived("Hello World"); + Exchange ex = template.request("netty4-http:http://localhost:{{port}}/bar?keepAlive=false", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("Hello World"); + } + }); + + assertMockEndpointsSatisfied(); + assertEquals(HttpHeaders.Values.CLOSE, ex.getOut().getHeader(HttpHeaders.Names.CONNECTION)); + } + @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { - from("netty4-http:http://0.0.0.0:{{port}}/foo") + from("netty4-http:http://localhost:{{port}}/foo") .to("mock:input") .transform().constant("Bye World"); + + from("netty4-http:http://localhost:{{port}}/bar").removeHeaders("*").to("mock:input").transform().constant("Bye World"); } }; } + + }
