blob: 64bd9e71568ee00a65552fa18efc09c4cca27311 [file] [log] [blame]
/*
* 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 java.net.URL;
import java.util.StringTokenizer;
import javax.xml.namespace.QName;
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;
/**
* @deprecated use {@link HTTPProxyConfigurator}
*/
@Deprecated
public class HTTPProxcyConfigurator {
private static Log log = LogFactory.getLog(HTTPProxcyConfigurator.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 = "";
}
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) {
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;
}
}