All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.markusbernhardt.proxy.selector.pac.PacProxySelector Maven / Gradle / Ivy

Go to download

Proxy Vole is a Java library to auto detect the platform network proxy settings.

There is a newer version: 1.0.5
Show newest version
package com.github.markusbernhardt.proxy.selector.pac;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import com.github.markusbernhardt.proxy.util.Logger;
import com.github.markusbernhardt.proxy.util.ProxyUtil;
import com.github.markusbernhardt.proxy.util.Logger.LogLevel;

/*****************************************************************************
 * ProxySelector that will use a PAC script to find an proxy for a given URI.
 *
 * @author Bernd Rosstauscher ([email protected]) Copyright 2009
 ****************************************************************************/
public class PacProxySelector extends ProxySelector {

    // private static final String PAC_PROXY = "PROXY";
    private static final String PAC_SOCKS = "SOCKS";
    private static final String PAC_DIRECT = "DIRECT";

    private PacScriptParser pacScriptParser;

    private static volatile boolean enabled = true;

    /*************************************************************************
     * Constructor
     * 
     * @param pacSource
     *            the source for the PAC file.
     ************************************************************************/

    public PacProxySelector(PacScriptSource pacSource) {
        super();
        selectEngine(pacSource);
    }

    /*************************************************************************
     * Can be used to enable / disable the proxy selector. If disabled it will
     * return DIRECT for all urls.
     * 
     * @param enable
     *            the new status to set.
     ************************************************************************/

    public static void setEnabled(boolean enable) {
        enabled = enable;
    }

    /*************************************************************************
     * Checks if the selector is currently enabled.
     * 
     * @return true if enabled else false.
     ************************************************************************/

    public static boolean isEnabled() {
        return enabled;
    }

    /*************************************************************************
     * Selects one of the available PAC parser engines.
     * 
     * @param pacSource
     *            to use as input.
     ************************************************************************/

    private void selectEngine(PacScriptSource pacSource) {
        try {
            Logger.log(getClass(), LogLevel.INFO, "Using javax.script JavaScript engine.");
            this.pacScriptParser = new JavaxPacScriptParser(pacSource);
        } catch (Exception e) {
            Logger.log(getClass(), LogLevel.ERROR, "PAC parser error.", e);
        }
    }

    /*************************************************************************
     * connectFailed
     * 
     * @see java.net.ProxySelector#connectFailed(java.net.URI,
     *      java.net.SocketAddress, java.io.IOException)
     ************************************************************************/
    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
        // Not used.
    }

    /*************************************************************************
     * select
     * 
     * @see java.net.ProxySelector#select(java.net.URI)
     ************************************************************************/
    @Override
    public List select(URI uri) {
        if (uri == null) {
            throw new IllegalArgumentException("URI must not be null.");
        }

        // Fix for Java 1.6.16+ where we get a infinite loop because
        // URL.connect(Proxy.NO_PROXY) does not work as expected.
        if (!enabled) {
            return ProxyUtil.noProxyList();
        }

        return findProxy(uri);
    }

    /*************************************************************************
     * Evaluation of the given URL with the PAC-file.
     * 
     * Two cases can be handled here: DIRECT Fetch the object directly from the
     * content HTTP server denoted by its URL PROXY name:port Fetch the object
     * via the proxy HTTP server at the given location (name and port)
     * 
     * @param uri
     *            URI to be evaluated.
     * @return Proxy-object list as result of the evaluation.
     ************************************************************************/

    private List findProxy(URI uri) {
        try {
            List proxies = new ArrayList();
            String parseResult = this.pacScriptParser.evaluate(uri.toString(), uri.getHost());
            String[] proxyDefinitions = parseResult.split("[;]");
            for (String proxyDef : proxyDefinitions) {
                if (proxyDef.trim().length() > 0) {
                    proxies.add(buildProxyFromPacResult(proxyDef));
                }
            }
            return proxies;
        } catch (ProxyEvaluationException e) {
            Logger.log(getClass(), LogLevel.ERROR, "PAC resolving error.", e);
            return ProxyUtil.noProxyList();
        }
    }

    /*************************************************************************
     * The proxy evaluator will return a proxy string. This method will take
     * this string and build a matching Proxy for it.
     * 
     * @param pacResult
     *            the result from the PAC parser.
     * @return a Proxy
     ************************************************************************/

    private Proxy buildProxyFromPacResult(String pacResult) {
        if (pacResult == null || pacResult.trim().length() < 6) {
            return Proxy.NO_PROXY;
        }
        String proxyDef = pacResult.trim();
        if (proxyDef.toUpperCase().startsWith(PAC_DIRECT)) {
            return Proxy.NO_PROXY;
        }

        // Check proxy type.
        Proxy.Type type = Proxy.Type.HTTP;
        if (proxyDef.toUpperCase().startsWith(PAC_SOCKS)) {
            type = Proxy.Type.SOCKS;
        }

        String host = proxyDef.substring(6);
        Integer port = ProxyUtil.DEFAULT_PROXY_PORT;

        // Split port from host
        int indexOfPort = host.indexOf(':');
        int index2 = host.lastIndexOf(']');
        if (indexOfPort != -1 && index2 < indexOfPort) {
            port = Integer.parseInt(host.substring(indexOfPort + 1).trim());
            host = host.substring(0, indexOfPort).trim();
        }

        SocketAddress adr = InetSocketAddress.createUnresolved(host, port);
        return new Proxy(type, adr);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy