/*
* $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/oac.hc3x/tags/HTTPCLIENT_3_1/src/contrib/org/apache/commons/httpclient/contrib/proxy/PluginProxyUtil.java $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.httpclient.contrib.proxy;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Properties;
import org.apache.commons.httpclient.ProxyHost;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
A utility class that gives applets the ability to detect proxy host settings.
This was adapted from a post from Chris Forster on 20030227 to a Sun Java
forum here:
http://forum.java.sun.com/thread.jspa?threadID=364342&tstart=120
The algorithm - which relies on Sun java plugin internal classes in some
cases - was maintained, but the following changes were made:
1. Logging was used to allow control of debug type messages.
2. Reflection is used instead of direct references to Sun internal classes
to avoid the need to have these classes in the CLASSPATH to compile.
3. Removed the use of global variables to allow this class to be used in
a multi-threaded environment.
4. Add the use of exception to indicate to the caller when proxy detection
failed as opposed to when no proxy is configured.
DISCLAIMER: HttpClient developers DO NOT actively support this component.
The component is provided as a reference material, which may be inappropriate
for use without additional customization.
/**
* A utility class that gives applets the ability to detect proxy host settings.
* This was adapted from a post from Chris Forster on 20030227 to a Sun Java
* forum here:
* http://forum.java.sun.com/thread.jspa?threadID=364342&tstart=120
*
* The algorithm - which relies on Sun java plugin internal classes in some
* cases - was maintained, but the following changes were made:
*
* 1. Logging was used to allow control of debug type messages.
* 2. Reflection is used instead of direct references to Sun internal classes
* to avoid the need to have these classes in the CLASSPATH to compile.
* 3. Removed the use of global variables to allow this class to be used in
* a multi-threaded environment.
* 4. Add the use of exception to indicate to the caller when proxy detection
* failed as opposed to when no proxy is configured.
*
* <p>
* DISCLAIMER: HttpClient developers DO NOT actively support this component.
* The component is provided as a reference material, which may be inappropriate
* for use without additional customization.
* </p>
*/
public class PluginProxyUtil {
Log object for this class /** Log object for this class */
private static final Log LOG = LogFactory.getLog(PluginProxyUtil.class);
This is used internally to indicate that no proxy detection succeeded
and no proxy setting is to be used - failover is unnecessary
/**
* This is used internally to indicate that no proxy detection succeeded
* and no proxy setting is to be used - failover is unnecessary
*/
private static final ProxyHost NO_PROXY_HOST = new ProxyHost("",80);
The system property that is used to convey proxy information in some VM's
/**
* The system property that is used to convey proxy information in some VM's
*/
private static final String PLUGIN_PROXY_CONFIG_PROP =
"javaplugin.proxy.config.list";
Returns the Proxy Host information using settings from the java plugin.
Params: - sampleURL – the url target for which proxy host information is
required
Throws: - ProxyDetectionException – if detection failed
Returns: the proxy host info (name and port) or null if a direct
connection is allowed to the target url.
/**
* Returns the Proxy Host information using settings from the java plugin.
*
* @param sampleURL the url target for which proxy host information is
* required
* @return the proxy host info (name and port) or null if a direct
* connection is allowed to the target url.
* @throws ProxyDetectionException if detection failed
*/
public static ProxyHost detectProxy(URL sampleURL)
throws ProxyDetectionException
{
ProxyHost result = null;
String javaVers = System.getProperty("java.runtime.version");
if (LOG.isDebugEnabled()) {
LOG.debug("About to attempt auto proxy detection under Java " +
"version:"+javaVers);
}
// If specific, known detection methods fail may try fallback
// detection method
boolean invokeFailover = false;
if (javaVers.startsWith("1.3")) {
result = detectProxySettingsJDK13(sampleURL);
if (result == null) {
invokeFailover = true;
}
} else if (javaVers.startsWith("1.4") || (javaVers.startsWith("1.5") || javaVers.startsWith("1.6"))) {
result = detectProxySettingsJDK14_JDK15_JDK16(sampleURL);
if (result == null) {
invokeFailover = true;
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Sun Plugin reported java version not 1.3.X, " +
"1.4.X, 1.5.X or 1.6.X - trying failover detection...");
}
invokeFailover = true;
}
if (invokeFailover) {
if (LOG.isDebugEnabled()) {
LOG.debug("Using failover proxy detection...");
}
result = getPluginProxyConfigSettings();
}
if (NO_PROXY_HOST.equals(result)) {
result = null;
}
return result;
}
Use Sun-specific internal plugin proxy classes for 1.3.X
Look around for the 1.3.X plugin proxy detection class. Without it,
cannot autodetect...
Params: - sampleURL – the URL to check proxy settings for
Throws: - ProxyDetectionException – if detection failed
Returns: ProxyHost the host and port of the proxy that should be used
/**
* Use Sun-specific internal plugin proxy classes for 1.3.X
* Look around for the 1.3.X plugin proxy detection class. Without it,
* cannot autodetect...
*
* @param sampleURL the URL to check proxy settings for
* @return ProxyHost the host and port of the proxy that should be used
* @throws ProxyDetectionException if detection failed
*/
private static ProxyHost detectProxySettingsJDK13(URL sampleURL)
throws ProxyDetectionException
{
ProxyHost result = null;
try {
// Attempt to discover proxy info by asking internal plugin
// code to locate proxy path to server sampleURL...
Class pluginProxyHandler =
Class.forName("sun.plugin.protocol.PluginProxyHandler");
Method getDefaultProxyHandlerMethod =
pluginProxyHandler.getDeclaredMethod("getDefaultProxyHandler",
null);
Object proxyHandlerObj =
getDefaultProxyHandlerMethod.invoke(null, null);
if (proxyHandlerObj != null) {
Class proxyHandlerClass = proxyHandlerObj.getClass();
Method getProxyInfoMethod =
proxyHandlerClass.getDeclaredMethod("getProxyInfo",
new Class[]{URL.class});
Object proxyInfoObject =
getProxyInfoMethod.invoke(proxyHandlerObj,
new Object[] { sampleURL });
if (proxyInfoObject != null) {
Class proxyInfoClass = proxyInfoObject.getClass();
Method getProxyMethod =
proxyInfoClass.getDeclaredMethod("getProxy", null);
boolean useProxy =
(getProxyMethod.invoke(proxyInfoObject, null) != null);
if (useProxy) {
String proxyIP =
(String)getProxyMethod.invoke(proxyInfoObject, null);
Method getProxyPortMethod =
proxyInfoClass.getDeclaredMethod("getPort", null);
Integer portInteger =
(Integer)getProxyPortMethod.invoke(proxyInfoObject, null);
int proxyPort = portInteger.intValue();
if (LOG.isDebugEnabled()) {
LOG.debug("1.3.X: proxy=" + proxyIP+
" port=" + proxyPort);
}
result = new ProxyHost(proxyIP, proxyPort);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("1.3.X reported NULL for " +
"proxyInfo.getProxy (no proxy assumed)");
}
result = NO_PROXY_HOST;
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("NULL proxyInfo in 1.3.X auto proxy " +
"detection, (no proxy assumed)");
}
result = NO_PROXY_HOST;
}
} else {
throw new ProxyDetectionException(
"Sun Plugin 1.3.X failed to provide a default proxy handler");
}
} catch (Exception e) {
LOG.warn("Sun Plugin 1.3.X proxy detection class not " +
"found, will try failover detection, e:"+e);
}
return result;
}
Returns the proxy information for the specified sampleURL using JRE 1.4
specific plugin classes.
Notes:
Plugin 1.4 Final added
com.sun.java.browser.net.* classes ProxyInfo & ProxyService...
Use those with JREs => 1.4
Params: - sampleURL – the URL to check proxy settings for
Returns: ProxyHost the host and port of the proxy that should be used
/**
* Returns the proxy information for the specified sampleURL using JRE 1.4
* specific plugin classes.
*
* Notes:
* Plugin 1.4 Final added
* com.sun.java.browser.net.* classes ProxyInfo & ProxyService...
* Use those with JREs => 1.4
*
* @param sampleURL the URL to check proxy settings for
* @return ProxyHost the host and port of the proxy that should be used
*/
private static ProxyHost detectProxySettingsJDK14_JDK15_JDK16(URL sampleURL) {
ProxyHost result = null;
try {
// Look around for the 1.4.X plugin proxy detection class...
// Without it, cannot autodetect...
Class ProxyServiceClass =
Class.forName("com.sun.java.browser.net.ProxyService");
Method getProxyInfoMethod =
ProxyServiceClass.getDeclaredMethod("getProxyInfo",
new Class[] {URL.class});
Object proxyInfoArrayObj =
getProxyInfoMethod.invoke(null, new Object[] {sampleURL});
if (proxyInfoArrayObj == null
|| Array.getLength(proxyInfoArrayObj) == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("1.4.X reported NULL proxy (no proxy assumed)");
}
result = NO_PROXY_HOST;
} else {
Object proxyInfoObject = Array.get(proxyInfoArrayObj, 0);
Class proxyInfoClass = proxyInfoObject.getClass();
Method getHostMethod =
proxyInfoClass.getDeclaredMethod("getHost",null);
String proxyIP =
(String)getHostMethod.invoke(proxyInfoObject, null);
Method getPortMethod =
proxyInfoClass.getDeclaredMethod("getPort",null);
Integer portInteger =
(Integer)getPortMethod.invoke(proxyInfoObject, null);
int proxyPort = portInteger.intValue();
if (LOG.isDebugEnabled()) {
LOG.debug("1.4.X Proxy info geProxy:"+proxyIP+
" get Port:"+proxyPort);
}
result = new ProxyHost(proxyIP, proxyPort);
}
} catch (Exception e) {
e.printStackTrace();
LOG.warn("Sun Plugin 1.4.X proxy detection class not found, " +
"will try failover detection, e:"+e);
}
return result;
}
Returns the proxy host information found by inspecting the system
property "javaplugin.proxy.config.list".
Throws: - ProxyDetectionException – if an exception is encountered while
parsing the value of
PLUGIN_PROXY_CONFIG_PROP
Returns: ProxyHost the host and port of the proxy that should be used
/**
* Returns the proxy host information found by inspecting the system
* property "javaplugin.proxy.config.list".
*
* @return ProxyHost the host and port of the proxy that should be used
* @throws ProxyDetectionException if an exception is encountered while
* parsing the value of
* PLUGIN_PROXY_CONFIG_PROP
*/
private static ProxyHost getPluginProxyConfigSettings()
throws ProxyDetectionException
{
ProxyHost result = null;
try {
Properties properties = System.getProperties();
String proxyList =
properties.getProperty("javaplugin.proxy.config.list");
if (LOG.isDebugEnabled()) {
LOG.debug("Plugin Proxy Config List Property:"+proxyList);
}
boolean useProxy = (proxyList != null);
if (useProxy) {
proxyList = proxyList.toUpperCase();
// Using HTTP proxy as proxy for HTTP proxy tunnelled SSL
// socket (should be listed FIRST)....
// 1/14/03 1.3.1_06 appears to omit HTTP portion of
// reported proxy list... Mod to accomodate this...
// Expecting proxyList of "HTTP=XXX.XXX.XXX.XXX:Port" OR
// "XXX.XXX.XXX.XXX:Port" & assuming HTTP...
String proxyIP="";
if (proxyList.indexOf("HTTP=") > -1) {
proxyIP =
proxyList.substring(proxyList.indexOf("HTTP=")+5,
proxyList.indexOf(":"));
} else {
proxyIP = proxyList.substring(0, proxyList.indexOf(":"));
}
int endOfPort = proxyList.indexOf(",");
if (endOfPort < 1) endOfPort = proxyList.length();
String portString =
proxyList.substring(proxyList.indexOf(":")+1,endOfPort);
int proxyPort = Integer.parseInt(portString);
if (LOG.isDebugEnabled()) {
LOG.debug("proxy " + proxyIP+" port " + proxyPort);
}
result = new ProxyHost(proxyIP, proxyPort);
} else {
LOG.debug("No configured plugin proxy list");
result = NO_PROXY_HOST;
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Exception during failover auto proxy detection, " +
", e:"+e);
throw new ProxyDetectionException(
"Encountered unexpected exception while attempting " +
"to parse proxy information stored in "+
PLUGIN_PROXY_CONFIG_PROP, e);
}
}
return result;
}
}