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 2015/07/23 14:58:04 UTC

[02/24] camel git commit: camel-http-common - as a common module

camel-http-common - as a common module


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

Branch: refs/heads/master
Commit: e51b7f8d9320072a64f60a23836c7ce15ffb45e7
Parents: 600063a
Author: Claus Ibsen <da...@apache.org>
Authored: Thu Jul 23 09:23:46 2015 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Jul 23 15:04:30 2015 +0200

----------------------------------------------------------------------
 .../camel/http/common/CamelFileDataSource.java  |  52 ++
 .../apache/camel/http/common/CamelServlet.java  | 247 ++++++++++
 .../camel/http/common/DefaultHttpBinding.java   | 494 +++++++++++++++++++
 .../apache/camel/http/common/HttpBinding.java   | 160 ++++++
 .../camel/http/common/HttpCommonComponent.java  |  75 +++
 .../camel/http/common/HttpCommonEndpoint.java   | 383 ++++++++++++++
 .../camel/http/common/HttpConfiguration.java    | 143 ++++++
 .../apache/camel/http/common/HttpConstants.java |  26 +
 .../apache/camel/http/common/HttpConsumer.java  |  80 +++
 .../apache/camel/http/common/HttpConverter.java |  98 ++++
 .../http/common/HttpHeaderFilterStrategy.java   |  49 ++
 .../apache/camel/http/common/HttpHelper.java    | 429 ++++++++++++++++
 .../apache/camel/http/common/HttpMessage.java   |  81 +++
 .../common/HttpOperationFailedException.java    |  75 +++
 .../HttpProtocolHeaderFilterStrategy.java       |  87 ++++
 .../HttpServletResolveConsumerStrategy.java     |  50 ++
 .../http/common/HttpServletUrlRewrite.java      |  45 ++
 .../common/ServletResolveConsumerStrategy.java  |  37 ++
 .../apache/camel/http/common/UrlRewrite.java    |  41 ++
 .../UrlRewriteHttpServletRequestAdapter.java    |  49 ++
 20 files changed, 2701 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelFileDataSource.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelFileDataSource.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelFileDataSource.java
new file mode 100644
index 0000000..8cb4c91
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelFileDataSource.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.http.common;
+
+import java.io.File;
+import javax.activation.FileDataSource;
+import javax.activation.FileTypeMap;
+
+public class CamelFileDataSource extends FileDataSource {
+    private final String fileName;
+    private FileTypeMap typeMap;
+
+    public CamelFileDataSource(File file, String fileName) {
+        super(file);
+        this.fileName = fileName;
+    }
+    
+    public String getContentType() {
+        if (typeMap == null) {
+            return FileTypeMap.getDefaultFileTypeMap().getContentType(fileName);
+        } else {
+            return typeMap.getContentType(fileName);
+        }
+    }
+    
+    public void setFileTypeMap(FileTypeMap map) {
+        typeMap = map;
+    }
+    
+    public String getName() {
+        if (fileName != null) {
+            return fileName;
+        } else {
+            return super.getName();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
new file mode 100644
index 0000000..061bf47
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
@@ -0,0 +1,247 @@
+/**
+ * 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.http.common;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.impl.DefaultExchange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A servlet to use as a Camel route as entry.
+ */
+public class CamelServlet extends HttpServlet {
+    private static final long serialVersionUID = -7061982839117697829L;
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+    
+    /**
+     *  We have to define this explicitly so the name can be set as we can not always be
+     *  sure that it is already set via the init method
+     */
+    private String servletName;
+
+    private ServletResolveConsumerStrategy servletResolveConsumerStrategy = new HttpServletResolveConsumerStrategy();
+    private final ConcurrentMap<String, HttpConsumer> consumers = new ConcurrentHashMap<String, HttpConsumer>();
+   
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        this.servletName = config.getServletName();
+    }
+
+    @Override
+    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        log.trace("Service: {}", request);
+
+        // Is there a consumer registered for the request.
+        HttpConsumer consumer = resolve(request);
+        if (consumer == null) {
+            log.debug("No consumer to service request {}", request);
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }       
+        
+        // are we suspended?
+        if (consumer.isSuspended()) {
+            log.debug("Consumer suspended, cannot service request {}", request);
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+            return;
+        }
+
+        // if its an OPTIONS request then return which method is allowed
+        if ("OPTIONS".equals(request.getMethod())) {
+            String s;
+            if (consumer.getEndpoint().getHttpMethodRestrict() != null) {
+                s = "OPTIONS," + consumer.getEndpoint().getHttpMethodRestrict();
+            } else {
+                // allow them all
+                s = "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,CONNECT,PATCH";
+            }
+            response.addHeader("Allow", s);
+            response.setStatus(HttpServletResponse.SC_OK);
+            return;
+        }
+        
+        if (consumer.getEndpoint().getHttpMethodRestrict() != null 
+            && !consumer.getEndpoint().getHttpMethodRestrict().contains(request.getMethod())) {
+            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            return;
+        }
+
+        if ("TRACE".equals(request.getMethod()) && !consumer.isTraceEnabled()) {
+            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            return;
+        }
+        
+        // create exchange and set data on it
+        Exchange exchange = new DefaultExchange(consumer.getEndpoint(), ExchangePattern.InOut);
+
+        if (consumer.getEndpoint().isBridgeEndpoint()) {
+            exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
+            exchange.setProperty(Exchange.SKIP_WWW_FORM_URLENCODED, Boolean.TRUE);
+        }
+        if (consumer.getEndpoint().isDisableStreamCache()) {
+            exchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, Boolean.TRUE);
+        }
+
+        // we override the classloader before building the HttpMessage just in case the binding
+        // does some class resolution
+        ClassLoader oldTccl = overrideTccl(exchange);
+        HttpHelper.setCharsetFromContentType(request.getContentType(), exchange);
+        exchange.setIn(new HttpMessage(exchange, request, response));
+        // set context path as header
+        String contextPath = consumer.getEndpoint().getPath();
+        exchange.getIn().setHeader("CamelServletContextPath", contextPath);
+
+        String httpPath = (String)exchange.getIn().getHeader(Exchange.HTTP_PATH);
+        // here we just remove the CamelServletContextPath part from the HTTP_PATH
+        if (contextPath != null
+            && httpPath.startsWith(contextPath)) {
+            exchange.getIn().setHeader(Exchange.HTTP_PATH,
+                    httpPath.substring(contextPath.length()));
+        }
+
+        // we want to handle the UoW
+        try {
+            consumer.createUoW(exchange);
+        } catch (Exception e) {
+            log.error("Error processing request", e);
+            throw new ServletException(e);
+        }
+
+        try {
+            if (log.isTraceEnabled()) {
+                log.trace("Processing request for exchangeId: {}", exchange.getExchangeId());
+            }
+            // process the exchange
+            consumer.getProcessor().process(exchange);
+        } catch (Exception e) {
+            exchange.setException(e);
+        }
+
+        try {
+            // now lets output to the response
+            if (log.isTraceEnabled()) {
+                log.trace("Writing response for exchangeId: {}", exchange.getExchangeId());
+            }
+            Integer bs = consumer.getEndpoint().getResponseBufferSize();
+            if (bs != null) {
+                log.trace("Using response buffer size: {}", bs);
+                response.setBufferSize(bs);
+            }
+            consumer.getBinding().writeResponse(exchange, response);
+        } catch (IOException e) {
+            log.error("Error processing request", e);
+            throw e;
+        } catch (Exception e) {
+            log.error("Error processing request", e);
+            throw new ServletException(e);
+        } finally {
+            consumer.doneUoW(exchange);
+            restoreTccl(exchange, oldTccl);
+        }
+    }
+
+    /**
+     * @deprecated use {@link ServletResolveConsumerStrategy#resolve(javax.servlet.http.HttpServletRequest, java.util.Map)}
+     */
+    @Deprecated
+    protected HttpConsumer resolve(HttpServletRequest request) {
+        return getServletResolveConsumerStrategy().resolve(request, getConsumers());
+    }
+
+    public void connect(HttpConsumer consumer) {
+        log.debug("Connecting consumer: {}", consumer);
+        consumers.put(consumer.getEndpoint().getEndpointUri(), consumer);
+    }
+
+    public void disconnect(HttpConsumer consumer) {
+        log.debug("Disconnecting consumer: {}", consumer);
+        consumers.remove(consumer.getEndpoint().getEndpointUri());
+    }
+
+    public String getServletName() {
+        return servletName;
+    }
+
+    public void setServletName(String servletName) {
+        this.servletName = servletName;
+    }
+
+    public ServletResolveConsumerStrategy getServletResolveConsumerStrategy() {
+        return servletResolveConsumerStrategy;
+    }
+
+    public void setServletResolveConsumerStrategy(ServletResolveConsumerStrategy servletResolveConsumerStrategy) {
+        this.servletResolveConsumerStrategy = servletResolveConsumerStrategy;
+    }
+
+    public Map<String, HttpConsumer> getConsumers() {
+        return Collections.unmodifiableMap(consumers);
+    }
+
+    /**
+     * Override the Thread Context ClassLoader if need be.
+     *
+     * @param exchange
+     * @return old classloader if overridden; otherwise returns null
+     */
+    protected ClassLoader overrideTccl(final Exchange exchange) {
+        ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+        ClassLoader appCtxCl = exchange.getContext().getApplicationContextClassLoader();
+        if (oldClassLoader == null || appCtxCl == null) {
+            return null;
+        }
+        
+        if (!oldClassLoader.equals(appCtxCl)) {
+            Thread.currentThread().setContextClassLoader(appCtxCl);
+            if (log.isTraceEnabled()) {
+                log.trace("Overrode TCCL for exchangeId {} to {} on thread {}", 
+                        new Object[] {exchange.getExchangeId(), appCtxCl, Thread.currentThread().getName()});
+            }
+            return oldClassLoader;
+        }
+        return null;
+    }
+
+    /**
+     * Restore the Thread Context ClassLoader if the old TCCL is not null.
+     */
+    protected void restoreTccl(final Exchange exchange, ClassLoader oldTccl) {
+        if (oldTccl == null) {
+            return;
+        }
+        Thread.currentThread().setContextClassLoader(oldTccl);
+        if (log.isTraceEnabled()) {
+            log.trace("Restored TCCL for exchangeId {} to {} on thread {}", 
+                    new String[] {exchange.getExchangeId(), oldTccl.toString(), Thread.currentThread().getName()});
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
new file mode 100644
index 0000000..dcb3f20
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
@@ -0,0 +1,494 @@
+/**
+ * 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.http.common;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import javax.activation.DataHandler;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.Message;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.StreamCache;
+import org.apache.camel.converter.stream.CachedOutputStream;
+import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.util.GZIPHelper;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.MessageHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Binding between {@link HttpMessage} and {@link HttpServletResponse}.
+ * <p/>
+ * Uses by default the {@link org.apache.camel.http.common.HttpHeaderFilterStrategy}
+ */
+public class DefaultHttpBinding implements HttpBinding {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultHttpBinding.class);
+    private boolean useReaderForPayload;
+    private boolean eagerCheckContentAvailable;
+    private boolean transferException;
+    private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
+
+    public DefaultHttpBinding() {
+    }
+
+    @Deprecated
+    public DefaultHttpBinding(HeaderFilterStrategy headerFilterStrategy) {
+        this.headerFilterStrategy = headerFilterStrategy;
+    }
+
+    @Deprecated
+    public DefaultHttpBinding(HttpCommonEndpoint endpoint) {
+        this.headerFilterStrategy = endpoint.getHeaderFilterStrategy();
+        this.transferException = endpoint.isTransferException();
+    }
+
+    public void readRequest(HttpServletRequest request, HttpMessage message) {
+        LOG.trace("readRequest {}", request);
+        
+        // lets force a parse of the body and headers
+        message.getBody();
+        // populate the headers from the request
+        Map<String, Object> headers = message.getHeaders();
+        
+        //apply the headerFilterStrategy
+        Enumeration<?> names = request.getHeaderNames();
+        while (names.hasMoreElements()) {
+            String name = (String)names.nextElement();
+            String value = request.getHeader(name);
+            // use http helper to extract parameter value as it may contain multiple values
+            Object extracted = HttpHelper.extractHttpParameterValue(value);
+            // mapping the content-type
+            if (name.toLowerCase().equals("content-type")) {
+                name = Exchange.CONTENT_TYPE;
+            }
+            if (headerFilterStrategy != null
+                && !headerFilterStrategy.applyFilterToExternalHeaders(name, extracted, message.getExchange())) {
+                HttpHelper.appendHeader(headers, name, extracted);
+            }
+        }
+                
+        if (request.getCharacterEncoding() != null) {
+            headers.put(Exchange.HTTP_CHARACTER_ENCODING, request.getCharacterEncoding());
+            message.getExchange().setProperty(Exchange.CHARSET_NAME, request.getCharacterEncoding());
+        }
+
+        try {
+            populateRequestParameters(request, message);
+        } catch (Exception e) {
+            throw new RuntimeCamelException("Cannot read request parameters due " + e.getMessage(), e);
+        }
+        
+        Object body = message.getBody();
+        // reset the stream cache if the body is the instance of StreamCache
+        if (body instanceof StreamCache) {
+            ((StreamCache)body).reset();
+        }
+
+        // store the method and query and other info in headers as String types
+        headers.put(Exchange.HTTP_METHOD, request.getMethod());
+        headers.put(Exchange.HTTP_QUERY, request.getQueryString());
+        headers.put(Exchange.HTTP_URL, request.getRequestURL().toString());
+        headers.put(Exchange.HTTP_URI, request.getRequestURI());
+        headers.put(Exchange.HTTP_PATH, request.getPathInfo());
+        headers.put(Exchange.CONTENT_TYPE, request.getContentType());
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("HTTP method {}", request.getMethod());
+            LOG.trace("HTTP query {}", request.getQueryString());
+            LOG.trace("HTTP url {}", request.getRequestURL());
+            LOG.trace("HTTP uri {}", request.getRequestURI());
+            LOG.trace("HTTP path {}", request.getPathInfo());
+            LOG.trace("HTTP content-type {}", request.getContentType());
+        }
+
+        // if content type is serialized java object, then de-serialize it to a Java object
+        if (request.getContentType() != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(request.getContentType())) {
+            try {
+                InputStream is = message.getExchange().getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, body);
+                Object object = HttpHelper.deserializeJavaObjectFromStream(is, message.getExchange().getContext());
+                if (object != null) {
+                    message.setBody(object);
+                }
+            } catch (Exception e) {
+                throw new RuntimeCamelException("Cannot deserialize body to Java object", e);
+            }
+        }
+        
+        populateAttachments(request, message);
+    }
+
+    protected void populateRequestParameters(HttpServletRequest request, HttpMessage message) throws Exception {
+        //we populate the http request parameters without checking the request method
+        Map<String, Object> headers = message.getHeaders();
+        Enumeration<?> names = request.getParameterNames();
+        while (names.hasMoreElements()) {
+            String name = (String)names.nextElement();
+            // there may be multiple values for the same name
+            String[] values = request.getParameterValues(name);
+            LOG.trace("HTTP parameter {} = {}", name, values);
+
+            if (values != null) {
+                for (String value : values) {
+                    if (headerFilterStrategy != null
+                        && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+                        HttpHelper.appendHeader(headers, name, value);
+                    }
+                }
+            }
+        }
+
+        LOG.trace("HTTP method {} with Content-Type {}", request.getMethod(), request.getContentType());
+        Boolean flag = message.getHeader(Exchange.SKIP_WWW_FORM_URLENCODED, Boolean.class);
+        boolean skipWwwFormUrlEncoding =  flag != null ? flag : false; 
+        if (request.getMethod().equals("POST") && request.getContentType() != null
+                && request.getContentType().startsWith(HttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED)
+                && !skipWwwFormUrlEncoding) {
+            String charset = request.getCharacterEncoding();
+            if (charset == null) {
+                charset = "UTF-8";
+            }
+            // Push POST form params into the headers to retain compatibility with DefaultHttpBinding
+            String body = message.getBody(String.class);
+            if (ObjectHelper.isNotEmpty(body)) {
+                for (String param : body.split("&")) {
+                    String[] pair = param.split("=", 2);
+                    if (pair.length == 2) {
+                        String name = URLDecoder.decode(pair[0], charset);
+                        String value = URLDecoder.decode(pair[1], charset);
+                        if (headerFilterStrategy != null
+                                && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+                            HttpHelper.appendHeader(headers, name, value);
+                        }
+                    } else {
+                        throw new IllegalArgumentException("Invalid parameter, expected to be a pair but was " + param);
+                    }
+                }
+            }
+        }
+    }
+    
+    protected void populateAttachments(HttpServletRequest request, HttpMessage message) {
+        // check if there is multipart files, if so will put it into DataHandler
+        Enumeration<?> names = request.getAttributeNames();
+        while (names.hasMoreElements()) {
+            String name = (String) names.nextElement();
+            Object object = request.getAttribute(name);
+            LOG.trace("HTTP attachment {} = {}", name, object);
+            if (object instanceof File) {
+                String fileName = request.getParameter(name);
+                message.addAttachment(fileName, new DataHandler(new CamelFileDataSource((File)object, fileName)));
+            }
+        }
+    }
+
+    public void writeResponse(Exchange exchange, HttpServletResponse response) throws IOException {
+        Message target = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
+        if (exchange.isFailed()) {
+            if (exchange.getException() != null) {
+                doWriteExceptionResponse(exchange.getException(), response);
+            } else {
+                // it must be a fault, no need to check for the fault flag on the message
+                doWriteFaultResponse(target, response, exchange);
+            }
+        } else {
+            if (exchange.hasOut()) {
+                // just copy the protocol relates header if we do not have them
+                copyProtocolHeaders(exchange.getIn(), exchange.getOut());
+            }
+            doWriteResponse(target, response, exchange);
+        }
+    }
+
+    private void copyProtocolHeaders(Message request, Message response) {
+        if (request.getHeader(Exchange.CONTENT_ENCODING) != null) {
+            String contentEncoding = request.getHeader(Exchange.CONTENT_ENCODING, String.class);
+            response.setHeader(Exchange.CONTENT_ENCODING, contentEncoding);
+        }        
+        if (checkChunked(response, response.getExchange())) {
+            response.setHeader(Exchange.TRANSFER_ENCODING, "chunked");
+        }
+    }
+
+    public void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException {
+        // 500 for internal server error
+        response.setStatus(500);
+
+        if (isTransferException()) {
+            // transfer the exception as a serialized java object
+            HttpHelper.writeObjectToServletResponse(response, exception);
+        } else {
+            // write stacktrace as plain text
+            response.setContentType("text/plain");
+            PrintWriter pw = response.getWriter();
+            exception.printStackTrace(pw);
+            pw.flush();
+        }
+    }
+
+    public void doWriteFaultResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
+        message.setHeader(Exchange.HTTP_RESPONSE_CODE, 500);
+        doWriteResponse(message, response, exchange);
+    }
+
+    public void doWriteResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
+        // set the status code in the response. Default is 200.
+        if (message.getHeader(Exchange.HTTP_RESPONSE_CODE) != null) {
+            int code = message.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
+            response.setStatus(code);
+        }
+        // set the content type in the response.
+        String contentType = MessageHelper.getContentType(message);
+        if (contentType != null) {
+            response.setContentType(contentType);
+        }
+
+        // append headers
+        // must use entrySet to ensure case of keys is preserved
+        for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) {
+            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);
+            while (it.hasNext()) {
+                String headerValue = exchange.getContext().getTypeConverter().convertTo(String.class, it.next());
+                if (headerValue != null && headerFilterStrategy != null
+                        && !headerFilterStrategy.applyFilterToCamelHeaders(key, headerValue, exchange)) {
+                    response.addHeader(key, headerValue);
+                }
+            }
+        }
+
+        // write the body.
+        if (message.getBody() != null) {
+            if (GZIPHelper.isGzip(message)) {
+                doWriteGZIPResponse(message, response, exchange);
+            } else {
+                doWriteDirectResponse(message, response, exchange);
+            }
+        }
+    }
+    
+    protected boolean isText(String contentType) {
+        if (contentType != null) {
+            String temp = contentType.toLowerCase();
+            if (temp.indexOf("text") >= 0 || temp.indexOf("html") >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    protected int copyStream(InputStream is, OutputStream os, int bufferSize) throws IOException {
+        try {
+            // copy stream, and must flush on each write as etc Jetty has better performance when
+            // flushing after writing to its servlet output stream
+            return IOHelper.copy(is, os, bufferSize, true);
+        } finally {
+            IOHelper.close(os, is);
+        }
+    }
+
+    protected void doWriteDirectResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
+        // if content type is serialized Java object, then serialize and write it to the response
+        String contentType = message.getHeader(Exchange.CONTENT_TYPE, String.class);
+        if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
+            try {
+                Object object = message.getMandatoryBody(Serializable.class);
+                HttpHelper.writeObjectToServletResponse(response, object);
+                // object is written so return
+                return;
+            } catch (InvalidPayloadException e) {
+                throw new IOException(e);
+            }
+        }
+
+        // prefer streaming
+        InputStream is = null;
+        if (checkChunked(message, exchange)) {
+            is = message.getBody(InputStream.class);
+        } else {
+            // try to use input stream first, so we can copy directly
+            if (!isText(contentType)) {
+                is = exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class, message.getBody());
+            }
+        }
+
+        if (is != null) {
+            ServletOutputStream os = response.getOutputStream();
+            if (!checkChunked(message, exchange)) {
+                CachedOutputStream stream = new CachedOutputStream(exchange);
+                try {
+                    // copy directly from input stream to the cached output stream to get the content length
+                    int len = copyStream(is, stream, response.getBufferSize());
+                    // we need to setup the length if message is not chucked
+                    response.setContentLength(len);
+                    OutputStream current = stream.getCurrentStream();
+                    if (current instanceof ByteArrayOutputStream) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Streaming (direct) response in non-chunked mode with content-length {}");
+                        }
+                        ByteArrayOutputStream bos = (ByteArrayOutputStream) current;
+                        bos.writeTo(os);
+                    } else {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Streaming response in non-chunked mode with content-length {} and buffer size: {}", len, len);
+                        }
+                        copyStream(stream.getInputStream(), os, len);
+                    }
+                } finally {
+                    IOHelper.close(is, os);
+                }
+            } else {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Streaming response in chunked mode with buffer size {}", response.getBufferSize());
+                }
+                copyStream(is, os, response.getBufferSize());
+            }
+        } else {
+            // not convertable as a stream so fallback as a String
+            String data = message.getBody(String.class);
+            if (data != null) {
+                // set content length and encoding before we write data
+                String charset = IOHelper.getCharsetName(exchange, true);
+                final int dataByteLength = data.getBytes(charset).length;
+                response.setCharacterEncoding(charset);
+                response.setContentLength(dataByteLength);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Writing response in non-chunked mode as plain text with content-length {} and buffer size: {}", dataByteLength, response.getBufferSize());
+                }
+                try {
+                    response.getWriter().print(data);
+                } finally {
+                    response.getWriter().flush();
+                }
+            }
+        }
+    }
+
+    protected boolean checkChunked(Message message, Exchange exchange) {
+        boolean answer = true;
+        if (message.getHeader(Exchange.HTTP_CHUNKED) == null) {
+            // check the endpoint option
+            Endpoint endpoint = exchange.getFromEndpoint();
+            if (endpoint instanceof HttpCommonEndpoint) {
+                answer = ((HttpCommonEndpoint)endpoint).isChunked();
+            }
+        } else {
+            answer = message.getHeader(Exchange.HTTP_CHUNKED, boolean.class);
+        }
+        return answer;
+    }
+
+    protected void doWriteGZIPResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
+        byte[] bytes;
+        try {
+            bytes = message.getMandatoryBody(byte[].class);
+        } catch (InvalidPayloadException e) {
+            throw ObjectHelper.wrapRuntimeCamelException(e);
+        }
+
+        byte[] data = GZIPHelper.compressGZIP(bytes);
+        ServletOutputStream os = response.getOutputStream();
+        try {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Streaming response as GZIP in non-chunked mode with content-length {} and buffer size: {}", data.length, response.getBufferSize());
+            }
+            response.setContentLength(data.length);
+            os.write(data);
+            os.flush();
+        } finally {
+            IOHelper.close(os);
+        }
+    }
+
+    public Object parseBody(HttpMessage httpMessage) throws IOException {
+        // lets assume the body is a reader
+        HttpServletRequest request = httpMessage.getRequest();
+        // there is only a body if we have a content length, or its -1 to indicate unknown length
+        int len = request.getContentLength();
+        LOG.trace("HttpServletRequest content-length: {}", len);
+        if (len == 0) {
+            return null;
+        }
+        if (isUseReaderForPayload()) {
+            // use reader to read the response body
+            return request.getReader();
+        } else {
+            // if we do not know if there is any data at all, then make sure to check the stream first
+            if (len < 0 && isEagerCheckContentAvailable()) {
+                InputStream is = request.getInputStream();
+                if (is.available() == 0) {
+                    // no data so return null
+                    return null;
+                }
+            }
+            // read the response body from servlet request
+            return HttpHelper.readRequestBodyFromServletRequest(request, httpMessage.getExchange());
+        }
+    }
+
+    public boolean isUseReaderForPayload() {
+        return useReaderForPayload;
+    }
+
+    public void setUseReaderForPayload(boolean useReaderForPayload) {
+        this.useReaderForPayload = useReaderForPayload;
+    }
+
+    public boolean isEagerCheckContentAvailable() {
+        return eagerCheckContentAvailable;
+    }
+
+    public void setEagerCheckContentAvailable(boolean eagerCheckContentAvailable) {
+        this.eagerCheckContentAvailable = eagerCheckContentAvailable;
+    }
+
+    public boolean isTransferException() {
+        return transferException;
+    }
+
+    public void setTransferException(boolean transferException) {
+        this.transferException = transferException;
+    }
+
+    public HeaderFilterStrategy getHeaderFilterStrategy() {
+        return headerFilterStrategy;
+    }
+
+    public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
+        this.headerFilterStrategy = headerFilterStrategy;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java
new file mode 100644
index 0000000..d76ba10
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java
@@ -0,0 +1,160 @@
+/**
+ * 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.http.common;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.spi.HeaderFilterStrategy;
+
+/**
+ * A pluggable strategy for configuring the http binding so reading request and writing response
+ * can be customized using the Java Servlet API.
+ * <p/>
+ * This is also used by the <tt>camel-jetty</tt> component in the <tt>JettyHttpConsumer</tt> class.
+ */
+public interface HttpBinding {
+
+    /**
+     * Strategy to read the given request and bindings it to the given message.
+     *
+     * @param request  the request
+     * @param message  the message to populate with data from request
+     */
+    void readRequest(HttpServletRequest request, HttpMessage message);
+
+    /**
+     * Parses the body from a {@link org.apache.camel.http.common.HttpMessage}
+     *
+     * @param httpMessage the http message
+     * @return the parsed body returned as either a {@link java.io.InputStream} or a {@link java.io.Reader}
+     * depending on the {@link #setUseReaderForPayload(boolean)} property.
+     * @throws java.io.IOException can be thrown
+     */
+    Object parseBody(HttpMessage httpMessage) throws IOException;
+
+    /**
+     * Writes the exchange to the servlet response.
+     * <p/>
+     * Default implementation will delegate to the following methods depending on the status of the exchange
+     * <ul>
+     *   <li>doWriteResponse - processing returns a OUT message </li>
+     *   <li>doWriteFaultResponse - processing returns a fault message</li>
+     *   <li>doWriteResponse - processing returns an exception and status code 500</li>
+     * </ul>
+     *
+     * @param exchange the exchange
+     * @param response the http response
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void writeResponse(Exchange exchange, HttpServletResponse response) throws IOException;
+
+    /**
+     * Strategy method that writes the response to the http response stream when an exception occurred
+     *
+     * @param exception  the exception occurred
+     * @param response   the http response
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException;
+
+    /**
+     * Strategy method that writes the response to the http response stream for a fault message
+     *
+     * @param message  the fault message
+     * @param response the http response
+     * @param exchange the exchange to provide context for header filtering
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void doWriteFaultResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException;
+
+    /**
+     * Strategy method that writes the response to the http response stream for an OUT message
+     *
+     * @param message  the OUT message
+     * @param response the http response
+     * @param exchange the exchange to provide context for header filtering
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void doWriteResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException;
+
+    /**
+     * Should reader by used instead of input stream.
+     *
+     * @see #setUseReaderForPayload(boolean) for more details
+     * @return <tt>true</tt> if reader should be used
+     */
+    boolean isUseReaderForPayload();
+
+    /**
+     * Should the {@link javax.servlet.http.HttpServletRequest#getReader()} be exposed as the payload of input messages in the Camel
+     * {@link org.apache.camel.Message#getBody()} or not. If false then the {@link javax.servlet.http.HttpServletRequest#getInputStream()} will be exposed.
+     * <p/>
+     * Is default <tt>false</tt>.
+     *
+     * @param useReaderForPayload whether to use reader or not
+     */
+    void setUseReaderForPayload(boolean useReaderForPayload);
+
+    /**
+     * If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back
+     * serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or
+     * Servlet Camel components). On the producer side the exception will be deserialized and thrown as is,
+     * instead of the HttpOperationFailedException. The caused exception is required to be serialized.
+     */
+    boolean isTransferException();
+
+    /**
+     * Whether to eager check whether the HTTP requests has content if the content-length header is 0 or not present.
+     * This can be turned on in case HTTP clients do not send streamed data.
+     */
+    boolean isEagerCheckContentAvailable();
+
+    /**
+     * Whether to eager check whether the HTTP requests has content if the content-length header is 0 or not present.
+     * This can be turned on in case HTTP clients do not send streamed data.
+     */
+    void setEagerCheckContentAvailable(boolean eagerCheckContentAvailable);
+
+    /**
+     * If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back
+     * serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or
+     * Servlet Camel components). On the producer side the exception will be deserialized and thrown as is,
+     * instead of the HttpOperationFailedException. The caused exception is required to be serialized.
+     */
+    void setTransferException(boolean transferException);
+
+    /**
+     * Gets the header filter strategy
+     *
+     * @return the strategy
+     */
+    HeaderFilterStrategy getHeaderFilterStrategy();
+
+    /**
+     * Sets the header filter strategy to use.
+     * <p/>
+     * Will default use {@link org.apache.camel.http.common.HttpHeaderFilterStrategy}
+     *
+     * @param headerFilterStrategy the custom strategy
+     */
+    void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy);
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
new file mode 100644
index 0000000..711a878
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
@@ -0,0 +1,75 @@
+/**
+ * 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.http.common;
+
+import org.apache.camel.impl.HeaderFilterStrategyComponent;
+
+public abstract class HttpCommonComponent extends HeaderFilterStrategyComponent {
+
+    protected HttpBinding httpBinding;
+    protected HttpConfiguration httpConfiguration;
+
+    public HttpCommonComponent(Class<? extends HttpCommonEndpoint> endpointClass) {
+        super(endpointClass);
+    }
+
+    /**
+     * Connects the URL specified on the endpoint to the specified processor.
+     *
+     * @param consumer the consumer
+     * @throws Exception can be thrown
+     */
+    public void connect(HttpConsumer consumer) throws Exception {
+    }
+
+    /**
+     * Disconnects the URL specified on the endpoint from the specified processor.
+     *
+     * @param consumer the consumer
+     * @throws Exception can be thrown
+     */
+    public void disconnect(HttpConsumer consumer) throws Exception {
+    }
+
+    @Override
+    protected boolean useIntrospectionOnEndpoint() {
+        return false;
+    }
+
+    public HttpBinding getHttpBinding() {
+        return httpBinding;
+    }
+
+    /**
+     * To use a custom HttpBinding to control the mapping between Camel message and HttpClient.
+     */
+    public void setHttpBinding(HttpBinding httpBinding) {
+        this.httpBinding = httpBinding;
+    }
+
+    public HttpConfiguration getHttpConfiguration() {
+        return httpConfiguration;
+    }
+
+    /**
+     * To use the shared HttpConfiguration as base configuration.
+     */
+    public void setHttpConfiguration(HttpConfiguration httpConfiguration) {
+        this.httpConfiguration = httpConfiguration;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
new file mode 100644
index 0000000..4ba2163
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
@@ -0,0 +1,383 @@
+/**
+ * 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.http.common;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.spi.HeaderFilterStrategyAware;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class HttpCommonEndpoint extends DefaultEndpoint implements HeaderFilterStrategyAware {
+
+    // Note: all options must be documented with description in annotations so extended components can access the documentation
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpCommonEndpoint.class);
+
+    HttpCommonComponent component;
+    UrlRewrite urlRewrite;
+
+    @UriPath(label = "producer", description = "The url of the HTTP endpoint to call.") @Metadata(required = "true")
+    URI httpUri;
+    @UriParam(description = "To use a custom HeaderFilterStrategy to filter header to and from Camel message.")
+    HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
+    @UriParam(description = "To use a custom HttpBinding to control the mapping between Camel message and HttpClient.")
+    HttpBinding binding;
+    @UriParam(label = "producer", defaultValue = "true",
+            description = "Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server."
+                    + " This allows you to get all responses regardless of the HTTP status code.")
+    boolean throwExceptionOnFailure = true;
+    @UriParam(label = "producer",
+            description = "If the option is true, HttpProducer will ignore the Exchange.HTTP_URI header, and use the endpoint's URI for request."
+                    + " You may also set the option throwExceptionOnFailure to be false to let the HttpProducer send all the fault response back.")
+    boolean bridgeEndpoint;
+    @UriParam(label = "consumer",
+            description = "Whether or not the consumer should try to find a target consumer by matching the URI prefix if no exact match is found.")
+    boolean matchOnUriPrefix;
+    @UriParam(defaultValue = "true", description = "If this option is false Jetty servlet will disable the HTTP streaming and set the content-length header on the response")
+    boolean chunked = true;
+    @UriParam(label = "consumer",
+            description = "Determines whether or not the raw input stream from Jetty is cached or not"
+                    + " (Camel will read the stream into a in memory/overflow to file, Stream caching) cache."
+                    + " By default Camel will cache the Jetty input stream to support reading it multiple times to ensure it Camel"
+                    + " can retrieve all data from the stream. However you can set this option to true when you for example need"
+                    + " to access the raw stream, such as streaming it directly to a file or other persistent store."
+                    + " DefaultHttpBinding will copy the request input stream into a stream cache and put it into message body"
+                    + " if this option is false to support reading the stream multiple times."
+                    + " If you use Jetty to bridge/proxy an endpoint then consider enabling this option to improve performance,"
+                    + " in case you do not need to read the message payload multiple times.")
+    boolean disableStreamCache;
+    @UriParam(label = "producer", description = "The proxy host name")
+    String proxyHost;
+    @UriParam(label = "producer", description = "The proxy port number")
+    int proxyPort;
+    @UriParam(label = "producer", enums = "Basic,Digest,NTLM", description = "Authentication method for proxy, either as Basic, Digest or NTLM.")
+    String authMethodPriority;
+    @UriParam(description = "Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server."
+            + " This allows you to get all responses regardless of the HTTP status code.")
+    boolean transferException;
+    @UriParam(label = "consumer",
+            description = "Specifies whether to enable HTTP TRACE for this Jetty consumer. By default TRACE is turned off.")
+    boolean traceEnabled;
+    @UriParam(label = "consumer",
+            description = "Used to only allow consuming if the HttpMethod matches, such as GET/POST/PUT etc. Multiple methods can be specified separated by comma.")
+    String httpMethodRestrict;
+    @UriParam(label = "consumer",
+            description = "To use a custom buffer size on the javax.servlet.ServletResponse.")
+    Integer responseBufferSize;
+    @UriParam(label = "producer",
+            description = "If this option is true, The http producer won't read response body and cache the input stream")
+    boolean ignoreResponseBody;
+    @UriParam(label = "producer", defaultValue = "true",
+            description = "If this option is true then IN exchange headers will be copied to OUT exchange headers according to copy strategy."
+                    + " Setting this to false, allows to only include the headers from the HTTP response (not propagating IN headers).")
+    boolean copyHeaders = true;
+    @UriParam(label = "consumer",
+            description = "Whether to eager check whether the HTTP requests has content if the content-length header is 0 or not present."
+                    + " This can be turned on in case HTTP clients do not send streamed data.")
+    boolean eagerCheckContentAvailable;
+
+    public HttpCommonEndpoint() {
+    }
+
+    public HttpCommonEndpoint(String endPointURI, HttpCommonComponent component, URI httpURI) throws URISyntaxException {
+        super(endPointURI, component);
+        this.component = component;
+        this.httpUri = httpURI;
+    }
+
+    public void connect(HttpConsumer consumer) throws Exception {
+        component.connect(consumer);
+    }
+
+    public void disconnect(HttpConsumer consumer) throws Exception {
+        component.disconnect(consumer);
+    }
+
+    public boolean isLenientProperties() {
+        // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
+        return true;
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+
+    // Properties
+    //-------------------------------------------------------------------------
+
+    public HttpBinding getBinding() {
+        if (binding == null) {
+            // create a new binding and use the options from this endpoint
+            binding = new DefaultHttpBinding();
+            binding.setHeaderFilterStrategy(getHeaderFilterStrategy());
+            binding.setTransferException(isTransferException());
+            binding.setEagerCheckContentAvailable(isEagerCheckContentAvailable());
+        }
+        return binding;
+    }
+
+    /**
+     * To use a custom HttpBinding to control the mapping between Camel message and HttpClient.
+     */
+    public void setBinding(HttpBinding binding) {
+        this.binding = binding;
+    }
+
+    public String getPath() {
+        //if the path is empty, we just return the default path here
+        return httpUri.getPath().length() == 0 ? "/" : httpUri.getPath();
+    }
+
+    public int getPort() {
+        if (httpUri.getPort() == -1) {
+            if ("https".equals(getProtocol())) {
+                return 443;
+            } else {
+                return 80;
+            }
+        }
+        return httpUri.getPort();
+    }
+
+    public String getProtocol() {
+        return httpUri.getScheme();
+    }
+
+    public URI getHttpUri() {
+        return httpUri;
+    }
+
+    /**
+     * The url of the HTTP endpoint to call.
+     */
+    public void setHttpUri(URI httpUri) {
+        this.httpUri = httpUri;
+    }
+
+    public HeaderFilterStrategy getHeaderFilterStrategy() {
+        return headerFilterStrategy;
+    }
+
+    /**
+     * To use a custom HeaderFilterStrategy to filter header to and from Camel message.
+     */
+    public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
+        this.headerFilterStrategy = headerFilterStrategy;
+    }
+
+    public boolean isThrowExceptionOnFailure() {
+        return throwExceptionOnFailure;
+    }
+
+    /**
+     * Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server.
+     * This allows you to get all responses regardless of the HTTP status code.
+     */
+    public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
+        this.throwExceptionOnFailure = throwExceptionOnFailure;
+    }
+
+    public boolean isBridgeEndpoint() {
+        return bridgeEndpoint;
+    }
+
+    /**
+     * If the option is true, HttpProducer will ignore the Exchange.HTTP_URI header, and use the endpoint's URI for request.
+     * You may also set the option throwExceptionOnFailure to be false to let the HttpProducer send all the fault response back.
+     */
+    public void setBridgeEndpoint(boolean bridge) {
+        this.bridgeEndpoint = bridge;
+    }
+
+    public boolean isMatchOnUriPrefix() {
+        return matchOnUriPrefix;
+    }
+
+    /**
+     * Whether or not the consumer should try to find a target consumer by matching the URI prefix if no exact match is found.
+     * <p/>
+     * See more details at: http://camel.apache.org/how-do-i-let-jetty-match-wildcards.html
+     */
+    public void setMatchOnUriPrefix(boolean match) {
+        this.matchOnUriPrefix = match;
+    }
+
+    public boolean isDisableStreamCache() {
+        return this.disableStreamCache;
+    }
+
+    /**
+     * Determines whether or not the raw input stream from Jetty is cached or not
+     * (Camel will read the stream into a in memory/overflow to file, Stream caching) cache.
+     * By default Camel will cache the Jetty input stream to support reading it multiple times to ensure it Camel
+     * can retrieve all data from the stream. However you can set this option to true when you for example need
+     * to access the raw stream, such as streaming it directly to a file or other persistent store.
+     * DefaultHttpBinding will copy the request input stream into a stream cache and put it into message body
+     * if this option is false to support reading the stream multiple times.
+     * If you use Jetty to bridge/proxy an endpoint then consider enabling this option to improve performance,
+     * in case you do not need to read the message payload multiple times.
+     */
+    public void setDisableStreamCache(boolean disable) {
+        this.disableStreamCache = disable;
+    }
+
+    public boolean isChunked() {
+        return this.chunked;
+    }
+
+    /**
+     * If this option is false Jetty servlet will disable the HTTP streaming and set the content-length header on the response
+     */
+    public void setChunked(boolean chunked) {
+        this.chunked = chunked;
+    }
+
+    public String getProxyHost() {
+        return proxyHost;
+    }
+
+    /**
+     * The proxy host name
+     */
+    public void setProxyHost(String proxyHost) {
+        this.proxyHost = proxyHost;
+    }
+
+    public int getProxyPort() {
+        return proxyPort;
+    }
+
+    /**
+     * The proxy port number
+     */
+    public void setProxyPort(int proxyPort) {
+        this.proxyPort = proxyPort;
+    }
+
+    public String getAuthMethodPriority() {
+        return authMethodPriority;
+    }
+
+    /**
+     * Authentication method for proxy, either as Basic, Digest or NTLM.
+     */
+    public void setAuthMethodPriority(String authMethodPriority) {
+        this.authMethodPriority = authMethodPriority;
+    }
+
+    public boolean isTransferException() {
+        return transferException;
+    }
+
+    /**
+     * Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server.
+     * This allows you to get all responses regardless of the HTTP status code.
+     */
+    public void setTransferException(boolean transferException) {
+        this.transferException = transferException;
+    }
+
+    public boolean isTraceEnabled() {
+        return this.traceEnabled;
+    }
+
+    /**
+     * Specifies whether to enable HTTP TRACE for this Jetty consumer. By default TRACE is turned off.
+     */
+    public void setTraceEnabled(boolean traceEnabled) {
+        this.traceEnabled = traceEnabled;
+    }
+
+    public String getHttpMethodRestrict() {
+        return httpMethodRestrict;
+    }
+
+    /**
+     * Used to only allow consuming if the HttpMethod matches, such as GET/POST/PUT etc.
+     * Multiple methods can be specified separated by comma.
+     */
+    public void setHttpMethodRestrict(String httpMethodRestrict) {
+        this.httpMethodRestrict = httpMethodRestrict;
+    }
+
+    public UrlRewrite getUrlRewrite() {
+        return urlRewrite;
+    }
+
+    /**
+     * Refers to a custom org.apache.camel.component.http.UrlRewrite which allows you to rewrite urls when you bridge/proxy endpoints.
+     * See more details at http://camel.apache.org/urlrewrite.html
+     */
+    public void setUrlRewrite(UrlRewrite urlRewrite) {
+        this.urlRewrite = urlRewrite;
+    }
+
+    public Integer getResponseBufferSize() {
+        return responseBufferSize;
+    }
+
+    /**
+     * To use a custom buffer size on the javax.servlet.ServletResponse.
+     */
+    public void setResponseBufferSize(Integer responseBufferSize) {
+        this.responseBufferSize = responseBufferSize;
+    }
+
+    public boolean isIgnoreResponseBody() {
+        return ignoreResponseBody;
+    }
+
+    /**
+     * If this option is true, The http producer won't read response body and cache the input stream.
+     */
+    public void setIgnoreResponseBody(boolean ignoreResponseBody) {
+        this.ignoreResponseBody = ignoreResponseBody;
+    }
+
+    /**
+     * If this option is true then IN exchange headers will be copied to OUT exchange headers according to copy strategy.
+     * Setting this to false, allows to only include the headers from the HTTP response (not propagating IN headers).
+     */
+    public boolean isCopyHeaders() {
+        return copyHeaders;
+    }
+
+    public void setCopyHeaders(boolean copyHeaders) {
+        this.copyHeaders = copyHeaders;
+    }
+
+    public boolean isEagerCheckContentAvailable() {
+        return eagerCheckContentAvailable;
+    }
+
+    /**
+     * Whether to eager check whether the HTTP requests has content if the content-length header is 0 or not present.
+     * This can be turned on in case HTTP clients do not send streamed data.
+     */
+    public void setEagerCheckContentAvailable(boolean eagerCheckContentAvailable) {
+        this.eagerCheckContentAvailable = eagerCheckContentAvailable;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConfiguration.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConfiguration.java
new file mode 100644
index 0000000..6a3e646
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConfiguration.java
@@ -0,0 +1,143 @@
+/**
+ * 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.http.common;
+
+import java.io.Serializable;
+
+public class HttpConfiguration implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String authMethod;
+    private String authUsername;
+    private String authPassword;
+    private String authDomain;
+    private String authHost;
+
+    private String proxyAuthMethod;
+    private String proxyAuthUsername;
+    private String proxyAuthPassword;
+    private String proxyAuthDomain;
+    private String proxyAuthHost;
+
+    private String proxyHost;
+    private int proxyPort;
+    private String authMethodPriority;
+
+    public String getAuthUsername() {
+        return authUsername;
+    }
+
+    public void setAuthUsername(String authUsername) {
+        this.authUsername = authUsername;
+    }
+
+    public String getAuthPassword() {
+        return authPassword;
+    }
+
+    public void setAuthPassword(String authPassword) {
+        this.authPassword = authPassword;
+    }
+
+    public String getAuthDomain() {
+        return authDomain;
+    }
+
+    public void setAuthDomain(String authDomain) {
+        this.authDomain = authDomain;
+    }
+
+    public String getAuthHost() {
+        return authHost;
+    }
+
+    public void setAuthHost(String authHost) {
+        this.authHost = authHost;
+    }
+
+    public String getProxyAuthUsername() {
+        return proxyAuthUsername;
+    }
+
+    public void setProxyAuthUsername(String proxyAuthUsername) {
+        this.proxyAuthUsername = proxyAuthUsername;
+    }
+
+    public String getProxyAuthPassword() {
+        return proxyAuthPassword;
+    }
+
+    public void setProxyAuthPassword(String proxyAuthPassword) {
+        this.proxyAuthPassword = proxyAuthPassword;
+    }
+
+    public String getProxyAuthDomain() {
+        return proxyAuthDomain;
+    }
+
+    public void setProxyAuthDomain(String proxyAuthDomain) {
+        this.proxyAuthDomain = proxyAuthDomain;
+    }
+
+    public String getProxyAuthHost() {
+        return proxyAuthHost;
+    }
+
+    public void setProxyAuthHost(String proxyAuthHost) {
+        this.proxyAuthHost = proxyAuthHost;
+    }
+
+    public String getAuthMethod() {
+        return authMethod;
+    }
+
+    public void setAuthMethod(String authMethod) {
+        this.authMethod = authMethod;
+    }
+
+    public String getProxyAuthMethod() {
+        return proxyAuthMethod;
+    }
+
+    public void setProxyAuthMethod(String proxyAuthMethod) {
+        this.proxyAuthMethod = proxyAuthMethod;
+    }
+
+    public String getProxyHost() {
+        return proxyHost;
+    }
+
+    public void setProxyHost(String proxyHost) {
+        this.proxyHost = proxyHost;
+    }
+
+    public int getProxyPort() {
+        return proxyPort;
+    }
+
+    public void setProxyPort(int proxyPort) {
+        this.proxyPort = proxyPort;
+    }
+
+    public String getAuthMethodPriority() {
+        return authMethodPriority;
+    }
+
+    public void setAuthMethodPriority(String authMethodPriority) {
+        this.authMethodPriority = authMethodPriority;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConstants.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConstants.java
new file mode 100644
index 0000000..bccf724
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConstants.java
@@ -0,0 +1,26 @@
+/**
+ * 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.http.common;
+
+public final class HttpConstants {
+
+    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";
+
+    private HttpConstants() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConsumer.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConsumer.java
new file mode 100644
index 0000000..f389081
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConsumer.java
@@ -0,0 +1,80 @@
+/**
+ * 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.http.common;
+
+import org.apache.camel.Processor;
+import org.apache.camel.SuspendableService;
+import org.apache.camel.impl.DefaultConsumer;
+
+public class HttpConsumer extends DefaultConsumer implements SuspendableService {
+    private volatile boolean suspended;
+    private boolean traceEnabled;
+
+    public HttpConsumer(HttpCommonEndpoint endpoint, Processor processor) {
+        super(endpoint, processor);
+        if (endpoint.isTraceEnabled()) {
+            setTraceEnabled(true);
+        }
+    }
+
+    @Override
+    public HttpCommonEndpoint getEndpoint() {
+        return (HttpCommonEndpoint)super.getEndpoint();
+    }
+
+    public HttpBinding getBinding() {
+        return getEndpoint().getBinding();
+    }
+
+    public String getPath() {
+        return getEndpoint().getPath();
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        getEndpoint().connect(this);
+        suspended = false;
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        suspended = false;
+        getEndpoint().disconnect(this);
+        super.doStop();
+    }
+
+    public void suspend() {
+        suspended = true;
+    }
+
+    public void resume() {
+        suspended = false;
+    }
+
+    public boolean isSuspended() {
+        return suspended;
+    }
+
+    public boolean isTraceEnabled() {
+        return this.traceEnabled;
+    }
+
+    public void setTraceEnabled(boolean traceEnabled) {
+        this.traceEnabled = traceEnabled;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConverter.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConverter.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConverter.java
new file mode 100644
index 0000000..8efa895
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpConverter.java
@@ -0,0 +1,98 @@
+/**
+ * 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.http.common;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.util.GZIPHelper;
+
+/**
+ * Some converter methods making it easy to convert the body of a message to servlet types or to switch between
+ * the underlying {@link ServletInputStream} or {@link BufferedReader} payloads etc.
+ */
+@Converter
+public final class HttpConverter {
+
+    private HttpConverter() {
+    }
+
+    @Converter
+    public static HttpServletRequest toServletRequest(Message message) {
+        if (message == null) {
+            return null;
+        }
+        return message.getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class);
+    }
+
+    @Converter
+    public static HttpServletResponse toServletResponse(Message message) {
+        if (message == null) {
+            return null;
+        }
+        return message.getHeader(Exchange.HTTP_SERVLET_RESPONSE, HttpServletResponse.class);
+    }
+
+    @Converter
+    public static ServletInputStream toServletInputStream(HttpMessage message) throws IOException {
+        HttpServletRequest request = toServletRequest(message);
+        if (request != null) {
+            return request.getInputStream();
+        }
+        return null;
+    }
+
+    @Converter
+    public static InputStream toInputStream(HttpMessage message, Exchange exchange) throws Exception {
+        return toInputStream(toServletRequest(message), exchange);
+    }
+
+    @Converter
+    public static BufferedReader toReader(HttpMessage message) throws IOException {
+        HttpServletRequest request = toServletRequest(message);
+        if (request != null) {
+            return request.getReader();
+        }
+        return null;
+    }
+
+    @Converter
+    public static InputStream toInputStream(HttpServletRequest request, Exchange exchange) throws IOException {
+        if (request == null) {
+            return null;
+        }
+        InputStream is = request.getInputStream();
+        if (is != null && is.available() <= 0) {
+            // there is no data, so we cannot uncompress etc.
+            return is;
+        }
+        if (exchange == null || !exchange.getProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.FALSE, Boolean.class)) {
+            String contentEncoding = request.getHeader(Exchange.CONTENT_ENCODING);
+            return GZIPHelper.uncompressGzip(contentEncoding, is);
+        } else {
+            return is;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e51b7f8d/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java
new file mode 100644
index 0000000..6df5b34
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java
@@ -0,0 +1,49 @@
+/**
+ * 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.http.common;
+
+import org.apache.camel.impl.DefaultHeaderFilterStrategy;
+
+public class HttpHeaderFilterStrategy extends DefaultHeaderFilterStrategy {
+    
+    public HttpHeaderFilterStrategy() {
+        initialize();  
+    }
+
+    protected void initialize() {
+        getOutFilter().add("content-length");
+        getOutFilter().add("content-type");
+        getOutFilter().add("host");
+        // Add the filter for the Generic Message header
+        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.5
+        getOutFilter().add("cache-control");
+        getOutFilter().add("connection");
+        getOutFilter().add("date");
+        getOutFilter().add("pragma");
+        getOutFilter().add("trailer");
+        getOutFilter().add("transfer-encoding");
+        getOutFilter().add("upgrade");
+        getOutFilter().add("via");
+        getOutFilter().add("warning");
+        
+        setLowerCase(true);
+        
+        // filter headers begin with "Camel" or "org.apache.camel"
+        // must ignore case for Http based transports
+        setOutFilterPattern("(?i)(Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*");
+    }
+}