Package org.apache.commons.httpclient.contrib.proxy

Source Code of org.apache.commons.httpclient.contrib.proxy.PluginProxyUtil

/*
* $HeadURL: https://svn.apache.org/repos/asf/jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/proxy/PluginProxyUtil.java $
* $Revision: 219776 $
* $Date: 2005-07-19 23:16:56 +0200 (Tue, 19 Jul 2005) $
*
* ====================================================================
*
*  Copyright 1999-2004 The Apache Software Foundation
*
*  Licensed 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.
*   
* <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 */
    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
     */
    private static final ProxyHost NO_PROXY_HOST = new ProxyHost("",80);
   
    /**
     * 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.
     *
     * @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"))  {
            result = detectProxySettingsJDK14(sampleURL);
            if (result == null) {
                invokeFailover = true;
            }
        } else if (javaVers.startsWith("1.5"))  {
            invokeFailover = true;
        } else {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Sun Plugin reported java version not 1.3.X, " +
                          "1.4.X or 1.5.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...
     *
     * @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
     *
     * @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(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) {
            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".
     *
     * @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;
    }   
}
TOP

Related Classes of org.apache.commons.httpclient.contrib.proxy.PluginProxyUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.