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 2013/05/08 11:32:06 UTC

[1/5] git commit: CAMEL-6327: More work on new camel-netty-http component.

Updated Branches:
  refs/heads/master 39cc1509a -> 514df2fb4


CAMEL-6327: More work on new camel-netty-http component.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/514df2fb
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/514df2fb
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/514df2fb

Branch: refs/heads/master
Commit: 514df2fb4fa05b6cec3f89b5805fcf3b8c0cd446
Parents: b67f5f9
Author: Claus Ibsen <da...@apache.org>
Authored: Wed May 8 11:27:12 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed May 8 11:31:50 2013 +0200

----------------------------------------------------------------------
 .../netty/http/NettyHttpReturnFaultTest.java       |    2 -
 .../netty/handlers/ServerChannelHandler.java       |   16 +++++---------
 2 files changed, 6 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/514df2fb/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
index 3943297..36b6383 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
@@ -19,13 +19,11 @@ 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.junit.Ignore;
 import org.junit.Test;
 
 public class NettyHttpReturnFaultTest extends BaseNettyTest {
 
     @Test
-    @Ignore
     public void testHttpFault() throws Exception {
         Exchange exchange = template.request("netty-http:http://localhost:{{port}}/test", new Processor() {
             @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/514df2fb/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java b/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java
index a054418..a509692 100644
--- a/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java
+++ b/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java
@@ -25,6 +25,7 @@ import org.apache.camel.component.netty.NettyConsumer;
 import org.apache.camel.component.netty.NettyHelper;
 import org.apache.camel.component.netty.NettyPayloadHelper;
 import org.apache.camel.util.CamelLogger;
+import org.apache.camel.util.ExchangeHelper;
 import org.apache.camel.util.IOHelper;
 import org.jboss.netty.channel.ChannelFutureListener;
 import org.jboss.netty.channel.ChannelHandlerContext;
@@ -133,16 +134,6 @@ public class ServerChannelHandler extends SimpleChannelUpstreamHandler {
     private void sendResponse(MessageEvent messageEvent, Exchange exchange) throws Exception {
         Object body = getResponseBody(exchange);
 
-        boolean failed = exchange.isFailed();
-        if (failed && !consumer.getEndpoint().getConfiguration().isTransferExchange()) {
-            if (exchange.getException() != null) {
-                body = exchange.getException();
-            } else {
-                // failed and no exception, must be a fault
-                body = exchange.getOut().getBody();
-            }
-        }
-
         if (body == null) {
             noReplyLogger.log("No payload to send as reply for exchange: " + exchange);
             if (consumer.getConfiguration().isDisconnectOnNoReply()) {
@@ -177,6 +168,11 @@ public class ServerChannelHandler extends SimpleChannelUpstreamHandler {
      * @throws Exception is thrown if error getting the response body
      */
     protected Object getResponseBody(Exchange exchange) throws Exception {
+        // if there was an exception then use that as response body
+        boolean exception = exchange.getException() != null && !consumer.getEndpoint().getConfiguration().isTransferExchange();
+        if (exception) {
+            return exchange.getException();
+        }
         if (exchange.hasOut()) {
             return NettyPayloadHelper.getOut(consumer.getEndpoint(), exchange);
         } else {


[4/5] git commit: CAMEL-6327: More work on new camel-netty-http component.

Posted by da...@apache.org.
CAMEL-6327: More work on new camel-netty-http component.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b67f5f90
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b67f5f90
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b67f5f90

Branch: refs/heads/master
Commit: b67f5f903275776f619d536c172682965e14dcd3
Parents: 27087f0
Author: Claus Ibsen <da...@apache.org>
Authored: Wed May 8 11:08:03 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed May 8 11:31:50 2013 +0200

----------------------------------------------------------------------
 .../netty/http/DefaultNettyHttpBinding.java        |  197 ++++++++++++---
 .../component/netty/http/NettyHttpBinding.java     |   50 +++--
 .../component/netty/http/NettyHttpComponent.java   |   18 ++-
 .../netty/http/NettyHttpConfiguration.java         |   36 +++
 .../component/netty/http/NettyHttpConstants.java   |   30 +++
 .../component/netty/http/NettyHttpConsumer.java    |    5 +
 .../component/netty/http/NettyHttpConverter.java   |    8 +
 .../component/netty/http/NettyHttpEndpoint.java    |   25 ++-
 .../component/netty/http/NettyHttpHelper.java      |   87 +++++++
 .../component/netty/http/NettyHttpMessage.java     |   22 +--
 .../http/NettyHttpOperationFailedException.java    |   76 ++++++
 .../component/netty/http/NettyHttpProducer.java    |   65 +++++-
 .../http/handlers/HttpClientChannelHandler.java    |    2 +-
 .../http/handlers/HttpServerChannelHandler.java    |   12 +-
 .../netty/http/NettyHttp500ErrorTest.java          |   66 +++++
 ...ettyHttp500ErrorThrowExceptionOnServerTest.java |   66 +++++
 ...tyHttpAccessHttpRequestAndResponseBeanTest.java |    4 +-
 .../http/NettyHttpAccessHttpRequestBeanTest.java   |    2 +-
 .../netty/http/NettyHttpAccessHttpRequestTest.java |    2 +-
 ...pBindingPreservePostFormUrlEncodedBodyTest.java |   68 +++++
 .../netty/http/NettyHttpCharacterEncodingTest.java |   63 +++++
 .../netty/http/NettyHttpContentTypeTest.java       |    3 +-
 .../NettyHttpConvertPayloadToInputStreamTest.java  |   62 +++++
 .../NettyHttpEndpointUriEncodingIssueTest.java     |   67 +++++
 ...pointUriEncodingIssueUrlDecodeDisabledTest.java |   50 ++++
 .../http/NettyHttpFilterCamelHeadersTest.java      |   76 ++++++
 .../netty/http/NettyHttpHeaderCaseTest.java        |   73 ++++++
 .../netty/http/NettyHttpMapHeadersFalseTest.java   |   70 +++++
 .../http/NettyHttpProducerConcurrentTest.java      |   85 +++++++
 .../netty/http/NettyHttpProducerKeepAliveTest.java |   62 +++++
 .../http/NettyHttpProducerSendEmptyHeaderTest.java |   48 ++++
 .../netty/http/NettyHttpProducerSimpleGetTest.java |   69 +++++
 ...tyHttpProducerTwoParametersWithSameKeyTest.java |  100 ++++++++
 .../http/NettyHttpRedirectNoLocationTest.java      |   55 ++++
 .../netty/http/NettyHttpRedirectTest.java          |   56 ++++
 ...ttpReturnDataNotInputStreamConvertableTest.java |   53 ++++
 .../netty/http/NettyHttpReturnFaultTest.java       |   60 +++++
 .../component/netty/http/NettyHttpSimpleTest.java  |    2 +-
 .../http/NettyHttpSimpleUriParametersTest.java     |   46 ++++
 .../netty/http/NettyHttpTransferExceptionTest.java |   52 ++++
 .../netty/http/NettyUseRawHttpResponseTest.java    |    2 +-
 41 files changed, 1901 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/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 42b583e..121e98e 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
@@ -16,16 +16,26 @@
  */
 package org.apache.camel.component.netty.http;
 
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.util.ExchangeHelper;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.MessageHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
@@ -55,12 +65,14 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
     }
 
     @Override
-    public Message toCamelMessage(HttpRequest request, Exchange exchange) throws Exception {
+    public Message toCamelMessage(HttpRequest request, Exchange exchange, NettyHttpConfiguration configuration) throws Exception {
         LOG.trace("toCamelMessage: {}", request);
 
-        NettyHttpMessage answer = new NettyHttpMessage(request, null, this);
-        // force getting headers which will populate them
-        answer.getHeaders();
+        NettyHttpMessage answer = new NettyHttpMessage(request, null);
+        answer.setExchange(exchange);
+        if (configuration.isMapHeaders()) {
+            populateCamelHeaders(request, answer.getHeaders(), exchange, configuration);
+        }
 
         // keep the body as is, and use type converters
         answer.setBody(request.getContent());
@@ -68,15 +80,17 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
     }
 
     @Override
-    public void populateCamelHeaders(HttpRequest request, Map<String, Object> headers, Exchange exchange) throws Exception {
+    public void populateCamelHeaders(HttpRequest request, Map<String, Object> headers, Exchange exchange, NettyHttpConfiguration configuration) throws Exception {
         LOG.trace("populateCamelHeaders: {}", request);
 
+        String uri = request.getUri();
+
         headers.put(Exchange.HTTP_METHOD, request.getMethod().getName());
-        headers.put(Exchange.HTTP_URI, request.getUri());
+        headers.put(Exchange.HTTP_URI, uri);
 
         if (LOG.isTraceEnabled()) {
             LOG.trace("HTTP-Method {}", request.getMethod().getName());
-            LOG.trace("HTTP-Uri {}", request.getUri());
+            LOG.trace("HTTP-Uri {}", uri);
         }
 
         for (String name : request.getHeaderNames()) {
@@ -89,22 +103,72 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
             Iterator<?> it = ObjectHelper.createIterator(values);
             while (it.hasNext()) {
                 Object extracted = it.next();
+                Object decoded = configuration.isUrlDecodeHeaders() ? URLDecoder.decode(extracted.toString(), "UTF-8") : extracted.toString();
                 LOG.trace("HTTP-header: {}", extracted);
                 if (headerFilterStrategy != null
-                        && !headerFilterStrategy.applyFilterToExternalHeaders(name, extracted, exchange)) {
-                    NettyHttpHelper.appendHeader(headers, name, extracted);
+                        && !headerFilterStrategy.applyFilterToExternalHeaders(name, decoded, exchange)) {
+                    NettyHttpHelper.appendHeader(headers, name, decoded);
+                }
+            }
+        }
+
+        // add uri parameters as headers to the Camel message
+        if (uri.contains("?")) {
+            String query = ObjectHelper.after(uri, "?");
+            Map<String, Object> uriParameters = URISupport.parseQuery(query);
+
+            for (Map.Entry<String, Object> entry : uriParameters.entrySet()) {
+                String name = entry.getKey();
+                Object values = entry.getValue();
+                Iterator<?> it = ObjectHelper.createIterator(values);
+                while (it.hasNext()) {
+                    Object extracted = it.next();
+                    Object decoded = configuration.isUrlDecodeHeaders() ? URLDecoder.decode(extracted.toString(), "UTF-8") : extracted.toString();
+                    LOG.trace("URI-Parameter: {}", extracted);
+                    if (headerFilterStrategy != null
+                            && !headerFilterStrategy.applyFilterToExternalHeaders(name, decoded, exchange)) {
+                        NettyHttpHelper.appendHeader(headers, name, decoded);
+                    }
                 }
             }
         }
+
+        // if body is application/x-www-form-urlencoded then extract the body as query string and append as headers
+        if (request.getMethod().getName().equals("POST") && request.getHeader(Exchange.CONTENT_TYPE) != null
+                && request.getHeader(Exchange.CONTENT_TYPE).startsWith(NettyHttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED)) {
+
+            String charset = "UTF-8";
+
+            // Push POST form params into the headers to retain compatibility with DefaultHttpBinding
+            String body = request.getContent().toString(Charset.forName(charset));
+            if (ObjectHelper.isNotEmpty(body)) {
+                for (String param : body.split("&")) {
+                    String[] pair = param.split("=", 2);
+                    if (pair.length == 2) {
+                        String name = configuration.isUrlDecodeHeaders() ? URLDecoder.decode(pair[0], charset) : pair[0];
+                        String value = configuration.isUrlDecodeHeaders() ? URLDecoder.decode(pair[1], charset) : pair[1];
+                        if (headerFilterStrategy != null
+                                && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) {
+                            NettyHttpHelper.appendHeader(headers, name, value);
+                        }
+                    } else {
+                        throw new IllegalArgumentException("Invalid parameter, expected to be a pair but was " + param);
+                    }
+                }
+            }
+        }
+
     }
 
     @Override
-    public Message toCamelMessage(HttpResponse response, Exchange exchange) throws Exception {
+    public Message toCamelMessage(HttpResponse response, Exchange exchange, NettyHttpConfiguration configuration) throws Exception {
         LOG.trace("toCamelMessage: {}", response);
 
-        NettyHttpMessage answer = new NettyHttpMessage(null, response, this);
-        // force getting headers which will populate them
-        answer.getHeaders();
+        NettyHttpMessage answer = new NettyHttpMessage(null, response);
+        answer.setExchange(exchange);
+        if (configuration.isMapHeaders()) {
+            populateCamelHeaders(response, answer.getHeaders(), exchange, configuration);
+        }
 
         // keep the body as is, and use type converters
         answer.setBody(response.getContent());
@@ -112,12 +176,11 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
     }
 
     @Override
-    public void populateCamelHeaders(HttpResponse response, Map<String, Object> headers, Exchange exchange) throws Exception {
+    public void populateCamelHeaders(HttpResponse response, Map<String, Object> headers, Exchange exchange, NettyHttpConfiguration configuration) throws Exception {
         LOG.trace("populateCamelHeaders: {}", response);
 
         headers.put(Exchange.HTTP_RESPONSE_CODE, response.getStatus().getCode());
-        // TODO: use another status header
-        headers.put("CamelHttpResponseText", response.getStatus().getReasonPhrase());
+        headers.put(NettyHttpConstants.HTTP_RESPONSE_TEXT, response.getStatus().getReasonPhrase());
 
         for (String name : response.getHeaderNames()) {
             // mapping the content-type
@@ -139,7 +202,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
     }
 
     @Override
-    public HttpResponse toNettyResponse(Message message) throws Exception {
+    public HttpResponse toNettyResponse(Message message, NettyHttpConfiguration configuration) throws Exception {
         LOG.trace("toNettyResponse: {}", message);
 
         // the message body may already be a Netty HTTP response
@@ -147,8 +210,11 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
             return (HttpResponse) message.getBody();
         }
 
-        // the status code is default 200, but a header can override that
-        Integer code = message.getHeader(Exchange.HTTP_RESPONSE_CODE, 200, Integer.class);
+        // the response code is 200 for OK and 500 for failed
+        boolean failed = message.getExchange().isFailed();
+        int defaultCode = failed ? 500 : 200;
+
+        int code = message.getHeader(Exchange.HTTP_RESPONSE_CODE, defaultCode, int.class);
         HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(code));
         LOG.trace("HTTP Status Code: {}", code);
 
@@ -172,9 +238,41 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
         }
 
         Object body = message.getBody();
-        if (body != null) {
+        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());
+            }
+
             if (body instanceof ChannelBuffer) {
                 buffer = (ChannelBuffer) body;
             } else {
@@ -182,8 +280,14 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
                 buffer = message.getBody(ChannelBuffer.class);
                 if (buffer == null) {
                     // fallback to byte array as last resort
-                    byte[] data = message.getMandatoryBody(byte[].class);
-                    buffer = ChannelBuffers.copiedBuffer(data);
+                    byte[] data = message.getBody(byte[].class);
+                    if (data != null) {
+                        buffer = ChannelBuffers.copiedBuffer(data);
+                    } else {
+                        // and if byte array fails then try String
+                        String str = message.getMandatoryBody(String.class);
+                        buffer = ChannelBuffers.copiedBuffer(str.getBytes());
+                    }
                 }
             }
             if (buffer != null) {
@@ -203,16 +307,25 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
             LOG.trace("Content-Type: {}", contentType);
         }
 
-        // TODO: keep alive should be something we can control
-        String keepAlive = HttpHeaders.Values.CLOSE;
-        response.setHeader(HttpHeaders.Names.CONNECTION, keepAlive);
-        LOG.trace("Connection: {}", keepAlive);
+        // configure connection to accordingly to keep alive configuration
+        // favor using the header from the message
+        String connection = message.getHeader(HttpHeaders.Names.CONNECTION, String.class);
+        if (connection == null) {
+            // fallback and use the keep alive from the configuration
+            if (configuration.isKeepAlive()) {
+                connection = HttpHeaders.Values.KEEP_ALIVE;
+            } else {
+                connection = HttpHeaders.Values.CLOSE;
+            }
+        }
+        response.setHeader(HttpHeaders.Names.CONNECTION, connection);
+        LOG.trace("Connection: {}", connection);
 
         return response;
     }
 
     @Override
-    public HttpRequest toNettyRequest(Message message, String uri) throws Exception {
+    public HttpRequest toNettyRequest(Message message, String uri, NettyHttpConfiguration configuration) throws Exception {
         LOG.trace("toNettyRequest: {}", message);
 
         // the message body may already be a Netty HTTP response
@@ -220,8 +333,8 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
             return (HttpRequest) message.getBody();
         }
 
-        // TODO: Compute the method to use
-        HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri);
+        // 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);
 
         TypeConverter tc = message.getExchange().getContext().getTypeConverter();
 
@@ -231,7 +344,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
             String key = entry.getKey();
             Object value = entry.getValue();
             // use an iterator as there can be multiple values. (must not use a delimiter)
-            final Iterator<?> it = ObjectHelper.createIterator(value, null);
+            final Iterator<?> it = ObjectHelper.createIterator(value, null, true);
             while (it.hasNext()) {
                 String headerValue = tc.convertTo(String.class, it.next());
                 if (headerValue != null && headerFilterStrategy != null
@@ -263,9 +376,16 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
                 // set content-length
                 request.setHeader(HttpHeaders.Names.CONTENT_LENGTH, len);
                 LOG.trace("Content-Length: {}", len);
+            } else {
+                // we do not support this kind of body
+                throw new NoTypeConversionAvailableException(body, ChannelBuffer.class);
             }
         }
 
+        // update HTTP method accordingly as we know if we have a body or not
+        HttpMethod method = NettyHttpHelper.createMethod(message, body != null);
+        request.setMethod(method);
+
         // set the content type in the response.
         String contentType = MessageHelper.getContentType(message);
         if (contentType != null) {
@@ -274,10 +394,19 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding {
             LOG.trace("Content-Type: {}", contentType);
         }
 
-        // TODO: keep alive should be something we can control
-        String keepAlive = HttpHeaders.Values.CLOSE;
-        request.setHeader(HttpHeaders.Names.CONNECTION, keepAlive);
-        LOG.trace("Connection: {}", keepAlive);
+        // configure connection to accordingly to keep alive configuration
+        // favor using the header from the message
+        String connection = message.getHeader(HttpHeaders.Names.CONNECTION, String.class);
+        if (connection == null) {
+            // fallback and use the keep alive from the configuration
+            if (configuration.isKeepAlive()) {
+                connection = HttpHeaders.Values.KEEP_ALIVE;
+            } else {
+                connection = HttpHeaders.Values.CLOSE;
+            }
+        }
+        request.setHeader(HttpHeaders.Names.CONNECTION, connection);
+        LOG.trace("Connection: {}", connection);
 
         return request;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
index f467a60..cd67e96 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
@@ -31,62 +31,74 @@ public interface NettyHttpBinding {
 
     /**
      * Binds from Netty {@link HttpRequest} to Camel {@Message}.
+     * <p/>
+     * Will use {@link #populateCamelHeaders(org.jboss.netty.handler.codec.http.HttpRequest, java.util.Map, org.apache.camel.Exchange, NettyHttpConfiguration)}
+     * for populating the headers.
      *
-     * @param request   the netty http request
-     * @param exchange  the exchange that should contain the returned message.
+     * @param request       the netty http request
+     * @param exchange      the exchange that should contain the returned message.
+     * @param configuration the endpoint configuration
      * @return the message to store on the given exchange
      * @throws Exception is thrown if error during binding
      */
-    Message toCamelMessage(HttpRequest request, Exchange exchange) throws Exception;
+    Message toCamelMessage(HttpRequest request, Exchange exchange, NettyHttpConfiguration configuration) throws Exception;
 
     /**
      * Binds from Netty {@link HttpRequest} to Camel headers as a {@link Map}.
      *
-     * @param request   the netty http request
-     * @param headers   the Camel headers that should be populated
-     * @param exchange  the exchange that should contain the returned message.
+     * @param request       the netty http request
+     * @param headers       the Camel headers that should be populated
+     * @param exchange      the exchange that should contain the returned message.
+     * @param configuration the endpoint configuration
      * @throws Exception is thrown if error during binding
      */
-    void populateCamelHeaders(HttpRequest request, Map<String, Object> headers, Exchange exchange) throws Exception;
+    void populateCamelHeaders(HttpRequest request, Map<String, Object> headers, Exchange exchange, NettyHttpConfiguration configuration) throws Exception;
 
     /**
      * Binds from Netty {@link HttpResponse} to Camel {@Message}.
+     * <p/>
+     * Will use {@link #populateCamelHeaders(org.jboss.netty.handler.codec.http.HttpResponse, java.util.Map, org.apache.camel.Exchange, NettyHttpConfiguration)}
+     * for populating the headers.
      *
-     * @param response  the netty http response
-     * @param exchange  the exchange that should contain the returned message.
+     * @param response      the netty http response
+     * @param exchange      the exchange that should contain the returned message.
+     * @param configuration the endpoint configuration
      * @return the message to store on the given exchange
      * @throws Exception is thrown if error during binding
      */
-    Message toCamelMessage(HttpResponse response, Exchange exchange) throws Exception;
+    Message toCamelMessage(HttpResponse response, Exchange exchange, NettyHttpConfiguration configuration) throws Exception;
 
     /**
      * Binds from Netty {@link HttpResponse} to Camel headers as a {@link Map}.
      *
-     * @param response   the netty http response
-     * @param headers   the Camel headers that should be populated
-     * @param exchange  the exchange that should contain the returned message.
+     * @param response      the netty http response
+     * @param headers       the Camel headers that should be populated
+     * @param exchange      the exchange that should contain the returned message.
+     * @param configuration the endpoint configuration
      * @throws Exception is thrown if error during binding
      */
-    void populateCamelHeaders(HttpResponse response, Map<String, Object> headers, Exchange exchange) throws Exception;
+    void populateCamelHeaders(HttpResponse response, Map<String, Object> headers, Exchange exchange, NettyHttpConfiguration configuration) throws Exception;
 
     /**
      * Binds from Camel {@link Message} to Netty {@link HttpResponse}.
      *
-     * @param message  the Camel message
+     * @param message       the Camel message
+     * @param configuration the endpoint configuration
      * @return the http response
      * @throws Exception is thrown if error during binding
      */
-    HttpResponse toNettyResponse(Message message) throws Exception;
+    HttpResponse toNettyResponse(Message message, NettyHttpConfiguration configuration) throws Exception;
 
     /**
      * Binds from Camel {@link Message} to Netty {@link org.jboss.netty.handler.codec.http.HttpRequest}.
      *
-     * @param message  the Camel message
-     * @param uri      the uri which is the intended uri to call, though the message may override the uri
+     * @param message       the Camel message
+     * @param uri           the uri which is the intended uri to call, though the message may override the uri
+     * @param configuration the endpoint configuration
      * @return the http request
      * @throws Exception is thrown if error during binding
      */
-    HttpRequest toNettyRequest(Message message, String uri) throws Exception;
+    HttpRequest toNettyRequest(Message message, String uri, NettyHttpConfiguration configuration) throws Exception;
 
     /**
      * Gets the header filter strategy

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
index c8c107e..b423201 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
@@ -24,18 +24,23 @@ import org.apache.camel.component.netty.NettyComponent;
 import org.apache.camel.component.netty.NettyConfiguration;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategyAware;
+import org.apache.camel.util.URISupport;
 
 /**
  * Netty HTTP based component.
  */
 public class NettyHttpComponent extends NettyComponent implements HeaderFilterStrategyAware {
 
-    // TODO: consider supporting on consumer
+    // TODO: support on consumer
     // - bridgeEndpoint
     // - matchOnUriPrefix
+    // - urlrewrite
 
-    // TODO: netty http producer
-    // TODO: make it easy to turn keep-alive on|off on producer
+    // TODO: producer
+    // - add support for HTTP_URI / HTTP_QUERY overrides
+    // - add actual url to state so we know exactly which url we called also for done callback
+    // - add support for connection timeout
+    // - add support for request timeout
 
     private NettyHttpBinding nettyHttpBinding;
     private HeaderFilterStrategy headerFilterStrategy;
@@ -64,6 +69,13 @@ public class NettyHttpComponent extends NettyComponent implements HeaderFilterSt
         NettyHttpEndpoint answer = new NettyHttpEndpoint(remaining, this, config);
         answer.setTimer(getTimer());
         setProperties(answer.getConfiguration(), parameters);
+
+        // any leftover parameters is uri parameters
+        if (!parameters.isEmpty()) {
+            String query = URISupport.createQueryString(parameters);
+            answer.setUriParameters(query);
+        }
+
         // set component options on endpoint as defaults
         if (answer.getNettyHttpBinding() == null) {
             answer.setNettyHttpBinding(getNettyHttpBinding());

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/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 4b52844..26a636f 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
@@ -29,7 +29,11 @@ import org.jboss.netty.channel.ChannelHandler;
 public class NettyHttpConfiguration extends NettyConfiguration {
 
     private boolean chunked = true;
+    private boolean urlDecodeHeaders = true;
+    private boolean mapHeaders = true;
     private boolean compression;
+    private boolean throwExceptionOnFailure = true;
+    private boolean transferException;
 
     public NettyHttpConfiguration() {
         // we need sync=true as http is request/reply by nature
@@ -70,4 +74,36 @@ public class NettyHttpConfiguration extends NettyConfiguration {
     public void setCompression(boolean compression) {
         this.compression = compression;
     }
+
+    public boolean isThrowExceptionOnFailure() {
+        return throwExceptionOnFailure;
+    }
+
+    public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
+        this.throwExceptionOnFailure = throwExceptionOnFailure;
+    }
+
+    public boolean isTransferException() {
+        return transferException;
+    }
+
+    public void setTransferException(boolean transferException) {
+        this.transferException = transferException;
+    }
+
+    public boolean isUrlDecodeHeaders() {
+        return urlDecodeHeaders;
+    }
+
+    public void setUrlDecodeHeaders(boolean urlDecodeHeaders) {
+        this.urlDecodeHeaders = urlDecodeHeaders;
+    }
+
+    public boolean isMapHeaders() {
+        return mapHeaders;
+    }
+
+    public void setMapHeaders(boolean mapHeaders) {
+        this.mapHeaders = mapHeaders;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java
new file mode 100644
index 0000000..073ba78
--- /dev/null
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java
@@ -0,0 +1,30 @@
+/**
+ * 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;
+
+/**
+ * Netty HTTP constants.
+ */
+public final class NettyHttpConstants {
+
+    public static final String CONTENT_TYPE_JAVA_SERIALIZED_OBJECT = "application/x-java-serialized-object";
+    public static final String CONTENT_TYPE_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
+    public static final String HTTP_RESPONSE_TEXT = "CamelHttpResponseText";
+
+    private NettyHttpConstants() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConsumer.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConsumer.java
index 5b76a28..01ef9b9 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConsumer.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConsumer.java
@@ -33,4 +33,9 @@ public class NettyHttpConsumer extends NettyConsumer {
     public NettyHttpEndpoint getEndpoint() {
         return (NettyHttpEndpoint) super.getEndpoint();
     }
+
+    @Override
+    public NettyHttpConfiguration getConfiguration() {
+        return (NettyHttpConfiguration) super.getConfiguration();
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
index 9cf6a80..affef68 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.netty.http;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.nio.charset.Charset;
 
 import org.apache.camel.Converter;
@@ -100,4 +102,10 @@ public final class NettyHttpConverter {
         return response.getContent().toByteBuffer().array();
     }
 
+    @Converter
+    public static InputStream toInputStream(HttpResponse response, Exchange exchange) {
+        byte[] bytes = toBytes(response, exchange);
+        return new ByteArrayInputStream(bytes);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
index 32a9744..a010fb3 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.netty.http;
 import org.apache.camel.Consumer;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.netty.NettyConfiguration;
@@ -37,6 +38,7 @@ import org.jboss.netty.handler.codec.http.HttpRequest;
  */
 public class NettyHttpEndpoint extends NettyEndpoint implements HeaderFilterStrategyAware {
 
+    private String uriParameters;
     private NettyHttpBinding nettyHttpBinding;
     private HeaderFilterStrategy headerFilterStrategy;
     private boolean traceEnabled;
@@ -55,7 +57,7 @@ public class NettyHttpEndpoint extends NettyEndpoint implements HeaderFilterStra
 
     @Override
     public Producer createProducer() throws Exception {
-        Producer answer = new NettyHttpProducer(this, getConfiguration());
+        Producer answer = new NettyHttpProducer(this, getConfiguration(), getUriParameters());
         if (isSynchronous()) {
             return new SynchronousDelegateProducer(answer);
         } else {
@@ -64,12 +66,17 @@ public class NettyHttpEndpoint extends NettyEndpoint implements HeaderFilterStra
     }
 
     @Override
+    public PollingConsumer createPollingConsumer() throws Exception {
+        throw new UnsupportedOperationException("This component does not support polling consumer");
+    }
+
+    @Override
     public Exchange createExchange(ChannelHandlerContext ctx, MessageEvent messageEvent) throws Exception {
         Exchange exchange = createExchange();
 
         // use the http binding
         HttpRequest request = (HttpRequest) messageEvent.getMessage();
-        Message in = getNettyHttpBinding().toCamelMessage(request, exchange);
+        Message in = getNettyHttpBinding().toCamelMessage(request, exchange, getConfiguration());
         exchange.setIn(in);
 
         // set additional headers
@@ -86,6 +93,12 @@ public class NettyHttpEndpoint extends NettyEndpoint implements HeaderFilterStra
     }
 
     @Override
+    public boolean isLenientProperties() {
+        // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
+        return true;
+    }
+
+    @Override
     public NettyHttpConfiguration getConfiguration() {
         return (NettyHttpConfiguration) super.getConfiguration();
     }
@@ -122,6 +135,14 @@ public class NettyHttpEndpoint extends NettyEndpoint implements HeaderFilterStra
         this.httpMethodRestrict = httpMethodRestrict;
     }
 
+    public String getUriParameters() {
+        return uriParameters;
+    }
+
+    public void setUriParameters(String uriParameters) {
+        this.uriParameters = uriParameters;
+    }
+
     @Override
     protected void doStart() throws Exception {
         super.doStart();

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
index 559f4df..d23a67f 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
@@ -16,13 +16,19 @@
  */
 package org.apache.camel.component.netty.http;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.Message;
 import org.apache.camel.converter.IOConverter;
 import org.apache.camel.util.IOHelper;
+import org.jboss.netty.handler.codec.http.HttpMethod;
+import org.jboss.netty.handler.codec.http.HttpResponse;
 
 /**
  * Helpers.
@@ -80,4 +86,85 @@ public final class NettyHttpHelper {
         headers.put(key, value);
     }
 
+    /**
+     * Creates the {@link HttpMethod} to use to call the remote server, often either its GET or POST.
+     *
+     * @param message  the Camel message
+     * @return the created method
+     */
+    public static HttpMethod createMethod(Message message, boolean hasPayload) {
+        // use header first
+        HttpMethod m = message.getHeader(Exchange.HTTP_METHOD, HttpMethod.class);
+        if (m != null) {
+            return m;
+        }
+        String name = message.getHeader(Exchange.HTTP_METHOD, String.class);
+        if (name != null) {
+            return HttpMethod.valueOf(name);
+        }
+
+        if (hasPayload) {
+            // use POST if we have payload
+            return HttpMethod.POST;
+        } else {
+            // fallback to GET
+            return HttpMethod.GET;
+        }
+    }
+
+    public static Exception populateNettyHttpOperationFailedException(Exchange exchange, HttpResponse response, int responseCode, boolean transferException) {
+        // TODO: we need to have the uri of the http server we called
+        String uri = "TODO";
+        String statusText = response.getStatus().getReasonPhrase();
+
+        if (responseCode >= 300 && responseCode < 400) {
+            String redirectLocation = response.getHeader("location");
+            if (redirectLocation != null) {
+                return new NettyHttpOperationFailedException(uri, responseCode, statusText, redirectLocation, response);
+            } else {
+                // no redirect location
+                return new NettyHttpOperationFailedException(uri, responseCode, statusText, null, response);
+            }
+        }
+
+        if (transferException) {
+            String contentType = response.getHeader(Exchange.CONTENT_TYPE);
+            if (NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
+                // if the response was a serialized exception then use that
+                InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, response);
+                if (is != null) {
+                    try {
+                        Object body = deserializeJavaObjectFromStream(is);
+                        if (body instanceof Exception) {
+                            return (Exception) body;
+                        }
+                    } catch (Exception e) {
+                        return e;
+                    } finally {
+                        IOHelper.close(is);
+                    }
+                }
+            }
+        }
+
+        // internal server error (error code 500)
+        return new NettyHttpOperationFailedException(uri, responseCode, statusText, null, response);
+    }
+
+    public static Object deserializeJavaObjectFromStream(InputStream is) throws ClassNotFoundException, IOException {
+        if (is == null) {
+            return null;
+        }
+
+        Object answer = null;
+        ObjectInputStream ois = new ObjectInputStream(is);
+        try {
+            answer = ois.readObject();
+        } finally {
+            IOHelper.close(ois);
+        }
+
+        return answer;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
index 7bec4aa..ba4ca55 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
@@ -16,9 +16,6 @@
  */
 package org.apache.camel.component.netty.http;
 
-import java.util.Map;
-
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.impl.DefaultMessage;
 import org.jboss.netty.handler.codec.http.HttpRequest;
 import org.jboss.netty.handler.codec.http.HttpResponse;
@@ -33,12 +30,10 @@ public class NettyHttpMessage extends DefaultMessage {
 
     private final transient HttpRequest httpRequest;
     private final transient HttpResponse httpResponse;
-    private final transient NettyHttpBinding httpBinding;
 
-    public NettyHttpMessage(HttpRequest httpRequest, HttpResponse httpResponse, NettyHttpBinding httpBinding) {
+    public NettyHttpMessage(HttpRequest httpRequest, HttpResponse httpResponse) {
         this.httpRequest = httpRequest;
         this.httpResponse = httpResponse;
-        this.httpBinding = httpBinding;
     }
 
     public HttpRequest getHttpRequest() {
@@ -50,20 +45,7 @@ public class NettyHttpMessage extends DefaultMessage {
     }
 
     @Override
-    protected void populateInitialHeaders(Map<String, Object> map) {
-        try {
-            if (httpRequest != null) {
-                httpBinding.populateCamelHeaders(httpRequest, map, getExchange());
-            } else {
-                httpBinding.populateCamelHeaders(httpResponse, map, getExchange());
-            }
-        } catch (Exception e) {
-            throw new RuntimeCamelException("Error populating initial headers", e);
-        }
-    }
-
-    @Override
     public DefaultMessage newInstance() {
-        return new NettyHttpMessage(httpRequest, httpResponse, httpBinding);
+        return new NettyHttpMessage(httpRequest, httpResponse);
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpOperationFailedException.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpOperationFailedException.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpOperationFailedException.java
new file mode 100644
index 0000000..cf8722a
--- /dev/null
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpOperationFailedException.java
@@ -0,0 +1,76 @@
+/**
+ * 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.CamelException;
+import org.apache.camel.util.ObjectHelper;
+import org.jboss.netty.handler.codec.http.HttpResponse;
+
+/**
+ * Exception when a Netty HTTP operation failed.
+ */
+public class NettyHttpOperationFailedException extends CamelException {
+    private static final long serialVersionUID = 1L;
+    private final String uri;
+    private final String redirectLocation;
+    private final int statusCode;
+    private final String statusText;
+    private final transient HttpResponse response;
+
+    public NettyHttpOperationFailedException(String uri, int statusCode, String statusText, String location, HttpResponse response) {
+        super("Netty HTTP operation failed invoking " + uri + " with statusCode: " + statusCode + (location != null ? ", redirectLocation: " + location : ""));
+        this.uri = uri;
+        this.statusCode = statusCode;
+        this.statusText = statusText;
+        this.redirectLocation = location;
+        this.response = response;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+
+    public boolean isRedirectError() {
+        return statusCode >= 300 && statusCode < 400;
+    }
+
+    public boolean hasRedirectLocation() {
+        return ObjectHelper.isNotEmpty(redirectLocation);
+    }
+
+    public String getRedirectLocation() {
+        return redirectLocation;
+    }
+
+    public int getStatusCode() {
+        return statusCode;
+    }
+
+    public String getStatusText() {
+        return statusText;
+    }
+
+    /**
+     * Gets the {@link HttpResponse}.
+     * <p/>
+     * Notice this may be <tt>null</tt> if this exception has been serialized,
+     * as the {@link HttpResponse} instance is marked as transient in this class.
+     */
+    public HttpResponse getResponse() {
+        return response;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java
index 7c52cf4..112c843 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java
@@ -16,17 +16,22 @@
  */
 package org.apache.camel.component.netty.http;
 
+import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.netty.NettyConfiguration;
 import org.apache.camel.component.netty.NettyProducer;
+import org.jboss.netty.handler.codec.http.HttpResponse;
 
 /**
  * HTTP based {@link NettyProducer}.
  */
 public class NettyHttpProducer extends NettyProducer {
 
-    public NettyHttpProducer(NettyHttpEndpoint nettyEndpoint, NettyConfiguration configuration) {
+    private final String uriParameters;
+
+    public NettyHttpProducer(NettyHttpEndpoint nettyEndpoint, NettyConfiguration configuration, String uriParameters) {
         super(nettyEndpoint, configuration);
+        this.uriParameters = uriParameters;
     }
 
     @Override
@@ -35,12 +40,66 @@ public class NettyHttpProducer extends NettyProducer {
     }
 
     @Override
+    public NettyHttpConfiguration getConfiguration() {
+        return (NettyHttpConfiguration) super.getConfiguration();
+    }
+
+    @Override
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        return super.process(exchange, new NettyHttpProducerCallback(exchange, callback));
+    }
+
+    @Override
     protected Object getRequestBody(Exchange exchange) throws Exception {
         String uri = getEndpoint().getEndpointUri();
+
+        if (uriParameters != null) {
+            uri += "?" + uriParameters;
+        }
+
         if (exchange.hasOut()) {
-            return getEndpoint().getNettyHttpBinding().toNettyRequest(exchange.getOut(), uri);
+            return getEndpoint().getNettyHttpBinding().toNettyRequest(exchange.getOut(), uri, getConfiguration());
         } else {
-            return getEndpoint().getNettyHttpBinding().toNettyRequest(exchange.getIn(), uri);
+            return getEndpoint().getNettyHttpBinding().toNettyRequest(exchange.getIn(), uri, getConfiguration());
         }
     }
+
+    /**
+     * Callback that ensures the channel is returned to the pool when we are done.
+     */
+    private final class NettyHttpProducerCallback implements AsyncCallback {
+
+        private final Exchange exchange;
+        private final AsyncCallback callback;
+
+        private NettyHttpProducerCallback(Exchange exchange, AsyncCallback callback) {
+            this.exchange = exchange;
+            this.callback = callback;
+        }
+
+        @Override
+        public void done(boolean doneSync) {
+            try {
+                NettyHttpMessage nettyMessage = exchange.hasOut() ? exchange.getOut(NettyHttpMessage.class) : exchange.getIn(NettyHttpMessage.class);
+                if (nettyMessage != null) {
+                    HttpResponse response = nettyMessage.getHttpResponse();
+                    if (response != null) {
+                        int code = response.getStatus() != null ? response.getStatus().getCode() : -1;
+                        log.debug("Http responseCode: {}", code);
+
+                        // if there was a http error code (300 or higher) then check if we should throw an exception
+                        if (code >= 300 && getConfiguration().isThrowExceptionOnFailure()) {
+                            // operation failed so populate exception to throw
+                            Exception cause = NettyHttpHelper.populateNettyHttpOperationFailedException(exchange, response, code, getConfiguration().isTransferException());
+                            exchange.setException(cause);
+                        }
+                    }
+                }
+            } finally {
+                // ensure we call the delegated callback
+                callback.done(doneSync);
+            }
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/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 0023ae6..e2cccf1 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
@@ -54,6 +54,6 @@ public class HttpClientChannelHandler extends ClientChannelHandler {
     @Override
     protected Message getResponseMessage(Exchange exchange, MessageEvent messageEvent) throws Exception {
         // use the binding
-        return producer.getEndpoint().getNettyHttpBinding().toCamelMessage(response, exchange);
+        return producer.getEndpoint().getNettyHttpBinding().toCamelMessage(response, exchange, producer.getConfiguration());
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/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 6ac0f25..e556cba 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
@@ -63,7 +63,8 @@ public class HttpServerChannelHandler extends ServerChannelHandler {
         request = (HttpRequest) messageEvent.getMessage();
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Message received: {} keep-alive: {}", request, isKeepAlive(request));
+            LOG.debug("Message received: {}", request);
+            LOG.debug("   is keep-alive: {}", isKeepAlive(request));
         }
 
         if (is100ContinueExpected(request)) {
@@ -102,7 +103,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler {
         if (consumer.isRunAllowed()) {
 
             if (exceptionEvent.getCause() instanceof ClosedChannelException) {
-                LOG.warn("Channel already closed. Ignoring this exception.");
+                LOG.debug("Channel already closed. Ignoring this exception.");
             } else {
                 LOG.warn("Closing channel as an exception was thrown from Netty", exceptionEvent.getCause());
                 // close channel in case an exception was thrown
@@ -115,9 +116,10 @@ public class HttpServerChannelHandler extends ServerChannelHandler {
     protected ChannelFutureListener createResponseFutureListener(NettyConsumer consumer, Exchange exchange, SocketAddress remoteAddress) {
         // make sure to close channel if not keep-alive
         if (request != null && isKeepAlive(request)) {
+            LOG.trace("Request has Connection: keep-alive so Channel is not being closed");
             return null;
         } else {
-            LOG.debug("Closing channel as not keep-alive");
+            LOG.trace("Request is not Connection: close so Channel is being closed");
             return ChannelFutureListener.CLOSE;
         }
     }
@@ -126,9 +128,9 @@ public class HttpServerChannelHandler extends ServerChannelHandler {
     protected Object getResponseBody(Exchange exchange) throws Exception {
         // use the binding
         if (exchange.hasOut()) {
-            return consumer.getEndpoint().getNettyHttpBinding().toNettyResponse(exchange.getOut());
+            return consumer.getEndpoint().getNettyHttpBinding().toNettyResponse(exchange.getOut(), consumer.getConfiguration());
         } else {
-            return consumer.getEndpoint().getNettyHttpBinding().toNettyResponse(exchange.getIn());
+            return consumer.getEndpoint().getNettyHttpBinding().toNettyResponse(exchange.getIn(), consumer.getConfiguration());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorTest.java
new file mode 100644
index 0000000..dc68494
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttp500ErrorTest extends BaseNettyTest {
+
+    @Test
+    public void testHttp500Error() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        try {
+            template.requestBody("netty-http:http://localhost:{{port}}/foo", "Hello World", String.class);
+            fail("Should have failed");
+        } catch (CamelExecutionException e) {
+            NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause());
+            assertEquals(500, cause.getStatusCode());
+            assertEquals("Camel cannot do this", context.getTypeConverter().convertTo(String.class, cause.getResponse().getContent()));
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testHttp500ErrorDisabled() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        String body = template.requestBody("netty-http:http://localhost:{{port}}/foo?throwExceptionOnFailure=false", "Hello World", String.class);
+        assertEquals("Camel cannot do this", body);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://0.0.0.0:{{port}}/foo")
+                    .to("mock:input")
+                    // trigger failure by setting error code to 500
+                    .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500))
+                    .setBody().constant("Camel cannot do this");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorThrowExceptionOnServerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorThrowExceptionOnServerTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorThrowExceptionOnServerTest.java
new file mode 100644
index 0000000..5b7206e
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttp500ErrorThrowExceptionOnServerTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.CamelExecutionException;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttp500ErrorThrowExceptionOnServerTest extends BaseNettyTest {
+
+    @Test
+    public void testHttp500Error() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        try {
+            template.requestBody("netty-http:http://localhost:{{port}}/foo", "Hello World", String.class);
+            fail("Should have failed");
+        } catch (CamelExecutionException e) {
+            NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause());
+            assertEquals(500, cause.getStatusCode());
+            String trace = context.getTypeConverter().convertTo(String.class, cause.getResponse().getContent());
+            assertNotNull(trace);
+            assertTrue(trace.startsWith("java.lang.IllegalArgumentException: Camel cannot do this"));
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testHttp500ErrorDisabled() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        String body = template.requestBody("netty-http:http://localhost:{{port}}/foo?throwExceptionOnFailure=false", "Hello World", String.class);
+        assertTrue(body.startsWith("java.lang.IllegalArgumentException: Camel cannot do this"));
+
+        assertMockEndpointsSatisfied();
+    }
+
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://0.0.0.0:{{port}}/foo")
+                    .to("mock:input")
+                    .throwException(new IllegalArgumentException("Camel cannot do this"));
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestAndResponseBeanTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestAndResponseBeanTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestAndResponseBeanTest.java
index 3b4dd28..f645c6d 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestAndResponseBeanTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestAndResponseBeanTest.java
@@ -34,10 +34,10 @@ public class NettyHttpAccessHttpRequestAndResponseBeanTest extends BaseNettyTest
     public void testRawHttpRequestAndResponseInBean() throws Exception {
         getMockEndpoint("mock:input").expectedBodiesReceived("World", "Camel");
 
-        String out = template.requestBody("http://localhost:{{port}}/foo", "World", String.class);
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo", "World", String.class);
         assertEquals("Bye World", out);
 
-        String out2 = template.requestBody("http://localhost:{{port}}/foo", "Camel", String.class);
+        String out2 = template.requestBody("netty-http:http://localhost:{{port}}/foo", "Camel", String.class);
         assertEquals("Bye Camel", out2);
 
         assertMockEndpointsSatisfied();

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestBeanTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestBeanTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestBeanTest.java
index 62ebbd5..68af929 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestBeanTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestBeanTest.java
@@ -28,7 +28,7 @@ public class NettyHttpAccessHttpRequestBeanTest extends BaseNettyTest {
     public void testAccessHttpRequest() throws Exception {
         getMockEndpoint("mock:input").expectedBodiesReceived("World");
 
-        String out = template.requestBody("http://localhost:{{port}}/foo", "World", String.class);
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo", "World", String.class);
         assertEquals("Bye World", out);
 
         assertMockEndpointsSatisfied();

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestTest.java
index 633f941..bac25a2 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpAccessHttpRequestTest.java
@@ -28,7 +28,7 @@ public class NettyHttpAccessHttpRequestTest extends BaseNettyTest {
     public void testAccessHttpRequest() throws Exception {
         getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
 
-        String out = template.requestBody("http://localhost:{{port}}/foo", "Hello World", String.class);
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo", "Hello World", String.class);
         assertEquals("Bye World", out);
 
         assertMockEndpointsSatisfied();

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/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
new file mode 100644
index 0000000..e49bfd3
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpBindingPreservePostFormUrlEncodedBodyTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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.junit.Test;
+
+public class NettyHttpBindingPreservePostFormUrlEncodedBodyTest extends BaseNettyTest {
+
+    @Test
+    public void testSendToNetty() throws Exception {
+        Exchange exchange = template.request("netty-http:http://localhost:{{port}}/myapp/myservice?query1=a&query2=b", 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"));
+
+                        // 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/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpCharacterEncodingTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpCharacterEncodingTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpCharacterEncodingTest.java
new file mode 100644
index 0000000..726ded3
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpCharacterEncodingTest.java
@@ -0,0 +1,63 @@
+/**
+ * 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.junit.Test;
+
+public class NettyHttpCharacterEncodingTest extends BaseNettyTest {
+
+    @Test
+    public void testSendToNetty() throws Exception {
+        Exchange exchange = template.request("netty-http:http://localhost:{{port}}/myapp/myservice", new Processor() {
+
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setBody("Hello World Thai Elephant \u0E08");
+                exchange.getIn().setHeader("Content-Type", "text/html; charset=utf-8");
+            }
+
+        });
+        // convert the response to a String
+        String body = exchange.getOut().getBody(String.class);
+        assertEquals("Response message is Thai Elephant \u0E08", 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 MyBookService());
+            }
+        };
+    }
+
+    public class MyBookService implements Processor {
+        public void process(Exchange exchange) throws Exception {
+            // just get the body as a string
+            String body = exchange.getIn().getBody(String.class);
+
+            // for unit testing make sure we got right message
+            assertEquals("Hello World Thai Elephant \u0E08", body);
+
+            // send a html response
+            exchange.getOut().setHeader("Content-Type", "text/html; charset=utf-8");
+            exchange.getOut().setBody("Response message is Thai Elephant \u0E08");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java
index 107354a..1330c8e 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java
@@ -31,7 +31,8 @@ public class NettyHttpContentTypeTest extends BaseNettyTest {
         getMockEndpoint("mock:input").expectedPropertyReceived(Exchange.CHARSET_NAME, "iso-8859-1");
 
         byte[] data = "Hello World".getBytes(Charset.forName("iso-8859-1"));
-        String out = template.requestBodyAndHeader("http://localhost:{{port}}/foo", data, "content-type", "text/plain; charset=\"iso-8859-1\"", String.class);
+        String out = template.requestBodyAndHeader("netty-http:http://localhost:{{port}}/foo", data,
+                "content-type", "text/plain; charset=\"iso-8859-1\"", String.class);
         assertEquals("Bye World", out);
 
         assertMockEndpointsSatisfied();

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpConvertPayloadToInputStreamTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpConvertPayloadToInputStreamTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpConvertPayloadToInputStreamTest.java
new file mode 100644
index 0000000..ab35f34
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpConvertPayloadToInputStreamTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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 java.io.InputStream;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Test;
+
+public class NettyHttpConvertPayloadToInputStreamTest extends BaseNettyTest {
+
+    protected String expectedBody = "<hello>world!</hello>";
+
+    @Test
+    public void testConvertPayloadToInputStream() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.expectedMessageCount(1);
+
+        template.requestBodyAndHeader("netty-http:http://localhost:{{port}}/test", expectedBody, "Content-Type", "application/xml");
+
+        mockEndpoint.assertIsSatisfied();
+        List<Exchange> list = mockEndpoint.getReceivedExchanges();
+        Exchange exchange = list.get(0);
+        assertNotNull("exchange", exchange);
+
+        Message in = exchange.getIn();
+        assertNotNull("in", in);
+
+        Object actual = in.getBody();
+        InputStream value = assertIsInstanceOf(InputStream.class, actual);
+        assertNotNull("InputStream", value);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                from("netty-http:http://localhost:{{port}}/test").
+                        convertBodyTo(InputStream.class).
+                        to("mock:result");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueTest.java
new file mode 100644
index 0000000..50f9248
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueTest.java
@@ -0,0 +1,67 @@
+/**
+ * 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.junit.Ignore;
+import org.junit.Test;
+
+public class NettyHttpEndpointUriEncodingIssueTest extends BaseNettyTest {
+
+    @Test
+    public void testEndpointUriEncodingIssue() throws Exception {
+        String uri = "netty-http:http://localhost:{{port}}/myapp/mytest?columns=totalsens,upsens&username=apiuser";
+        String out = template.requestBody(uri, null, String.class);
+
+        assertEquals("We got totalsens,upsens columns", out);
+    }
+
+    @Test
+    public void testEndpointUriWithDanishCharEncodingIssue() throws Exception {
+        String uri = "netty-http:http://localhost:{{port}}/myapp/mytest?columns=claus,s\u00F8ren&username=apiuser";
+        String out = template.requestBody(uri, null, String.class);
+
+        assertEquals("We got claus,s\u00F8ren columns", out);
+    }
+
+    @Test
+    @Ignore("Implement the HTTP_URI override")
+    public void testEndpointHeaderUriEncodingIssue() throws Exception {
+        String uri = "netty-http:http://localhost:{{port}}/myapp/mytest?columns=totalsens,upsens&username=apiuser";
+        String out = template.requestBodyAndHeader("netty-http:http://localhost/dummy", null, Exchange.HTTP_URI, uri, String.class);
+
+        assertEquals("We got totalsens,upsens columns", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/myapp/mytest").process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        String columns = exchange.getIn().getHeader("columns", String.class);
+                        exchange.getOut().setBody("We got " + columns + " columns");
+                    }
+                });
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueUrlDecodeDisabledTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueUrlDecodeDisabledTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueUrlDecodeDisabledTest.java
new file mode 100644
index 0000000..9cf7f75
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointUriEncodingIssueUrlDecodeDisabledTest.java
@@ -0,0 +1,50 @@
+/**
+ * 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.junit.Ignore;
+import org.junit.Test;
+
+public class NettyHttpEndpointUriEncodingIssueUrlDecodeDisabledTest extends BaseNettyTest {
+
+    @Test
+    public void testEndpointUriWithDanishCharEncodingIssue() throws Exception {
+        String uri = "netty-http:http://localhost:{{port}}/myapp/mytest?columns=claus,s\u00F8ren&username=apiuser";
+        String out = template.requestBody(uri, null, String.class);
+
+        assertEquals("We got claus%2Cs%C3%B8ren columns", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/myapp/mytest?urlDecodeHeaders=false").process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        String columns = exchange.getIn().getHeader("columns", String.class);
+                        exchange.getOut().setBody("We got " + columns + " columns");
+                    }
+                });
+            }
+        };
+    }
+
+}


[3/5] CAMEL-6327: More work on new camel-netty-http component.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpFilterCamelHeadersTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpFilterCamelHeadersTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpFilterCamelHeadersTest.java
new file mode 100644
index 0000000..47f0dd5
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpFilterCamelHeadersTest.java
@@ -0,0 +1,76 @@
+/**
+ * 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 java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+import org.junit.Test;
+
+public class NettyHttpFilterCamelHeadersTest extends BaseNettyTest {
+
+    @Test
+    public void testFilterCamelHeaders() throws Exception {
+        Exchange out = template.request("netty-http:http://localhost:{{port}}/test/filter", new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setBody("Claus");
+                exchange.getIn().setHeader("bar", 123);
+            }
+        });
+
+        assertNotNull(out);
+        assertEquals("Hi Claus", out.getOut().getBody(String.class));
+
+        // there should be no internal Camel headers
+        // except for the response code and response text
+        Map<String, Object> headers = out.getOut().getHeaders();
+        for (String key : headers.keySet()) {
+            if (!key.equalsIgnoreCase(Exchange.HTTP_RESPONSE_CODE) && !key.equalsIgnoreCase(NettyHttpConstants.HTTP_RESPONSE_TEXT)) {
+                assertTrue("Should not contain any Camel internal headers", !key.toLowerCase().startsWith("camel"));
+            }
+        }
+        assertEquals(200, headers.get(Exchange.HTTP_RESPONSE_CODE));
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+        jndi.bind("foo", new MyFooBean());
+        return jndi;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/test/filter").beanRef("foo");
+            }
+        };
+    }
+
+    public static class MyFooBean {
+
+        public String hello(String name) {
+            return "Hi " + name;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHeaderCaseTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHeaderCaseTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHeaderCaseTest.java
new file mode 100644
index 0000000..2b89be2
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHeaderCaseTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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 java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.junit.Test;
+
+public class NettyHttpHeaderCaseTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpHeaderCase() throws Exception {
+        HttpClient client = new HttpClient();
+        HttpMethod method = new PostMethod("http://localhost:" + getPort() + "/myapp/mytest");
+
+        method.setRequestHeader("clientHeader", "fooBAR");
+        method.setRequestHeader("OTHER", "123");
+        method.setRequestHeader("beer", "Carlsberg");
+
+        client.executeMethod(method);
+
+        assertEquals("Bye World", method.getResponseBodyAsString());
+        assertEquals("aBc123", method.getResponseHeader("MyCaseHeader").getValue());
+        assertEquals("456DEf", method.getResponseHeader("otherCaseHeader").getValue());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/myapp/mytest").process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+
+                        // headers received should be in case as well
+                        Map<String, Object> map = new LinkedHashMap<String, Object>();
+                        map.putAll(exchange.getIn().getHeaders());
+
+                        assertEquals("123", map.get("OTHER"));
+                        assertEquals(null, map.get("other"));
+                        assertEquals("Carlsberg", map.get("beer"));
+                        assertEquals(null, map.get("Beer"));
+
+                        exchange.getOut().setBody("Bye World");
+                        exchange.getOut().setHeader("MyCaseHeader", "aBc123");
+                        exchange.getOut().setHeader("otherCaseHeader", "456DEf");
+                    }
+                });
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpMapHeadersFalseTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpMapHeadersFalseTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpMapHeadersFalseTest.java
new file mode 100644
index 0000000..28498e9
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpMapHeadersFalseTest.java
@@ -0,0 +1,70 @@
+/**
+ * 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.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.junit.Test;
+
+public class NettyHttpMapHeadersFalseTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpHeaderCase() throws Exception {
+        HttpClient client = new HttpClient();
+        HttpMethod method = new PostMethod("http://localhost:" + getPort() + "/myapp/mytest");
+
+        method.setRequestHeader("clientHeader", "fooBAR");
+        method.setRequestHeader("OTHER", "123");
+        method.setRequestHeader("beer", "Carlsberg");
+
+        client.executeMethod(method);
+
+        assertEquals("Bye World", method.getResponseBodyAsString());
+        assertEquals("aBc123", method.getResponseHeader("MyCaseHeader").getValue());
+        assertEquals("456DEf", method.getResponseHeader("otherCaseHeader").getValue());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/myapp/mytest?mapHeaders=false").process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        // these headers is not mapped
+                        assertNull(exchange.getIn().getHeader("clientHeader"));
+                        assertNull(exchange.getIn().getHeader("OTHER"));
+                        assertNull(exchange.getIn().getHeader("beer"));
+
+                        // but we can find them in the http request from netty
+                        assertEquals("fooBAR", exchange.getIn(NettyHttpMessage.class).getHttpRequest().getHeader("clientHeader"));
+                        assertEquals("123", exchange.getIn(NettyHttpMessage.class).getHttpRequest().getHeader("OTHER"));
+                        assertEquals("Carlsberg", exchange.getIn(NettyHttpMessage.class).getHttpRequest().getHeader("beer"));
+
+                        exchange.getOut().setBody("Bye World");
+                        exchange.getOut().setHeader("MyCaseHeader", "aBc123");
+                        exchange.getOut().setHeader("otherCaseHeader", "456DEf");
+                    }
+                });
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerConcurrentTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerConcurrentTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerConcurrentTest.java
new file mode 100644
index 0000000..7f54ddf
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerConcurrentTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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 java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpProducerConcurrentTest extends BaseNettyTest {
+
+    @Test
+    public void testNoConcurrentProducers() throws Exception {
+        doSendMessages(1, 1);
+    }
+
+    @Test
+    public void testConcurrentProducers() throws Exception {
+        doSendMessages(10, 5);
+    }
+
+    private void doSendMessages(int files, int poolSize) throws Exception {
+        getMockEndpoint("mock:result").expectedMessageCount(files);
+        getMockEndpoint("mock:result").assertNoDuplicates(body());
+
+        ExecutorService executor = Executors.newFixedThreadPool(poolSize);
+        Map<Integer, Future<String>> responses = new ConcurrentHashMap<Integer, Future<String>>();
+        for (int i = 0; i < files; i++) {
+            final int index = i;
+            Future<String> out = executor.submit(new Callable<String>() {
+                public String call() throws Exception {
+                    return template.requestBody("netty-http:http://localhost:{{port}}/echo", "" + index, String.class);
+                }
+            });
+            responses.put(index, out);
+        }
+
+        assertMockEndpointsSatisfied();
+
+        assertEquals(files, responses.size());
+
+        // get all responses
+        Set<Object> unique = new HashSet<Object>();
+        for (Future<String> future : responses.values()) {
+            unique.add(future.get());
+        }
+
+        // should be 'files' unique responses
+        assertEquals("Should be " + files + " unique responses", files, unique.size());
+        executor.shutdownNow();
+    }
+
+
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                // expose a echo service
+                from("netty-http:http://localhost:{{port}}/echo")
+                        .transform(body().append(body())).to("mock:result");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerKeepAliveTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerKeepAliveTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerKeepAliveTest.java
new file mode 100644
index 0000000..ad018f0
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerKeepAliveTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpProducerKeepAliveTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpKeepAlive() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World", "Hello Again");
+
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo?keepAlive=true", "Hello World", String.class);
+        assertEquals("Bye World", out);
+
+        out = template.requestBody("netty-http:http://localhost:{{port}}/foo?keepAlive=true", "Hello Again", String.class);
+        assertEquals("Bye World", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testHttpKeepAliveFalse() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World", "Hello Again");
+
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo?keepAlive=false", "Hello World", String.class);
+        assertEquals("Bye World", out);
+
+        out = template.requestBody("netty-http:http://localhost:{{port}}/foo?keepAlive=false", "Hello Again", String.class);
+        assertEquals("Bye World", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://0.0.0.0:{{port}}/foo")
+                    .to("mock:input")
+                    .transform().constant("Bye World");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSendEmptyHeaderTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSendEmptyHeaderTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSendEmptyHeaderTest.java
new file mode 100644
index 0000000..7212c82
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSendEmptyHeaderTest.java
@@ -0,0 +1,48 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Test;
+
+public class NettyHttpProducerSendEmptyHeaderTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpProducerSendEmptyHeader() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.expectedHeaderReceived("foo", "");
+
+        template.sendBodyAndHeader("netty-http:http://localhost:{{port}}/myapp/mytest", "Hello World", "foo", "");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/myapp/mytest")
+                        .convertBodyTo(String.class)
+                        .to("mock:result");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleGetTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleGetTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleGetTest.java
new file mode 100644
index 0000000..c5e7430
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleGetTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpProducerSimpleGetTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpSimple() throws Exception {
+        getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_METHOD, "GET");
+
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo", null, String.class);
+        assertEquals("Bye World", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testHttpSimpleHeader() throws Exception {
+        getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_METHOD, "GET");
+
+        String out = template.requestBodyAndHeader("netty-http:http://localhost:{{port}}/foo", null, Exchange.HTTP_METHOD, "GET", String.class);
+        assertEquals("Bye World", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testHttpSimpleHeaderAndBody() throws Exception {
+        // even if we have a body we force it to be GET
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_METHOD, "GET");
+
+        String out = template.requestBodyAndHeader("netty-http:http://localhost:{{port}}/foo", "Hello World", Exchange.HTTP_METHOD, "GET", String.class);
+        assertEquals("Bye World", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://0.0.0.0:{{port}}/foo")
+                    .to("mock:input")
+                    .transform().constant("Bye World");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerTwoParametersWithSameKeyTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerTwoParametersWithSameKeyTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerTwoParametersWithSameKeyTest.java
new file mode 100644
index 0000000..6b8917e
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerTwoParametersWithSameKeyTest.java
@@ -0,0 +1,100 @@
+/**
+ * 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 java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpProducerTwoParametersWithSameKeyTest extends BaseNettyTest {
+
+    @Test
+    public void testTwoParametersWithSameKey() throws Exception {
+        Exchange out = template.request("netty-http:http://localhost:{{port}}/myapp?from=me&to=foo&to=bar", null);
+
+        assertNotNull(out);
+        assertFalse("Should not fail", out.isFailed());
+        assertEquals("OK", out.getOut().getBody(String.class));
+        assertEquals("yes", out.getOut().getHeader("bar"));
+
+        List<?> foo = out.getOut().getHeader("foo", List.class);
+        assertNotNull(foo);
+        assertEquals(2, foo.size());
+        assertEquals("123", foo.get(0));
+        assertEquals("456", foo.get(1));
+    }
+
+    @Test
+    public void testTwoHeadersWithSameKeyHeader() throws Exception {
+        Exchange out = template.request("netty-http:http://localhost:{{port}}/myapp", new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setBody(null);
+                exchange.getIn().setHeader("from", "me");
+                List<String> list = new ArrayList<String>();
+                list.add("foo");
+                list.add("bar");
+                exchange.getIn().setHeader("to", list);
+            }
+        });
+
+        assertNotNull(out);
+        assertFalse("Should not fail", out.isFailed());
+        assertEquals("OK", out.getOut().getBody(String.class));
+        assertEquals("yes", out.getOut().getHeader("bar"));
+
+        List<?> foo = out.getOut().getHeader("foo", List.class);
+        assertNotNull(foo);
+        assertEquals(2, foo.size());
+        assertEquals("123", foo.get(0));
+        assertEquals("456", foo.get(1));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/myapp").process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        String from = exchange.getIn().getHeader("from", String.class);
+                        assertEquals("me", from);
+
+                        List<?> to = exchange.getIn().getHeader("to", List.class);
+                        assertNotNull(to);
+                        assertEquals(2, to.size());
+                        assertEquals("foo", to.get(0));
+                        assertEquals("bar", to.get(1));
+
+                        // response
+                        exchange.getOut().setBody("OK");
+                        // use multiple values for the foo header in the reply
+                        List<Integer> list = new ArrayList<Integer>();
+                        list.add(123);
+                        list.add(456);
+                        exchange.getOut().setHeader("foo", list);
+                        exchange.getOut().setHeader("bar", "yes");
+                    }
+                });
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/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
new file mode 100644
index 0000000..0005673
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectNoLocationTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpRedirectNoLocationTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpRedirectNoLocation() throws Exception {
+        try {
+            template.requestBody("netty-http:http://localhost:{{port}}/test", "Hello World", String.class);
+            fail("Should have thrown an exception");
+        } catch (RuntimeCamelException e) {
+            NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause());
+            assertEquals(302, cause.getStatusCode());
+            assertEquals(true, cause.isRedirectError());
+            assertEquals(false, cause.hasRedirectLocation());
+            assertEquals(null, cause.getRedirectLocation());
+        }
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/test")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, 302);
+                            }
+                        });
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectTest.java
new file mode 100644
index 0000000..631ed3d
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpRedirectTest.java
@@ -0,0 +1,56 @@
+/**
+ * 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.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpRedirectTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpRedirect() throws Exception {
+        try {
+            template.requestBody("netty-http:http://localhost:{{port}}/test", "Hello World", String.class);
+            fail("Should have thrown an exception");
+        } catch (RuntimeCamelException e) {
+            NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause());
+            assertEquals(301, cause.getStatusCode());
+            assertEquals(true, cause.isRedirectError());
+            assertEquals(true, cause.hasRedirectLocation());
+            assertEquals("http://localhost:" + getPort() + "/newtest", cause.getRedirectLocation());
+        }
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/test")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, 301);
+                                exchange.getOut().setHeader("location", "http://localhost:" + getPort() + "/newtest");
+                            }
+                        });
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnDataNotInputStreamConvertableTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnDataNotInputStreamConvertableTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnDataNotInputStreamConvertableTest.java
new file mode 100644
index 0000000..c43a164
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnDataNotInputStreamConvertableTest.java
@@ -0,0 +1,53 @@
+/**
+ * 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.junit.Test;
+
+public class NettyHttpReturnDataNotInputStreamConvertableTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpReturnDataNotInputStreamConvertableTest() throws Exception {
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/test", "Hello World", String.class);
+        assertEquals("This is the response", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/test")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                exchange.getOut().setBody(new MyResponseBean());
+                            }
+                        });
+            }
+        };
+    }
+
+    private static class MyResponseBean {
+        @Override
+        public String toString() {
+            return "This is the response";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
new file mode 100644
index 0000000..3943297
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpReturnFaultTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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.junit.Ignore;
+import org.junit.Test;
+
+public class NettyHttpReturnFaultTest extends BaseNettyTest {
+
+    @Test
+    @Ignore
+    public void testHttpFault() throws Exception {
+        Exchange exchange = template.request("netty-http:http://localhost:{{port}}/test", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setBody("Hello World!");
+            }
+
+        });
+        assertTrue(exchange.isFailed());
+        NettyHttpOperationFailedException exception = exchange.getException(NettyHttpOperationFailedException.class);
+        assertNotNull(exception);
+        assertEquals(500, exception.getStatusCode());
+        String message = context.getTypeConverter().convertTo(String.class, exception.getResponse().getContent());
+        assertEquals("This is a fault", message);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://localhost:{{port}}/test")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                exchange.getOut().setFault(true);
+                                exchange.getOut().setBody("This is a fault");
+                            }
+                        });
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleTest.java
index ee4f099..188f12d 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleTest.java
@@ -25,7 +25,7 @@ public class NettyHttpSimpleTest extends BaseNettyTest {
     public void testHttpSimple() throws Exception {
         getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
 
-        String out = template.requestBody("http://localhost:{{port}}/foo", "Hello World", String.class);
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo", "Hello World", String.class);
         assertEquals("Bye World", out);
 
         assertMockEndpointsSatisfied();

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleUriParametersTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleUriParametersTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleUriParametersTest.java
new file mode 100644
index 0000000..2710f71
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpSimpleUriParametersTest.java
@@ -0,0 +1,46 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpSimpleUriParametersTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpSimple() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo?name=bar", "Hello World", String.class);
+        assertEquals("Bye bar", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://0.0.0.0:{{port}}/foo")
+                    .to("mock:input")
+                    .transform().simple("Bye ${header.name}");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTransferExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTransferExceptionTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTransferExceptionTest.java
new file mode 100644
index 0000000..b25ed09
--- /dev/null
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTransferExceptionTest.java
@@ -0,0 +1,52 @@
+/**
+ * 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.CamelExecutionException;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class NettyHttpTransferExceptionTest extends BaseNettyTest {
+
+    @Test
+    public void testHttpTransferException() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        try {
+            template.requestBody("netty-http:http://localhost:{{port}}/foo?transferException=true", "Hello World", String.class);
+            fail("Should have failed");
+        } catch (CamelExecutionException e) {
+            IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+            assertEquals("Camel cannot do this", cause.getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("netty-http:http://0.0.0.0:{{port}}/foo?transferException=true")
+                    .to("mock:input")
+                    .throwException(new IllegalArgumentException("Camel cannot do this"));
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b67f5f90/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyUseRawHttpResponseTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyUseRawHttpResponseTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyUseRawHttpResponseTest.java
index 12215d7..de6b6ad 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyUseRawHttpResponseTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyUseRawHttpResponseTest.java
@@ -33,7 +33,7 @@ public class NettyUseRawHttpResponseTest extends BaseNettyTest {
     public void testAccessHttpRequest() throws Exception {
         getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
 
-        String out = template.requestBody("http://localhost:{{port}}/foo", "Hello World", String.class);
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/foo", "Hello World", String.class);
         assertEquals("Bye World", out);
 
         assertMockEndpointsSatisfied();


[5/5] git commit: Polished tests

Posted by da...@apache.org.
Polished tests


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a8c85b58
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a8c85b58
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a8c85b58

Branch: refs/heads/master
Commit: a8c85b58d4f4ddc494f8b23df2d40a4bb3793235
Parents: 39cc150
Author: Claus Ibsen <da...@apache.org>
Authored: Wed May 8 11:03:09 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed May 8 11:31:50 2013 +0200

----------------------------------------------------------------------
 ...pBindingPreservePostFormUrlEncodedBodyTest.java |    2 +-
 .../component/jetty/HttpMethodRestrictTest.java    |    4 ----
 2 files changed, 1 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a8c85b58/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java
index 067f383..6fa6df0 100644
--- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java
+++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java
@@ -26,7 +26,7 @@ public class HttpBindingPreservePostFormUrlEncodedBodyTest extends BaseJettyTest
     
     @Test
     public void testSendToJetty() throws Exception {
-        Exchange exchange = template.send("http://localhost:{{port}}/myapp/myservice?query1=a&query2=b", new Processor() {
+        Exchange exchange = template.request("http://localhost:{{port}}/myapp/myservice?query1=a&query2=b", new Processor() {
 
             public void process(Exchange exchange) throws Exception {
                 exchange.getIn().setBody("b1=x&b2=y");

http://git-wip-us.apache.org/repos/asf/camel/blob/a8c85b58/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpMethodRestrictTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpMethodRestrictTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpMethodRestrictTest.java
index 0772bed..8ff3990 100644
--- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpMethodRestrictTest.java
+++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpMethodRestrictTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.camel.component.jetty;
 
-
-
-
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
@@ -29,7 +26,6 @@ import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.StringRequestEntity;
 import org.junit.Test;
 
-
 public class HttpMethodRestrictTest extends BaseJettyTest {
 
     private String getUrl() {


[2/5] git commit: Fixed potential NPE

Posted by da...@apache.org.
Fixed potential NPE


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/27087f0a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/27087f0a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/27087f0a

Branch: refs/heads/master
Commit: 27087f0aa1a682685e2ceaa6bd6d62f9e2841cf8
Parents: a8c85b5
Author: Claus Ibsen <da...@apache.org>
Authored: Wed May 8 11:04:33 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed May 8 11:31:50 2013 +0200

----------------------------------------------------------------------
 .../camel/component/netty/NettyConfiguration.java  |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/27087f0a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
index a703092..33a092a 100644
--- a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
+++ b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
@@ -142,7 +142,7 @@ public class NettyConfiguration implements Cloneable {
 
         boolean found = false;
         for (String supportedProtocol : supportedProtocols) {
-            if (protocol.equalsIgnoreCase(supportedProtocol)) {
+            if (protocol != null && protocol.equalsIgnoreCase(supportedProtocol)) {
                 found = true;
                 break;
             }