Author: sagara Date: Tue May 8 06:52:55 2012 New Revision: 1335355 URL: http://svn.apache.org/viewvc?rev=1335355&view=rev Log: Applied latest patch.
Added: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPProxyConfigurator.java (with props) Modified: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java 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/httpclient3/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/httpclient3/HTTPProxyConfigurator.java?rev=1335355&view=auto ============================================================================== --- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPProxyConfigurator.java (added) +++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPProxyConfigurator.java Tue May 8 06:52:55 2012 @@ -0,0 +1,463 @@ +/* + * 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.httpclient3; + +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.httpclient.Credentials; +import org.apache.commons.httpclient.HostConfiguration; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpState; +import org.apache.commons.httpclient.NTCredentials; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +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 + * commons-httpclient instance + * @param config + * commons-httpclient HostConfiguration + * @throws AxisFault + * if Proxy settings are invalid + */ + public static void configure(MessageContext messageContext, HttpClient httpClient, + HostConfiguration config) 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 = ""; + } + + proxyCredentials = new UsernamePasswordCredentials(proxyUser, 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); + } + } + + } + + } + + // 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) { + httpClient.getParams().setAuthenticationPreemptive(true); + HttpState cachedHttpState = (HttpState) messageContext + .getProperty(HTTPConstants.CACHED_HTTP_STATE); + if (cachedHttpState != null) { + httpClient.setState(cachedHttpState); + } + httpClient.getState().setProxyCredentials(AuthScope.ANY, proxyCredentials); + } + config.setProxy(proxyHost, proxyPort); + } + + 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/httpclient3/HTTPProxyConfigurator.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/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/httpclient3/HTTPSenderImpl.java?rev=1335355&r1=1335354&r2=1335355&view=diff ============================================================================== --- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java (original) +++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java Tue May 8 06:52:55 2012 @@ -538,11 +538,11 @@ public class HTTPSenderImpl extends HTTP } // proxy configuration - if (HTTPProxcyConfigurator.isProxyEnabled(msgCtx, targetURL)) { + if (HTTPProxyConfigurator.isProxyEnabled(msgCtx, targetURL)) { if (log.isDebugEnabled()) { log.debug("Configuring HTTP proxy."); } - HTTPProxcyConfigurator.configure(msgCtx, client, config); + HTTPProxyConfigurator.configure(msgCtx, client, config); } return config; Modified: 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=1335355&r1=1335354&r2=1335355&view=diff ============================================================================== --- axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java (original) +++ axis/axis2/java/core/branches/AXIS2-4318/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java Tue May 8 06:52:55 2012 @@ -87,6 +87,9 @@ public class HTTPProxyConfigurator { if (proxyPassword == null) { proxyPassword = ""; } + + proxyCredentials = new UsernamePasswordCredentials(proxyUser, proxyPassword); + int proxyUserDomainIndex = proxyUser.indexOf("\\"); if (proxyUserDomainIndex > 0) { String domain = proxyUser.substring(0, proxyUserDomainIndex); @@ -96,9 +99,7 @@ public class HTTPProxyConfigurator { domain); } } - proxyCredentials = new UsernamePasswordCredentials(proxyUser, proxyPassword); } - } // If there is runtime proxy settings, these settings will override