camel-netty-http: Fixed problem if message body is null. And an unit test.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/6bc5a693 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/6bc5a693 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/6bc5a693 Branch: refs/heads/master Commit: 6bc5a693cb7c117a01d12e05e81e4b7d720e536e Parents: 337c271 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Aug 1 19:43:47 2013 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Aug 1 19:43:47 2013 +0200 ---------------------------------------------------------------------- .../netty/http/DefaultNettyHttpBinding.java | 107 ++++++++++--------- .../http/handlers/HttpClientChannelHandler.java | 12 ++- .../http/handlers/HttpServerChannelHandler.java | 4 + .../http/NettyHttpRedirectNoLocationTest.java | 8 +- 4 files changed, 75 insertions(+), 56 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/6bc5a693/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 e464f0b..f739f81 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 @@ -290,64 +290,67 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding { Object body = message.getBody(); Exception cause = message.getExchange().getException(); - if (body != null || cause != null) { - // support bodies as native Netty - ChannelBuffer buffer; - - // if there was an exception then use that as body - if (cause != null) { - if (configuration.isTransferException()) { - // we failed due an exception, and transfer it as java serialized object - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(cause); - oos.flush(); - IOHelper.close(oos, bos); - - // the body should be the serialized java object of the exception - body = ChannelBuffers.copiedBuffer(bos.toByteArray()); - // force content type to be serialized java object - message.setHeader(Exchange.CONTENT_TYPE, NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT); - } else { - // we failed due an exception so print it as plain text - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - cause.printStackTrace(pw); - - // the body should then be the stacktrace - body = ChannelBuffers.copiedBuffer(sw.toString().getBytes()); - // force content type to be text/plain as that is what the stacktrace is - message.setHeader(Exchange.CONTENT_TYPE, "text/plain"); - } - - // and mark the exception as failure handled, as we handled it by returning it as the response - ExchangeHelper.setFailureHandled(message.getExchange()); + // support bodies as native Netty + ChannelBuffer buffer; + + // if there was an exception then use that as body + if (cause != null) { + if (configuration.isTransferException()) { + // we failed due an exception, and transfer it as java serialized object + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(cause); + oos.flush(); + IOHelper.close(oos, bos); + + // the body should be the serialized java object of the exception + body = ChannelBuffers.copiedBuffer(bos.toByteArray()); + // force content type to be serialized java object + message.setHeader(Exchange.CONTENT_TYPE, NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT); + } else { + // we failed due an exception so print it as plain text + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + cause.printStackTrace(pw); + + // the body should then be the stacktrace + body = ChannelBuffers.copiedBuffer(sw.toString().getBytes()); + // force content type to be text/plain as that is what the stacktrace is + message.setHeader(Exchange.CONTENT_TYPE, "text/plain"); } - if (body instanceof ChannelBuffer) { - buffer = (ChannelBuffer) body; - } else { - // try to convert to buffer first - buffer = message.getBody(ChannelBuffer.class); - if (buffer == null) { - // fallback to byte array as last resort - byte[] data = message.getBody(byte[].class); - if (data != null) { - buffer = ChannelBuffers.copiedBuffer(data); + // and mark the exception as failure handled, as we handled it by returning it as the response + ExchangeHelper.setFailureHandled(message.getExchange()); + } + + if (body instanceof ChannelBuffer) { + buffer = (ChannelBuffer) body; + } else { + // try to convert to buffer first + buffer = message.getBody(ChannelBuffer.class); + if (buffer == null) { + // fallback to byte array as last resort + byte[] data = message.getBody(byte[].class); + if (data != null) { + buffer = ChannelBuffers.copiedBuffer(data); + } else { + // and if byte array fails then try String + String str; + if (body != null) { + str = message.getMandatoryBody(String.class); } else { - // and if byte array fails then try String - String str = message.getMandatoryBody(String.class); - buffer = ChannelBuffers.copiedBuffer(str.getBytes()); + str = ""; } + buffer = ChannelBuffers.copiedBuffer(str.getBytes()); } } - if (buffer != null) { - response.setContent(buffer); - int len = buffer.readableBytes(); - // set content-length - response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, len); - LOG.trace("Content-Length: {}", len); - } + } + if (buffer != null) { + response.setContent(buffer); + int len = buffer.readableBytes(); + // set content-length + response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, len); + LOG.trace("Content-Length: {}", len); } // set the content type in the response. http://git-wip-us.apache.org/repos/asf/camel/blob/6bc5a693/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java index e2cccf1..cdee347 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java @@ -46,9 +46,17 @@ public class HttpClientChannelHandler extends ClientChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent messageEvent) throws Exception { // store response, as this channel handler is created per pipeline - response = (HttpResponse) messageEvent.getMessage(); + Object msg = messageEvent.getMessage(); + if (msg instanceof HttpResponse) { + response = (HttpResponse) msg; + super.messageReceived(ctx, messageEvent); + } else { + // ignore not supported message + if (msg != null) { + LOG.trace("Ignoring non HttpResponse message of type {} -> {}", msg.getClass(), msg); + } + } - super.messageReceived(ctx, messageEvent); } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/6bc5a693/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java index 12c1083..0ae157b 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java @@ -92,6 +92,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { // are we suspended? LOG.debug("Consumer suspended, cannot service request {}", request); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, SERVICE_UNAVAILABLE); + response.setChunked(false); response.setHeader(Exchange.CONTENT_TYPE, "text/plain"); response.setHeader(Exchange.CONTENT_LENGTH, 0); response.setContent(ChannelBuffers.copiedBuffer(new byte[]{})); @@ -101,6 +102,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { if (consumer.getEndpoint().getHttpMethodRestrict() != null && !consumer.getEndpoint().getHttpMethodRestrict().contains(request.getMethod().getName())) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED); + response.setChunked(false); response.setHeader(Exchange.CONTENT_TYPE, "text/plain"); response.setHeader(Exchange.CONTENT_LENGTH, 0); response.setContent(ChannelBuffers.copiedBuffer(new byte[]{})); @@ -109,6 +111,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { } if ("TRACE".equals(request.getMethod().getName()) && !consumer.getEndpoint().isTraceEnabled()) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED); + response.setChunked(false); response.setHeader(Exchange.CONTENT_TYPE, "text/plain"); response.setHeader(Exchange.CONTENT_LENGTH, 0); response.setContent(ChannelBuffers.copiedBuffer(new byte[]{})); @@ -118,6 +121,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { // must include HOST header as required by HTTP 1.1 if (!request.getHeaderNames().contains(HttpHeaders.Names.HOST)) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST); + response.setChunked(false); response.setHeader(Exchange.CONTENT_TYPE, "text/plain"); response.setHeader(Exchange.CONTENT_LENGTH, 0); response.setContent(ChannelBuffers.copiedBuffer(new byte[]{})); http://git-wip-us.apache.org/repos/asf/camel/blob/6bc5a693/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectNoLocationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectNoLocationTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectNoLocationTest.java index 0005673..0762bba 100644 --- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectNoLocationTest.java +++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectNoLocationTest.java @@ -24,10 +24,12 @@ import org.junit.Test; public class NettyHttpRedirectNoLocationTest extends BaseNettyTest { + private int nextPort; + @Test public void testHttpRedirectNoLocation() throws Exception { try { - template.requestBody("netty-http:http://localhost:{{port}}/test", "Hello World", String.class); + template.requestBody("netty-http:http://localhost:" + nextPort + "/test", "Hello World", String.class); fail("Should have thrown an exception"); } catch (RuntimeCamelException e) { NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause()); @@ -43,7 +45,9 @@ public class NettyHttpRedirectNoLocationTest extends BaseNettyTest { return new RouteBuilder() { @Override public void configure() throws Exception { - from("netty-http:http://localhost:{{port}}/test") + nextPort = getNextPort(); + + from("netty-http:http://localhost:" + nextPort + "/test") .process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, 302);