You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@axis.apache.org by sa...@apache.org on 2012/04/30 12:04:11 UTC

svn commit: r1332141 - in /axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http: src/org/apache/axis2/transport/http/impl/httpclient4/ test/org/apache/axis2/transport/http/

Author: sagara
Date: Mon Apr 30 10:04:10 2012
New Revision: 1332141

URL: http://svn.apache.org/viewvc?rev=1332141&view=rev
Log:
Apply latest patch for AXIS2-4318. 

Added:
    axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java   (with props)
    axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java   (with props)
    axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPClient4SenderTest.java   (with props)
Modified:
    axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPSenderTest.java

Added: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java?rev=1332141&view=auto
==============================================================================
--- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java (added)
+++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java Mon Apr 30 10:04:10 2012
@@ -0,0 +1,462 @@
+/*
+ * 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.axis2.transport.http.impl.httpclient4;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.axis2.transport.http.HTTPTransportConstants;
+import org.apache.axis2.transport.http.HttpTransportProperties;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.NTCredentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.apache.http.impl.client.AbstractHttpClient;
+
+import javax.xml.namespace.QName;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+
+public class HTTPProxyConfigurator {
+
+    private static Log log = LogFactory.getLog(HTTPProxyConfigurator.class);
+
+    /**
+     * Configure HTTP Proxy settings of commons-httpclient HostConfiguration.
+     * Proxy settings can be get from axis2.xml, Java proxy settings or can be
+     * override through property in message context.
+     * <p/>
+     * HTTP Proxy setting element format: <parameter name="Proxy">
+     * <Configuration> <ProxyHost>example.org</ProxyHost>
+     * <ProxyPort>3128</ProxyPort> <ProxyUser>EXAMPLE/John</ProxyUser>
+     * <ProxyPassword>password</ProxyPassword> <Configuration> <parameter>
+     *
+     * @param messageContext
+     *            in message context for
+     * @param httpClient
+     *            instance
+     * @throws org.apache.axis2.AxisFault
+     *             if Proxy settings are invalid
+     */
+    public static void configure(MessageContext messageContext, AbstractHttpClient httpClient)
+            throws AxisFault {
+
+        Credentials proxyCredentials = null;
+        String proxyHost = null;
+        String nonProxyHosts = null;
+        Integer proxyPort = -1;
+        String proxyUser = null;
+        String proxyPassword = null;
+
+        // Getting configuration values from Axis2.xml
+        Parameter proxySettingsFromAxisConfig = messageContext.getConfigurationContext()
+                .getAxisConfiguration().getParameter(HTTPTransportConstants.ATTR_PROXY);
+        if (proxySettingsFromAxisConfig != null) {
+            OMElement proxyConfiguration =
+                    getProxyConfigurationElement(proxySettingsFromAxisConfig);
+            proxyHost = getProxyHost(proxyConfiguration);
+            proxyPort = getProxyPort(proxyConfiguration);
+            proxyUser = getProxyUser(proxyConfiguration);
+            proxyPassword = getProxyPassword(proxyConfiguration);
+            if (proxyUser != null) {
+                if (proxyPassword == null) {
+                    proxyPassword = "";
+                }
+                int proxyUserDomainIndex = proxyUser.indexOf("\\");
+                if (proxyUserDomainIndex > 0) {
+                    String domain = proxyUser.substring(0, proxyUserDomainIndex);
+                    if (proxyUser.length() > proxyUserDomainIndex + 1) {
+                        String user = proxyUser.substring(proxyUserDomainIndex + 1);
+                        proxyCredentials = new NTCredentials(user, proxyPassword, proxyHost,
+                                                             domain);
+                    }
+                }
+                proxyCredentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
+            }
+
+        }
+
+        // If there is runtime proxy settings, these settings will override
+        // settings from axis2.xml
+        HttpTransportProperties.ProxyProperties proxyProperties =
+                (HttpTransportProperties.ProxyProperties) messageContext
+                .getProperty(HTTPConstants.PROXY);
+        if (proxyProperties != null) {
+            String proxyHostProp = proxyProperties.getProxyHostName();
+            if (proxyHostProp == null || proxyHostProp.length() <= 0) {
+                throw new AxisFault("HTTP Proxy host is not available. Host is a MUST parameter");
+            } else {
+                proxyHost = proxyHostProp;
+            }
+            proxyPort = proxyProperties.getProxyPort();
+
+            // Overriding credentials
+            String userName = proxyProperties.getUserName();
+            String password = proxyProperties.getPassWord();
+            String domain = proxyProperties.getDomain();
+
+            if (userName != null && password != null && domain != null) {
+                proxyCredentials = new NTCredentials(userName, password, proxyHost, domain);
+            } else if (userName != null && domain == null) {
+                proxyCredentials = new UsernamePasswordCredentials(userName, password);
+            }
+
+        }
+
+        // Overriding proxy settings if proxy is available from JVM settings
+        String host = System.getProperty(HTTPTransportConstants.HTTP_PROXY_HOST);
+        if (host != null) {
+            proxyHost = host;
+        }
+
+        String port = System.getProperty(HTTPTransportConstants.HTTP_PROXY_PORT);
+        if (port != null) {
+            proxyPort = Integer.parseInt(port);
+        }
+
+        if (proxyCredentials != null) {
+            // TODO : Set preemptive authentication, but its not recommended in HC 4
+            httpClient.getParams().setParameter(ClientPNames.HANDLE_AUTHENTICATION, true);
+
+            httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, proxyCredentials);
+            HttpHost proxy = new HttpHost(proxyHost, proxyPort);
+            httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
+
+        }
+    }
+
+    private static OMElement getProxyConfigurationElement(Parameter proxySettingsFromAxisConfig)
+            throws AxisFault {
+        OMElement proxyConfigurationElement = proxySettingsFromAxisConfig.getParameterElement()
+                .getFirstElement();
+        if (proxyConfigurationElement == null) {
+            log.error(HTTPTransportConstants.PROXY_CONFIGURATION_NOT_FOUND);
+            throw new AxisFault(HTTPTransportConstants.PROXY_CONFIGURATION_NOT_FOUND);
+        }
+        return proxyConfigurationElement;
+    }
+
+    private static String getProxyHost(OMElement proxyConfiguration) throws AxisFault {
+        OMElement proxyHostElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_HOST_ELEMENT));
+        if (proxyHostElement == null) {
+            log.error(HTTPTransportConstants.PROXY_HOST_ELEMENT_NOT_FOUND);
+            throw new AxisFault(HTTPTransportConstants.PROXY_HOST_ELEMENT_NOT_FOUND);
+        }
+        String proxyHost = proxyHostElement.getText();
+        if (proxyHost == null) {
+            log.error(HTTPTransportConstants.PROXY_HOST_ELEMENT_WITH_EMPTY_VALUE);
+            throw new AxisFault(HTTPTransportConstants.PROXY_HOST_ELEMENT_WITH_EMPTY_VALUE);
+        }
+        return proxyHost;
+    }
+
+    private static Integer getProxyPort(OMElement proxyConfiguration) throws AxisFault {
+        OMElement proxyPortElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_PORT_ELEMENT));
+        if (proxyPortElement == null) {
+            log.error(HTTPTransportConstants.PROXY_PORT_ELEMENT_NOT_FOUND);
+            throw new AxisFault(HTTPTransportConstants.PROXY_PORT_ELEMENT_NOT_FOUND);
+        }
+        String proxyPort = proxyPortElement.getText();
+        if (proxyPort == null) {
+            log.error(HTTPTransportConstants.PROXY_PORT_ELEMENT_WITH_EMPTY_VALUE);
+            throw new AxisFault(HTTPTransportConstants.PROXY_PORT_ELEMENT_WITH_EMPTY_VALUE);
+        }
+        return Integer.parseInt(proxyPort);
+    }
+
+    private static String getProxyUser(OMElement proxyConfiguration) {
+        OMElement proxyUserElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_USER_ELEMENT));
+        if (proxyUserElement == null) {
+            return null;
+        }
+        String proxyUser = proxyUserElement.getText();
+        if (proxyUser == null) {
+            log.warn("Empty user name element in HTTP Proxy settings.");
+            return null;
+        }
+
+        return proxyUser;
+    }
+
+    private static String getProxyPassword(OMElement proxyConfiguration) {
+        OMElement proxyPasswordElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_PASSWORD_ELEMENT));
+        if (proxyPasswordElement == null) {
+            return null;
+        }
+        String proxyUser = proxyPasswordElement.getText();
+        if (proxyUser == null) {
+            log.warn("Empty user name element in HTTP Proxy settings.");
+            return null;
+        }
+
+        return proxyUser;
+    }
+
+    /**
+     * Check whether http proxy is configured or active. This is not a deep
+     * check.
+     *
+     * @param messageContext
+     *            in message context
+     * @param targetURL
+     *            URL of the edpoint which we are sending the request
+     * @return true if proxy is enabled, false otherwise
+     */
+    public static boolean isProxyEnabled(MessageContext messageContext, URL targetURL) {
+        boolean proxyEnabled = false;
+
+        Parameter param = messageContext.getConfigurationContext().getAxisConfiguration()
+                .getParameter(HTTPTransportConstants.ATTR_PROXY);
+
+        // If configuration is over ridden
+        Object obj = messageContext.getProperty(HTTPConstants.PROXY);
+
+        // From Java Networking Properties
+        String sp = System.getProperty(HTTPTransportConstants.HTTP_PROXY_HOST);
+
+        if (param != null || obj != null || sp != null) {
+            proxyEnabled = true;
+        }
+
+        boolean isNonProxyHost = validateNonProxyHosts(targetURL.getHost());
+
+        return proxyEnabled && !isNonProxyHost;
+    }
+
+    /**
+     * Validates for names that shouldn't be listered as proxies. The
+     * http.nonProxyHosts can be set to specify the hosts which should be
+     * connected to directly (not through the proxy server). The value of the
+     * http.nonProxyHosts property can be a list of hosts, each separated by a
+     * |; it can also take a regular expression for matches; for example:
+     * *.sfbay.sun.com would match any fully qualified hostname in the sfbay
+     * domain.
+     * <p/>
+     * For more information refer to :
+     * http://java.sun.com/features/2002/11/hilevel_network.html
+     * <p/>
+     * false : validation fail : User can use the proxy true : validation pass ;
+     * User can't use the proxy
+     *
+     * @return boolean
+     */
+    private static boolean validateNonProxyHosts(String host) {
+        // From system property http.nonProxyHosts
+        String nonProxyHosts = System.getProperty(HTTPTransportConstants.HTTP_NON_PROXY_HOSTS);
+        return isHostInNonProxyList(host, nonProxyHosts);
+    }
+
+    /**
+     * Check if the specified host is in the list of non proxy hosts.
+     *
+     * @param host
+     *            host name
+     * @param nonProxyHosts
+     *            string containing the list of non proxy hosts
+     * @return true/false
+     */
+    public static boolean isHostInNonProxyList(String host, String nonProxyHosts) {
+        if ((nonProxyHosts == null) || (host == null)) {
+            return false;
+        }
+
+        /*
+         * The http.nonProxyHosts system property is a list enclosed in double
+         * quotes with items separated by a vertical bar.
+         */
+        StringTokenizer tokenizer = new StringTokenizer(nonProxyHosts, "|\"");
+
+        while (tokenizer.hasMoreTokens()) {
+            String pattern = tokenizer.nextToken();
+            if (match(pattern, host, false)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Matches a string against a pattern. The pattern contains two special
+     * characters: '*' which means zero or more characters,
+     *
+     * @param pattern
+     *            the (non-null) pattern to match against
+     * @param str
+     *            the (non-null) string that must be matched against the pattern
+     * @param isCaseSensitive
+     * @return <code>true</code> when the string matches against the pattern,
+     *         <code>false</code> otherwise.
+     */
+    private static boolean match(String pattern, String str, boolean isCaseSensitive) {
+
+        char[] patArr = pattern.toCharArray();
+        char[] strArr = str.toCharArray();
+        int patIdxStart = 0;
+        int patIdxEnd = patArr.length - 1;
+        int strIdxStart = 0;
+        int strIdxEnd = strArr.length - 1;
+        char ch;
+        boolean containsStar = false;
+
+        for (int i = 0; i < patArr.length; i++) {
+            if (patArr[i] == '*') {
+                containsStar = true;
+                break;
+            }
+        }
+        if (!containsStar) {
+
+            // No '*'s, so we make a shortcut
+            if (patIdxEnd != strIdxEnd) {
+                return false; // Pattern and string do not have the same size
+            }
+            for (int i = 0; i <= patIdxEnd; i++) {
+                ch = patArr[i];
+                if (isCaseSensitive && (ch != strArr[i])) {
+                    return false; // Character mismatch
+                }
+                if (!isCaseSensitive
+                        && (Character.toUpperCase(ch) != Character.toUpperCase(strArr[i]))) {
+                    return false; // Character mismatch
+                }
+            }
+            return true; // String matches against pattern
+        }
+        if (patIdxEnd == 0) {
+            return true; // Pattern contains only '*', which matches anything
+        }
+
+        // Process characters before first star
+        while ((ch = patArr[patIdxStart]) != '*' && (strIdxStart <= strIdxEnd)) {
+            if (isCaseSensitive && (ch != strArr[strIdxStart])) {
+                return false; // Character mismatch
+            }
+            if (!isCaseSensitive
+                    && (Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxStart]))) {
+                return false; // Character mismatch
+            }
+            patIdxStart++;
+            strIdxStart++;
+        }
+        if (strIdxStart > strIdxEnd) {
+
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            for (int i = patIdxStart; i <= patIdxEnd; i++) {
+                if (patArr[i] != '*') {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // Process characters after last star
+        while ((ch = patArr[patIdxEnd]) != '*' && (strIdxStart <= strIdxEnd)) {
+            if (isCaseSensitive && (ch != strArr[strIdxEnd])) {
+                return false; // Character mismatch
+            }
+            if (!isCaseSensitive
+                    && (Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxEnd]))) {
+                return false; // Character mismatch
+            }
+            patIdxEnd--;
+            strIdxEnd--;
+        }
+        if (strIdxStart > strIdxEnd) {
+
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            for (int i = patIdxStart; i <= patIdxEnd; i++) {
+                if (patArr[i] != '*') {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // process pattern between stars. padIdxStart and patIdxEnd point
+        // always to a '*'.
+        while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
+            int patIdxTmp = -1;
+
+            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+                if (patArr[i] == '*') {
+                    patIdxTmp = i;
+                    break;
+                }
+            }
+            if (patIdxTmp == patIdxStart + 1) {
+
+                // Two stars next to each other, skip the first one.
+                patIdxStart++;
+                continue;
+            }
+
+            // Find the pattern between padIdxStart & padIdxTmp in str between
+            // strIdxStart & strIdxEnd
+            int patLength = (patIdxTmp - patIdxStart - 1);
+            int strLength = (strIdxEnd - strIdxStart + 1);
+            int foundIdx = -1;
+
+            strLoop: for (int i = 0; i <= strLength - patLength; i++) {
+                for (int j = 0; j < patLength; j++) {
+                    ch = patArr[patIdxStart + j + 1];
+                    if (isCaseSensitive && (ch != strArr[strIdxStart + i + j])) {
+                        continue strLoop;
+                    }
+                    if (!isCaseSensitive
+                            && (Character.toUpperCase(ch) != Character
+                                    .toUpperCase(strArr[strIdxStart + i + j]))) {
+                        continue strLoop;
+                    }
+                }
+                foundIdx = strIdxStart + i;
+                break;
+            }
+            if (foundIdx == -1) {
+                return false;
+            }
+            patIdxStart = patIdxTmp;
+            strIdxStart = foundIdx + patLength;
+        }
+
+        // All characters in the string are used. Check if only '*'s are left
+        // in the pattern. If so, we succeeded. Otherwise failure.
+        for (int i = patIdxStart; i <= patIdxEnd; i++) {
+            if (patArr[i] != '*') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}

Propchange: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java?rev=1332141&view=auto
==============================================================================
--- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java (added)
+++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java Mon Apr 30 10:04:10 2012
@@ -0,0 +1,997 @@
+/*
+ * 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.axis2.transport.http.impl.httpclient4;
+
+
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.context.NamedValue;
+import org.apache.axis2.context.OperationContext;
+import org.apache.axis2.i18n.Messages;
+import org.apache.axis2.transport.MessageFormatter;
+import org.apache.axis2.transport.TransportUtils;
+import org.apache.axis2.transport.http.HTTPAuthenticator;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.axis2.transport.http.HTTPSender;
+import org.apache.axis2.transport.http.HTTPTransportConstants;
+import org.apache.axis2.wsdl.WSDLConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.NTCredentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.params.AuthPolicy;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.client.AbstractHttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+
+import javax.xml.namespace.QName;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.GZIPInputStream;
+
+
+public class HTTPSenderImpl extends HTTPSender {
+
+    private static final Log log = LogFactory.getLog(HTTPSenderImpl.class);
+
+    /**
+     * Used to send a request via HTTP Get method
+     *
+     * @param msgContext        - The MessageContext of the message
+     * @param url               - The target URL
+     * @param soapActionString - The soapAction string of the request
+     * @throws org.apache.axis2.AxisFault - Thrown in case an exception occurs
+     */
+    protected void sendViaGet(MessageContext msgContext, URL url, String soapActionString)
+            throws AxisFault {
+        HttpGet httpGet = new HttpGet();
+        AbstractHttpClient httpClient = getHttpClient(msgContext);
+        MessageFormatter messageFormatter = populateCommonProperties(msgContext, url, httpGet,
+                                                                     httpClient, soapActionString);
+
+        // Need to have this here because we can have soap action when using the
+        // soap response MEP
+        String soapAction = messageFormatter
+                .formatSOAPAction(msgContext, format, soapActionString);
+
+        if (soapAction != null) {
+            httpGet.setHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
+        }
+
+        /*
+         * main execution takes place..
+         */
+        HttpResponse response = null;
+        try {
+            response = executeMethod(httpClient, msgContext, url, httpGet);
+            handleResponse(msgContext, response);
+        } catch (IOException e) {
+            log.info("Unable to sendViaGet to url[" + url + "]", e);
+            throw AxisFault.makeFault(e);
+        } finally {
+            cleanup(msgContext, response);
+        }
+    }
+
+    @Override
+    protected void cleanup(MessageContext msgContext, Object httpResponse) {
+        HttpResponse response;
+        if (httpResponse instanceof HttpResponse) {
+            response = (HttpResponse) httpResponse;
+        } else {
+            log.trace("HttpResponse expected, but found - " + httpResponse);
+            return;
+        }
+        log.trace("Cleaning response : " + response);
+        HttpEntity entity = response.getEntity();
+        if (entity != null && entity.isStreaming()) {
+            InputStream inputStream;
+            try {
+                inputStream = entity.getContent();
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (IOException e) {
+                log.error("Error while cleaning response : "+response, e);
+            }
+        }
+    }
+
+    /**
+     * Used to send a request via HTTP Delete Method
+     *
+     * @param msgContext        - The MessageContext of the message
+     * @param url               - The target URL
+     * @param soapActionString - The soapAction string of the request
+     * @throws org.apache.axis2.AxisFault - Thrown in case an exception occurs
+     */
+    protected void sendViaDelete(MessageContext msgContext, URL url, String soapActionString)
+            throws AxisFault {
+
+        HttpDelete deleteMethod = new HttpDelete();
+        AbstractHttpClient httpClient = getHttpClient(msgContext);
+        populateCommonProperties(msgContext, url, deleteMethod, httpClient, soapActionString);
+
+        /*
+         * main execution takes place..
+         */
+        HttpResponse response = null;
+        try {
+            response = executeMethod(httpClient, msgContext, url, deleteMethod);
+            handleResponse(msgContext, response);
+        } catch (IOException e) {
+            log.info("Unable to sendViaDelete to url[" + url + "]", e);
+            throw AxisFault.makeFault(e);
+        } finally {
+            cleanup(msgContext, response);
+        }
+    }
+
+    /**
+     * Used to send a request via HTTP Post Method
+     *
+     * @param msgContext       - The MessageContext of the message
+     * @param url              - The target URL
+     * @param soapActionString - The soapAction string of the request
+     * @throws org.apache.axis2.AxisFault - Thrown in case an exception occurs
+     */
+    protected void sendViaPost(MessageContext msgContext, URL url, String soapActionString)
+            throws AxisFault {
+
+        AbstractHttpClient httpClient = getHttpClient(msgContext);
+
+        /*
+         * What's up with this, it never gets used anywhere?? --Glen String
+         * charEncoding = (String)
+         * msgContext.getProperty(Constants.Configuration
+         * .CHARACTER_SET_ENCODING);
+         *
+         * if (charEncoding == null) { charEncoding =
+         * MessageContext.DEFAULT_CHAR_SET_ENCODING; }
+         */
+
+        HttpPost postMethod = new HttpPost();
+        if (log.isTraceEnabled()) {
+            log.trace(Thread.currentThread() + " PostMethod " + postMethod + " / " + httpClient);
+        }
+        MessageFormatter messageFormatter = populateCommonProperties(msgContext, url, postMethod,
+                                                                     httpClient, soapActionString);
+        AxisRequestEntityImpl requestEntity =
+                new AxisRequestEntityImpl(messageFormatter, msgContext, format,
+                                          soapActionString, chunked, isAllowedRetry);
+        postMethod.setEntity(requestEntity);
+
+        if (!httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10) && chunked) {
+            requestEntity.setChunked(chunked);
+        }
+
+        String soapAction = messageFormatter.formatSOAPAction(msgContext, format, soapActionString);
+
+        if (soapAction != null) {
+            postMethod.setHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
+        }
+
+        /*
+         * main execution takes place..
+         */
+        HttpResponse response = null;
+        try {
+            response = executeMethod(httpClient, msgContext, url, postMethod);
+            handleResponse(msgContext, response);
+        } catch (IOException e) {
+            log.info("Unable to sendViaPost to url[" + url + "]", e);
+            throw AxisFault.makeFault(e);
+        } finally {
+            cleanup(msgContext, response);
+        }
+    }
+
+    /**
+     * Used to send a request via HTTP Put Method
+     *
+     * @param msgContext       - The MessageContext of the message
+     * @param url              - The target URL
+     * @param soapActionString - The soapAction string of the request
+     * @throws org.apache.axis2.AxisFault - Thrown in case an exception occurs
+     */
+    protected void sendViaPut(MessageContext msgContext, URL url, String soapActionString)
+            throws AxisFault {
+
+        AbstractHttpClient httpClient = getHttpClient(msgContext);
+
+        /*
+         * Same deal - this value never gets used, why is it here? --Glen String
+         * charEncoding = (String)
+         * msgContext.getProperty(Constants.Configuration
+         * .CHARACTER_SET_ENCODING);
+         *
+         * if (charEncoding == null) { charEncoding =
+         * MessageContext.DEFAULT_CHAR_SET_ENCODING; }
+         */
+
+        HttpPut putMethod = new HttpPut();
+        MessageFormatter messageFormatter = populateCommonProperties(msgContext, url, putMethod,
+                                                                     httpClient, soapActionString);
+        AxisRequestEntityImpl requestEntity =
+                new AxisRequestEntityImpl(messageFormatter, msgContext, format,
+                                          soapActionString, chunked, isAllowedRetry);
+        putMethod.setEntity(requestEntity);
+
+        if (!httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10) && chunked) {
+            requestEntity.setChunked(chunked);
+        }
+
+        String soapAction = messageFormatter.formatSOAPAction(msgContext, format, soapActionString);
+        if (soapAction != null) {
+            putMethod.setHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
+        }
+
+        /*
+         * main execution takes place..
+         */
+        HttpResponse response = null;
+        try {
+            response = executeMethod(httpClient, msgContext, url, putMethod);
+            handleResponse(msgContext, response);
+        } catch (IOException e) {
+            log.info("Unable to sendViaPut to url[" + url + "]", e);
+            throw AxisFault.makeFault(e);
+        } finally {
+            cleanup(msgContext, response);
+        }
+    }
+
+    /**
+     * Used to handle the HTTP Response
+     *
+     * @param msgContext - The MessageContext of the message
+     * @param -          The HTTP method used
+     * @throws java.io.IOException - Thrown in case an exception occurs
+     */
+    protected void handleResponse(MessageContext msgContext, Object httpResponse)
+            throws IOException {
+        HttpResponse response;
+        if (httpResponse instanceof HttpResponse) {
+            response = (HttpResponse) httpResponse;
+        } else {
+            log.trace("HttpResponse expected, but found - " + httpResponse);
+            return;
+        }
+        int statusCode = response.getStatusLine().getStatusCode();
+        HTTPStatusCodeFamily family = getHTTPStatusCodeFamily(statusCode);
+        log.trace("Handling response - " + statusCode);
+        if (HTTPStatusCodeFamily.SUCCESSFUL.equals(family)) {
+            // Save the HttpMethod so that we can release the connection when
+            // cleaning up
+            // TODO : Do we need to save the http method
+//            msgContext.setProperty(HTTPConstants.HTTP_METHOD, method);
+
+            processResponse(response, msgContext);
+        } else if (statusCode == HttpStatus.SC_ACCEPTED) {
+            /*
+             * When an HTTP 202 Accepted code has been received, this will be
+             * the case of an execution of an in-only operation. In such a
+             * scenario, the HTTP response headers should be returned, i.e.
+             * session cookies.
+             */
+            obtainHTTPHeaderInformation(response.getEntity(), msgContext);
+
+        } else if (statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR
+                   || statusCode == HttpStatus.SC_BAD_REQUEST) {
+            // Save the HttpMethod so that we can release the connection when
+            // cleaning up
+//            msgContext.setProperty(HTTPConstants.HTTP_METHOD, method);
+            Header contentTypeHeader = response.getFirstHeader(HTTPConstants.HEADER_CONTENT_TYPE);
+            String value = null;
+            if (contentTypeHeader != null) {
+                value = contentTypeHeader.getValue();
+            }
+            OperationContext opContext = msgContext.getOperationContext();
+            if (opContext != null) {
+                MessageContext inMessageContext = opContext
+                        .getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+                if (inMessageContext != null) {
+                    inMessageContext.setProcessingFault(true);
+                }
+            }
+            if (value != null) {
+                processResponse(response, msgContext);
+            }
+
+            if (org.apache.axis2.util.Utils.isClientThreadNonBlockingPropertySet(msgContext)) {
+                throw new AxisFault(Messages.
+                        getMessage("transportError",
+                                   String.valueOf(statusCode),
+                                   response.getStatusLine().toString()));
+            }
+        } else {
+            throw new AxisFault(Messages.getMessage("transportError", String.valueOf(statusCode),
+                                                    response.getStatusLine().toString()));
+        }
+    }
+
+    /**
+     * Collect the HTTP header information and set them in the message context
+     *
+     * @param httpResponse which holds the header information
+     * @param msgContext the MessageContext in which to place the information... OR
+     *                   NOT!
+     * @throws AxisFault if problems occur
+     */
+    protected void obtainHTTPHeaderInformation(Object httpResponse, MessageContext msgContext)
+            throws AxisFault {
+        HttpResponse response;
+        if (httpResponse instanceof HttpResponse) {
+            response = (HttpResponse) httpResponse;
+        } else {
+            return;
+        }
+        // Set RESPONSE properties onto the REQUEST message context. They will
+        // need to be copied off the request context onto
+        // the response context elsewhere, for example in the
+        // OutInOperationClient.
+        Map transportHeaders = new HTTPTransportHeaders(response.getAllHeaders());
+        msgContext.setProperty(MessageContext.TRANSPORT_HEADERS, transportHeaders);
+        msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE,
+                               new Integer(response.getStatusLine().getStatusCode()));
+        Header header = response.getFirstHeader(HTTPConstants.HEADER_CONTENT_TYPE);
+
+        if (header != null) {
+            HeaderElement[] headers = header.getElements();
+            MessageContext inMessageContext = msgContext.getOperationContext().getMessageContext(
+                    WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+
+            Object contentType = header.getValue();
+            Object charSetEnc = null;
+
+            for (int i = 0; i < headers.length; i++) {
+                NameValuePair charsetEnc = headers[i]
+                        .getParameterByName(HTTPConstants.CHAR_SET_ENCODING);
+                if (charsetEnc != null) {
+                    charSetEnc = charsetEnc.getValue();
+                }
+            }
+
+            if (inMessageContext != null) {
+                inMessageContext.setProperty(Constants.Configuration.CONTENT_TYPE, contentType);
+                inMessageContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING,
+                                             charSetEnc);
+            } else {
+
+                // Transport details will be stored in a HashMap so that anybody
+                // interested can
+                // retrieve them
+                HashMap transportInfoMap = new HashMap();
+                transportInfoMap.put(Constants.Configuration.CONTENT_TYPE, contentType);
+                transportInfoMap.put(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEnc);
+
+                // the HashMap is stored in the outgoing message.
+                msgContext
+                        .setProperty(Constants.Configuration.TRANSPORT_INFO_MAP, transportInfoMap);
+            }
+        }
+
+        String sessionCookie = null;
+        // Process old style headers first
+        Header[] cookieHeaders = response.getHeaders(HTTPConstants.HEADER_SET_COOKIE);
+        String customCoookiId = (String) msgContext.getProperty(Constants.CUSTOM_COOKIE_ID);
+        for (int i = 0; i < cookieHeaders.length; i++) {
+            HeaderElement[] elements = cookieHeaders[i].getElements();
+            for (int e = 0; e < elements.length; e++) {
+                HeaderElement element = elements[e];
+                if (Constants.SESSION_COOKIE.equalsIgnoreCase(element.getName())
+                    || Constants.SESSION_COOKIE_JSESSIONID.equalsIgnoreCase(element.getName())) {
+                    sessionCookie = processCookieHeader(element);
+                }
+                if (customCoookiId != null && customCoookiId.equalsIgnoreCase(element.getName())) {
+                    sessionCookie = processCookieHeader(element);
+                }
+            }
+        }
+        // Overwrite old style cookies with new style ones if present
+        cookieHeaders = response.getHeaders(HTTPConstants.HEADER_SET_COOKIE2);
+        for (int i = 0; i < cookieHeaders.length; i++) {
+            HeaderElement[] elements = cookieHeaders[i].getElements();
+            for (int e = 0; e < elements.length; e++) {
+                HeaderElement element = elements[e];
+                if (Constants.SESSION_COOKIE.equalsIgnoreCase(element.getName())
+                    || Constants.SESSION_COOKIE_JSESSIONID.equalsIgnoreCase(element.getName())) {
+                    sessionCookie = processCookieHeader(element);
+                }
+                if (customCoookiId != null && customCoookiId.equalsIgnoreCase(element.getName())) {
+                    sessionCookie = processCookieHeader(element);
+                }
+            }
+        }
+
+        if (sessionCookie != null) {
+            msgContext.getServiceContext().setProperty(HTTPConstants.COOKIE_STRING, sessionCookie);
+        }
+    }
+
+    private String processCookieHeader(HeaderElement element) {
+        String cookie = element.getName() + "=" + element.getValue();
+        NameValuePair[] parameters = element.getParameters();
+        for (int j = 0; parameters != null && j < parameters.length; j++) {
+            NameValuePair parameter = parameters[j];
+            cookie = cookie + "; " + parameter.getName() + "=" + parameter.getValue();
+        }
+        return cookie;
+    }
+
+    protected void processResponse(HttpResponse response, MessageContext msgContext)
+            throws IOException {
+        obtainHTTPHeaderInformation(response, msgContext);
+
+        HttpEntity httpEntity = response.getEntity();
+        InputStream in = httpEntity.getContent();
+        if (in == null) {
+            throw new AxisFault(Messages.getMessage("canNotBeNull", "InputStream"));
+        }
+        Header contentEncoding = httpEntity.getContentEncoding();
+        if (contentEncoding != null) {
+            if (contentEncoding.getValue().equalsIgnoreCase(HTTPConstants.COMPRESSION_GZIP)) {
+                in = new GZIPInputStream(in);
+                // If the content-encoding is identity we can basically ignore
+                // it.
+            } else if (!"identity".equalsIgnoreCase(contentEncoding.getValue())) {
+                throw new AxisFault("HTTP :" + "unsupported content-encoding of '"
+                                    + contentEncoding.getValue() + "' found");
+            }
+        }
+
+        OperationContext opContext = msgContext.getOperationContext();
+        if (opContext != null) {
+            opContext.setProperty(MessageContext.TRANSPORT_IN, in);
+        }
+    }
+
+    /**
+     * getting host configuration to support standard http/s, proxy and NTLM
+     * support
+     *
+     * @param client    active HttpClient
+     * @param msgCtx    active MessageContext
+     * @param targetURL the target URL
+     * @return a HostConfiguration set up with proxy information
+     * @throws org.apache.axis2.AxisFault if problems occur
+     */
+    protected HttpHost getHostConfiguration(AbstractHttpClient client, MessageContext msgCtx,
+                                            URL targetURL) throws AxisFault {
+
+        boolean isAuthenticationEnabled = isAuthenticationEnabled(msgCtx);
+        int port = targetURL.getPort();
+
+        String protocol = targetURL.getProtocol();
+        if (port == -1) {
+            if (HTTPTransportConstants.PROTOCOL_HTTP.equals(protocol)) {
+                port = 80;
+            } else if (HTTPTransportConstants.PROTOCOL_HTTPS.equals(protocol)) {
+                port = 443;
+            }
+        }
+        // to see the host is a proxy and in the proxy list - available in
+        // axis2.xml
+        HttpHost hostConfig = new HttpHost(targetURL.getHost(), port, targetURL.getProtocol());
+
+        // TODO : one might need to set his own socket factory. We have to allow that case as well.
+
+        if (isAuthenticationEnabled) {
+            // Basic, Digest, NTLM and custom authentications.
+            this.setAuthenticationInfo(client, msgCtx);
+        }
+        // proxy configuration
+
+        if (HTTPProxyConfigurator.isProxyEnabled(msgCtx, targetURL)) {
+            if (log.isDebugEnabled()) {
+                log.debug("Configuring HTTP proxy.");
+            }
+            HTTPProxyConfigurator.configure(msgCtx, client);
+        }
+
+        return hostConfig;
+    }
+
+    protected boolean isAuthenticationEnabled(MessageContext msgCtx) {
+        return (msgCtx.getProperty(HTTPConstants.AUTHENTICATE) != null);
+    }
+
+    /*
+     * This will handle server Authentication, It could be either NTLM, Digest
+     * or Basic Authentication. Apart from that user can change the priory or
+     * add a custom authentication scheme.
+     */
+    protected void setAuthenticationInfo(AbstractHttpClient agent, MessageContext msgCtx)
+            throws AxisFault {
+        HTTPAuthenticator authenticator;
+        Object obj = msgCtx.getProperty(HTTPConstants.AUTHENTICATE);
+        if (obj != null) {
+            if (obj instanceof HTTPAuthenticator) {
+                authenticator = (HTTPAuthenticator) obj;
+
+                String username = authenticator.getUsername();
+                String password = authenticator.getPassword();
+                String host = authenticator.getHost();
+                String domain = authenticator.getDomain();
+
+                int port = authenticator.getPort();
+                String realm = authenticator.getRealm();
+
+                /* If retrying is available set it first */
+                isAllowedRetry = authenticator.isAllowedRetry();
+
+                Credentials creds;
+
+                // TODO : Set preemptive authentication, but its not recommended in HC 4
+
+                if (host != null) {
+                    if (domain != null) {
+                        /* Credentials for NTLM Authentication */
+                        //TODO : To enable NTLM we have to register the scheme with client, but it is available from 4.1 only
+//                        agent.getAuthSchemes().register("ntlm",new NTLMSchemeFactory());
+                        creds = new NTCredentials(username, password, host, domain);
+                    } else {
+                        /* Credentials for Digest and Basic Authentication */
+                        creds = new UsernamePasswordCredentials(username, password);
+                    }
+                    agent.getCredentialsProvider().
+                            setCredentials(new AuthScope(host, port, realm), creds);
+                } else {
+                    if (domain != null) {
+                        /*
+                         * Credentials for NTLM Authentication when host is
+                         * ANY_HOST
+                         */
+                        // TODO : Enable NTLM as metioned above
+                        creds = new NTCredentials(username, password, AuthScope.ANY_HOST, domain);
+                        agent.getCredentialsProvider().
+                                setCredentials(new AuthScope(AuthScope.ANY_HOST, port, realm),
+                                               creds);
+                    } else {
+                        /* Credentials only for Digest and Basic Authentication */
+                        creds = new UsernamePasswordCredentials(username, password);
+                        agent.getCredentialsProvider().
+                                setCredentials(new AuthScope(AuthScope.ANY), creds);
+                    }
+                }
+                /* Customizing the priority Order */
+                List schemes = authenticator.getAuthSchemes();
+                if (schemes != null && schemes.size() > 0) {
+                    List authPrefs = new ArrayList(3);
+                    for (int i = 0; i < schemes.size(); i++) {
+                        if (schemes.get(i) instanceof AuthPolicy) {
+                            authPrefs.add(schemes.get(i));
+                            continue;
+                        }
+                        String scheme = (String) schemes.get(i);
+                        authPrefs.add(authenticator.getAuthPolicyPref(scheme));
+
+                    }
+                    // TODO : This is available in 4.1 only
+//                    agent.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authPrefs);
+                }
+
+            } else {
+                throw new AxisFault("HttpTransportProperties.Authenticator class cast exception");
+            }
+        }
+
+    }
+
+    /**
+     * Method used to copy all the common properties
+     *
+     * @param msgContext       - The messageContext of the request message
+     * @param url              - The target URL
+     * @param httpMethod       - The http method used to send the request
+     * @param httpClient       - The httpclient used to send the request
+     * @param soapActionString - The soap action atring of the request message
+     * @return MessageFormatter - The messageFormatter for the relavent request
+     *         message
+     * @throws org.apache.axis2.AxisFault - Thrown in case an exception occurs
+     */
+    protected MessageFormatter populateCommonProperties(MessageContext msgContext, URL url,
+                                                        HttpRequestBase httpMethod,
+                                                        AbstractHttpClient httpClient,
+                                                        String soapActionString)
+            throws AxisFault {
+
+        if (isAuthenticationEnabled(msgContext)) {
+            httpMethod.getParams().setBooleanParameter(ClientPNames.HANDLE_AUTHENTICATION, true);
+        }
+
+        MessageFormatter messageFormatter = TransportUtils.getMessageFormatter(msgContext);
+
+        url = messageFormatter.getTargetAddress(msgContext, format, url);
+
+        try {
+            httpMethod.setURI(url.toURI());
+        } catch (URISyntaxException e) {
+            log.error("Error in URI : " + url, e);
+        }
+
+        httpMethod.setHeader(HTTPConstants.HEADER_CONTENT_TYPE,
+                             messageFormatter.getContentType(msgContext, format, soapActionString));
+
+        httpMethod.setHeader(HTTPConstants.HEADER_HOST, url.getHost());
+
+        if (msgContext.getOptions() != null && msgContext.getOptions().isManageSession()) {
+            // setting the cookie in the out path
+            Object cookieString = msgContext.getProperty(HTTPConstants.COOKIE_STRING);
+
+            if (cookieString != null) {
+                StringBuffer buffer = new StringBuffer();
+                buffer.append(cookieString);
+                httpMethod.setHeader(HTTPConstants.HEADER_COOKIE, buffer.toString());
+            }
+        }
+
+        if (httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10)) {
+            httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
+                                                HttpVersion.HTTP_1_0);
+        }
+        return messageFormatter;
+    }
+
+    /**
+     * This is used to get the dynamically set time out values from the message
+     * context. If the values are not available or invalid then the default
+     * values or the values set by the configuration will be used
+     *
+     * @param msgContext the active MessageContext
+     * @param httpClient
+     */
+    protected void initializeTimeouts(MessageContext msgContext, AbstractHttpClient httpClient) {
+        // If the SO_TIMEOUT of CONNECTION_TIMEOUT is set by dynamically the
+        // override the static config
+        Integer tempSoTimeoutProperty = (Integer) msgContext.getProperty(HTTPConstants.SO_TIMEOUT);
+        Integer tempConnTimeoutProperty = (Integer) msgContext
+                .getProperty(HTTPConstants.CONNECTION_TIMEOUT);
+        long timeout = msgContext.getOptions().getTimeOutInMilliSeconds();
+
+        if (tempConnTimeoutProperty != null) {
+            int connectionTimeout = tempConnTimeoutProperty.intValue();
+            // timeout for initial connection
+            httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
+                                                connectionTimeout);
+        } else {
+            // set timeout in client
+            if (timeout > 0) {
+                httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
+                                                    (int) timeout);
+            }
+        }
+
+        if (tempSoTimeoutProperty != null) {
+            int soTimeout = tempSoTimeoutProperty.intValue();
+            // SO_TIMEOUT -- timeout for blocking reads
+            httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, soTimeout);
+        } else {
+            // set timeout in client
+            if (timeout > 0) {
+                httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, (int) timeout);
+            }
+        }
+    }
+
+    /**
+     * This is used to get the dynamically set time out values from the message
+     * context. If the values are not available or invalid then the default
+     * values or the values set by the configuration will be used
+     *
+     * @param msgContext the active MessageContext
+     * @param httpMethod method
+     */
+    protected void setTimeouts(MessageContext msgContext, HttpRequestBase httpMethod) {
+        // If the SO_TIMEOUT of CONNECTION_TIMEOUT is set by dynamically the
+        // override the static config
+        Integer tempSoTimeoutProperty = (Integer) msgContext.getProperty(HTTPConstants.SO_TIMEOUT);
+        Integer tempConnTimeoutProperty = (Integer) msgContext
+                .getProperty(HTTPConstants.CONNECTION_TIMEOUT);
+        long timeout = msgContext.getOptions().getTimeOutInMilliSeconds();
+
+        if (tempConnTimeoutProperty != null) {
+            // timeout for initial connection
+            httpMethod.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
+                                                tempConnTimeoutProperty);
+        }
+
+        if (tempSoTimeoutProperty != null) {
+            // SO_TIMEOUT -- timeout for blocking reads
+            httpMethod.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,
+                                                tempSoTimeoutProperty);
+        } else {
+            // set timeout in client
+            if (timeout > 0) {
+                httpMethod.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, (int) timeout);
+            }
+        }
+    }
+
+    protected AbstractHttpClient getHttpClient(MessageContext msgContext) {
+        ConfigurationContext configContext = msgContext.getConfigurationContext();
+
+        AbstractHttpClient httpClient = (AbstractHttpClient) msgContext
+                .getProperty(HTTPConstants.CACHED_HTTP_CLIENT);
+
+        if (httpClient == null) {
+            httpClient = (AbstractHttpClient) configContext.
+                    getProperty(HTTPConstants.CACHED_HTTP_CLIENT);
+        }
+
+        if (httpClient != null) {
+            return httpClient;
+        }
+
+        synchronized (this) {
+            httpClient = (AbstractHttpClient) msgContext.
+                    getProperty(HTTPConstants.CACHED_HTTP_CLIENT);
+
+            if (httpClient == null) {
+                httpClient = (AbstractHttpClient) configContext
+                        .getProperty(HTTPConstants.CACHED_HTTP_CLIENT);
+            }
+
+            if (httpClient != null) {
+                return httpClient;
+            }
+
+            ClientConnectionManager connManager = (ClientConnectionManager) msgContext
+                    .getProperty(HTTPConstants.MULTITHREAD_HTTP_CONNECTION_MANAGER);
+            if (connManager == null) {
+                connManager = (ClientConnectionManager) msgContext
+                        .getProperty(HTTPConstants.MULTITHREAD_HTTP_CONNECTION_MANAGER);
+            }
+            if (connManager == null) {
+                // reuse HttpConnectionManager
+                synchronized (configContext) {
+                    connManager = (ClientConnectionManager) configContext
+                            .getProperty(HTTPConstants.MULTITHREAD_HTTP_CONNECTION_MANAGER);
+                    if (connManager == null) {
+                        log.trace("Making new ConnectionManager");
+                        SchemeRegistry schemeRegistry = new SchemeRegistry();
+                        schemeRegistry.register(
+                                new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+                        schemeRegistry.register(
+                                new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+
+                        connManager = new ThreadSafeClientConnManager(new BasicHttpParams(),
+                                                                      schemeRegistry);
+                        configContext.setProperty(
+                                HTTPConstants.MULTITHREAD_HTTP_CONNECTION_MANAGER, connManager);
+                    }
+                }
+            }
+            /*
+             * Create a new instance of HttpClient since the way it is used here
+             * it's not fully thread-safe.
+             */
+            httpClient = new DefaultHttpClient(connManager, null);
+
+            //We don't need to set timeout for connection manager, since we are doing it below
+            // and its enough
+
+            // Get the timeout values set in the runtime
+            initializeTimeouts(msgContext, httpClient);
+
+            return httpClient;
+        }
+    }
+
+    protected HttpResponse executeMethod(AbstractHttpClient httpClient, MessageContext msgContext,
+                                         URL url,
+                                         HttpRequestBase method) throws IOException {
+        HttpHost httpHost = this.getHostConfiguration(httpClient, msgContext, url);
+
+        // set the custom headers, if available
+        addCustomHeaders(method, msgContext);
+
+        // add compression headers if needed
+        if (msgContext.isPropertyTrue(HTTPConstants.MC_ACCEPT_GZIP)) {
+            method.addHeader(HTTPConstants.HEADER_ACCEPT_ENCODING,
+                             HTTPConstants.COMPRESSION_GZIP);
+        }
+
+        if (msgContext.isPropertyTrue(HTTPConstants.MC_GZIP_REQUEST)) {
+            method.addHeader(HTTPConstants.HEADER_CONTENT_ENCODING,
+                             HTTPConstants.COMPRESSION_GZIP);
+        }
+
+        if (msgContext.getProperty(HTTPConstants.HTTP_METHOD_PARAMS) != null) {
+            HttpParams params = (HttpParams) msgContext
+                    .getProperty(HTTPConstants.HTTP_METHOD_PARAMS);
+            method.setParams(params);
+        }
+
+        String cookiePolicy = (String) msgContext.getProperty(HTTPConstants.COOKIE_POLICY);
+        if (cookiePolicy != null) {
+            method.getParams().setParameter(ClientPNames.COOKIE_POLICY, cookiePolicy);
+        }
+
+        setTimeouts(msgContext, method);
+        HttpContext localContext = new BasicHttpContext();
+        // Why do we have add context here
+        return httpClient.execute(httpHost, method, localContext);
+    }
+
+    public void addCustomHeaders(HttpRequestBase method, MessageContext msgContext) {
+
+        boolean isCustomUserAgentSet = false;
+        // set the custom headers, if available
+        Object httpHeadersObj = msgContext.getProperty(HTTPConstants.HTTP_HEADERS);
+        if (httpHeadersObj != null) {
+            if (httpHeadersObj instanceof List) {
+                List httpHeaders = (List) httpHeadersObj;
+                for (int i = 0; i < httpHeaders.size(); i++) {
+                    NamedValue nv = (NamedValue) httpHeaders.get(i);
+                    if (nv != null) {
+                        Header header = new BasicHeader(nv.getName(), nv.getValue());
+                        if (HTTPConstants.HEADER_USER_AGENT.equals(header.getName())) {
+                            isCustomUserAgentSet = true;
+                        }
+                        method.addHeader(header);
+                    }
+                }
+
+            }
+            if (httpHeadersObj instanceof Map) {
+                Map httpHeaders = (Map) httpHeadersObj;
+                for (Iterator iterator = httpHeaders.entrySet().iterator(); iterator.hasNext(); ) {
+                    Map.Entry entry = (Map.Entry) iterator.next();
+                    String key = (String) entry.getKey();
+                    String value = (String) entry.getValue();
+                    if (HTTPConstants.HEADER_USER_AGENT.equals(key)) {
+                        isCustomUserAgentSet = true;
+                    }
+                    method.addHeader(key, value);
+                }
+            }
+        }
+
+        // we have to consider the TRANSPORT_HEADERS map as well
+        Map transportHeaders = (Map) msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
+        if (transportHeaders != null) {
+            removeUnwantedHeaders(msgContext);
+
+            Set headerEntries = transportHeaders.entrySet();
+
+            for (Object headerEntry : headerEntries) {
+                if (headerEntry instanceof Map.Entry) {
+                    Header[] headers = method.getAllHeaders();
+
+                    boolean headerAdded = false;
+                    for (Header header : headers) {
+                        if (header.getName() != null
+                            && header.getName().equals(((Map.Entry) headerEntry).getKey())) {
+                            headerAdded = true;
+                            break;
+                        }
+                    }
+
+                    if (!headerAdded) {
+                        method.addHeader(((Map.Entry) headerEntry).getKey().toString(),
+                                         ((Map.Entry) headerEntry).getValue().toString());
+                    }
+                }
+            }
+        }
+
+        if (!isCustomUserAgentSet) {
+            String userAgentString = getUserAgent(msgContext);
+            method.setHeader(HTTPConstants.HEADER_USER_AGENT, userAgentString);
+        }
+
+    }
+
+    /**
+     * Remove unwanted headers from the transport headers map of outgoing
+     * request. These are headers which should be dictated by the transport and
+     * not the user. We remove these as these may get copied from the request
+     * messages
+     *
+     * @param msgContext the Axis2 Message context from which these headers should be
+     *                   removed
+     */
+    private void removeUnwantedHeaders(MessageContext msgContext) {
+        Map headers = (Map) msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
+
+        if (headers == null || headers.isEmpty()) {
+            return;
+        }
+
+        Iterator iter = headers.keySet().iterator();
+        while (iter.hasNext()) {
+            String headerName = (String) iter.next();
+            if (HTTP.CONN_DIRECTIVE.equalsIgnoreCase(headerName)
+                || HTTP.TRANSFER_ENCODING.equalsIgnoreCase(headerName)
+                || HTTP.DATE_HEADER.equalsIgnoreCase(headerName)
+                || HTTP.CONTENT_TYPE.equalsIgnoreCase(headerName)
+                || HTTP.CONTENT_LEN.equalsIgnoreCase(headerName)) {
+                iter.remove();
+            }
+        }
+    }
+
+    private String getUserAgent(MessageContext messageContext) {
+        String userAgentString = "Axis2";
+        boolean locked = false;
+        if (messageContext.getParameter(HTTPConstants.USER_AGENT) != null) {
+            OMElement userAgentElement = messageContext.getParameter(HTTPConstants.USER_AGENT)
+                    .getParameterElement();
+            userAgentString = userAgentElement.getText().trim();
+            OMAttribute lockedAttribute = userAgentElement.getAttribute(new QName("locked"));
+            if (lockedAttribute != null) {
+                if (lockedAttribute.getAttributeValue().equalsIgnoreCase("true")) {
+                    locked = true;
+                }
+            }
+        }
+        // Runtime overing part
+        if (!locked) {
+            if (messageContext.getProperty(HTTPConstants.USER_AGENT) != null) {
+                userAgentString = (String) messageContext.getProperty(HTTPConstants.USER_AGENT);
+            }
+        }
+
+        return userAgentString;
+    }
+
+}

Propchange: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPClient4SenderTest.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPClient4SenderTest.java?rev=1332141&view=auto
==============================================================================
--- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPClient4SenderTest.java (added)
+++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPClient4SenderTest.java Mon Apr 30 10:04:10 2012
@@ -0,0 +1,178 @@
+/*
+* 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.axis2.transport.http;
+
+import org.apache.axis2.Constants;
+import org.apache.axis2.transport.http.impl.httpclient4.HTTPSenderImpl;
+
+import javax.ws.rs.core.HttpHeaders;
+
+public class HTTPClient4SenderTest extends HTTPSenderTest {
+
+    @Override
+    protected HTTPSender getHTTPSender() {
+        return new HTTPSenderImpl();
+    }
+
+    @Override
+    public void testSendViaGet() throws Exception {
+        int port = getBasicHttpServer().getPort();
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_GET, "urn:getService", "http://localhost:"
+                                                                               + port + "/getService", true);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_GET,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", "/getService?part=sample%20data",
+                     getStringContent());
+        assertEquals("Not the expected HTTP Header value", "urn:getService",
+                     getHeaders().get("SOAPAction"));
+        assertEquals("Not the expected HTTP Header value",
+                     "application/x-www-form-urlencoded;action=\"urn:getService\";",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+    }
+
+    @Override
+    public void testSendViaPost() throws Exception {
+        // test with REST payload
+        int port = getBasicHttpServer().getPort();
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_POST, "urn:postService",
+                    "http://localhost:" + port + "/postService", true);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_POST,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", getEnvelope().getFirstElement().getFirstElement()
+                .toString(), getStringContent());
+        assertEquals("Not the expected HTTP Header value", "urn:postService",
+                     getHeaders().get("SOAPAction"));
+        assertEquals("Not the expected HTTP Header value", "application/xml",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+
+        // test with SOAP payload.
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_POST, "urn:postService",
+                    "http://localhost:" + port + "/postService", false);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_POST,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", getEnvelope().toString(), getStringContent());
+        assertEquals("Not the expected HTTP Header value", "urn:postService",
+                     getHeaders().get("SOAPAction").replace("\"", ""));
+        assertEquals("Not the expected HTTP Header value", "text/xml",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+    }
+
+    @Override
+    public void testSendViaPut() throws Exception {
+        // test with REST payload
+        int port = getBasicHttpServer().getPort();
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_PUT, "urn:putService", "http://localhost:"
+                                                                               + port + "/putService", true);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_PUT,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", getEnvelope().getFirstElement().getFirstElement()
+                .toString(), getStringContent());
+        assertEquals("Not the expected HTTP Header value", "urn:putService",
+                     getHeaders().get("SOAPAction"));
+        assertEquals("Not the expected HTTP Header value", "application/xml",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+
+        // test with SOAP payload.
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_PUT, "urn:putService", "http://localhost:"
+                                                                               + port + "/putService", false);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_PUT,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", getEnvelope().toString(), getStringContent());
+        assertEquals("Not the expected HTTP Header value", "urn:putService",
+                     getHeaders().get("SOAPAction").replace("\"", ""));
+        assertEquals("Not the expected HTTP Header value", "text/xml",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+    }
+
+    @Override
+    public void testSendViaDelete() throws Exception {
+        // test with REST payload
+        int port = getBasicHttpServer().getPort();
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_DELETE, "urn:deleteService",
+                    "http://localhost:" + port + "/deleteService", true);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_DELETE,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", "/deleteService?part=sample%20data",
+                     getStringContent());
+        assertEquals("Not the expected HTTP Header value",
+                     "application/x-www-form-urlencoded;action=\"urn:deleteService\";", getHeaders()
+                .get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+    }
+
+    @Override
+    public void testSendViaHead() throws Exception {
+        int port = getBasicHttpServer().getPort();
+        sendViaHTTP(Constants.Configuration.HTTP_METHOD_HEAD, "urn:deleteService",
+                    "http://localhost:" + port + "/deleteService", true);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_POST,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", getEnvelope().getFirstElement().getFirstElement()
+                .toString(), getStringContent());
+        assertEquals("Not the expected HTTP Header value", "application/xml",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+
+    }
+
+    @Override
+    public void testSendNOHTTPMethod() throws Exception {
+        int port = getBasicHttpServer().getPort();
+        sendViaHTTP(null, "urn:noService", "http://localhost:" + port + "/noService", true);
+        assertEquals("Not the expected HTTP Method", Constants.Configuration.HTTP_METHOD_POST,
+                     getHTTPMethod());
+        assertEquals("Not the expected content", getEnvelope().getFirstElement().getFirstElement()
+                .toString(), getStringContent());
+        assertEquals("Not the expected HTTP Header value", "urn:noService",
+                     getHeaders().get("SOAPAction"));
+        assertEquals("Not the expected HTTP Header value", "application/xml",
+                     getHeaders().get(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Not the expected HTTP Header value", "localhost",
+                     getHeaders().get(HttpHeaders.HOST));
+        assertEquals("Not the expected HTTP Header value", "Axis2",
+                     getHeaders().get(HttpHeaders.USER_AGENT));
+    }
+}

Propchange: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPClient4SenderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPSenderTest.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPSenderTest.java?rev=1332141&r1=1332140&r2=1332141&view=diff
==============================================================================
--- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPSenderTest.java (original)
+++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/test/org/apache/axis2/transport/http/HTTPSenderTest.java Mon Apr 30 10:04:10 2012
@@ -19,12 +19,6 @@
 
 package org.apache.axis2.transport.http;
 
-import java.io.IOException;
-import java.net.URL;
-
-import javax.mail.MessagingException;
-import javax.ws.rs.core.HttpHeaders;
-
 import org.apache.axis2.Constants;
 import org.apache.axis2.context.ConfigurationContext;
 import org.apache.axis2.context.ConfigurationContextFactory;
@@ -33,6 +27,11 @@ import org.apache.axis2.context.Operatio
 import org.apache.axis2.transport.http.mock.server.AbstractHTTPServerTest;
 import org.apache.axis2.transport.http.mock.server.BasicHttpServer;
 
+import javax.mail.MessagingException;
+import javax.ws.rs.core.HttpHeaders;
+import java.io.IOException;
+import java.net.URL;
+
 /**
  * The Class HTTPSenderTest.
  */
@@ -58,7 +57,7 @@ public abstract class HTTPSenderTest ext
      * @throws MessagingException
      *             the messaging exception
      */
-    private void sendViaHTTP(String httpMethod, String soapAction, String address, boolean rest)
+    protected void sendViaHTTP(String httpMethod, String soapAction, String address, boolean rest)
             throws IOException, MessagingException {
         httpSender = getHTTPSender();
         MessageContext msgContext = new MessageContext();