ProxySelector.java 10 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.commons.logging.Log
 *  org.apache.commons.logging.LogFactory
 */
package com.day.commons.httpclient.impl;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.ProxyHost;
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 org.apache.sling.commons.osgi.OsgiUtil;

final class ProxySelector {
    public static final String PROP_PROXY_ENABLED = "proxy.enabled";
    public static final boolean DEFAULT_PROXY_ENABLED = false;
    public static final String PROP_PROXY_HOST = "proxy.host";
    public static final String DEFAULT_PROXY_HOST = null;
    public static final String PROP_PROXY_EXCEPTIONS = "proxy.exceptions";
    public static final String[] DEFAULT_PROXY_EXCEPTIONS = new String[]{"localhost", "127.0.0.1"};
    public static final String PROP_PROXY_USERNAME = "proxy.user";
    public static final String DEFAULT_PROXY_USERNAME = null;
    public static final String PROP_PROXY_PASSWORD = "proxy.password";
    public static final String DEFAULT_PROXY_PASSWORD = null;
    public static final String PROP_PROXY_NTLM_HOST = "proxy.ntlm.host";
    public static final String DEFAULT_PROXY_NTLM_HOST = null;
    public static final String PROP_PROXY_NTLM_DOMAIN = "proxy.ntlm.domain";
    public static final String DEFAULT_PROXY_NTLM_DOMAIN = null;
    public static final ProxyHost NULL_PROXY = new ProxyHost("", -1){};
    static final Pattern IP_MASK_PATTERN = Pattern.compile("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})(/(\\d{1,2}))?");
    private final Log log;
    private boolean proxyEnabled;
    private ProxyHost proxyHost;
    private AuthScope proxyAuthScope;
    private Credentials proxyCredentials;
    private HostMatcher[] exceptions;

    ProxySelector() {
        this.log = LogFactory.getLog(this.getClass());
        this.proxyEnabled = false;
        this.proxyHost = NULL_PROXY;
        this.exceptions = new HostMatcher[0];
    }

    final void configure(Dictionary properties) {
        if (properties != null) {
            boolean pEnabled = OsgiUtil.toBoolean(properties.get("proxy.enabled"), false);
            this.setProxyEnabled(pEnabled);
            this.setProxyHost(pEnabled ? OsgiUtil.toString(properties.get("proxy.host"), DEFAULT_PROXY_HOST) : DEFAULT_PROXY_HOST);
            this.setProxyExceptions(OsgiUtil.toStringArray(properties.get("proxy.exceptions"), DEFAULT_PROXY_EXCEPTIONS));
            this.setProxyCredentials(OsgiUtil.toString(properties.get("proxy.user"), DEFAULT_PROXY_USERNAME), OsgiUtil.toString(properties.get("proxy.password"), DEFAULT_PROXY_PASSWORD), OsgiUtil.toString(properties.get("proxy.ntlm.host"), DEFAULT_PROXY_NTLM_HOST), OsgiUtil.toString(properties.get("proxy.ntlm.domain"), DEFAULT_PROXY_NTLM_DOMAIN));
        } else {
            this.setProxyEnabled(false);
            this.setProxyHost(DEFAULT_PROXY_HOST);
            this.setProxyExceptions(DEFAULT_PROXY_EXCEPTIONS);
            this.setProxyCredentials(DEFAULT_PROXY_USERNAME, DEFAULT_PROXY_PASSWORD, DEFAULT_PROXY_NTLM_HOST, DEFAULT_PROXY_NTLM_DOMAIN);
        }
        this.log.info((Object)("ProxySelector reconfigured: enabled=" + this.proxyEnabled + ", host:" + this.proxyHost));
    }

    private void setProxyEnabled(boolean proxyEnabled) {
        this.proxyEnabled = proxyEnabled;
    }

    private void setProxyHost(String proxyHostConfig) {
        this.proxyHost = NULL_PROXY;
        this.proxyAuthScope = null;
        if (proxyHostConfig != null) {
            String[] parts = proxyHostConfig.split(":");
            if (parts.length != 2) {
                this.log.error((Object)("ProxyHost: Missing coloing in format; expect host:port, get: " + proxyHostConfig));
            } else if (parts[0].length() == 0) {
                this.log.error((Object)("ProxyHost: Empty host name; expect host:port, get: " + proxyHostConfig));
            } else if (parts[1].length() == 0) {
                this.log.error((Object)("ProxyHost: Empty port number; expect host:port, get: " + proxyHostConfig));
            } else {
                try {
                    InetAddress.getByName(parts[0]);
                    int port = Integer.parseInt(parts[1]);
                    this.proxyHost = new ProxyHost(parts[0], port);
                    this.proxyAuthScope = new AuthScope(parts[0], port);
                }
                catch (NumberFormatException nfe) {
                    this.log.error((Object)("ProxyHost: Port not a number; expect host:port, get: " + proxyHostConfig));
                }
                catch (UnknownHostException e) {
                    this.log.error((Object)("ProxyHost: Proxy Host name '" + parts[0] + "' does not resolve"), (Throwable)e);
                }
            }
        }
    }

    private void setProxyCredentials(String userName, String passWord, String host, String domain) {
        this.proxyCredentials = userName != null && userName.length() > 0 ? (host != null && host.length() > 0 && domain != null && domain.length() > 0 ? new NTCredentials(userName, passWord, host, domain) : new UsernamePasswordCredentials(userName, passWord)) : null;
    }

    private void setProxyExceptions(String[] exceptions) {
        ArrayList<HostMatcher> exceptionList = new ArrayList<HostMatcher>();
        if (exceptions != null) {
            for (int i = 0; i < exceptions.length; ++i) {
                exceptionList.add(ProxySelector.createMatcher(exceptions[i].trim()));
            }
        }
        this.exceptions = exceptionList.toArray(new HostMatcher[exceptionList.size()]);
    }

    final ProxyHost getProxy(String targetHost) {
        ProxyHost proxy;
        if (this.proxyEnabled && this.proxyHost != NULL_PROXY) {
            proxy = this.proxyHost;
            HostMatcher[] exceptions = this.exceptions;
            for (int i = 0; i < exceptions.length; ++i) {
                if (!exceptions[i].matches(targetHost)) continue;
                proxy = NULL_PROXY;
                break;
            }
        } else {
            proxy = NULL_PROXY;
        }
        return proxy;
    }

    final void setProxyCredentials(HttpState httpState) {
        if (this.proxyEnabled && this.proxyAuthScope != null && this.proxyCredentials != null) {
            httpState.setProxyCredentials(this.proxyAuthScope, this.proxyCredentials);
        }
    }

    private static HostMatcher createMatcher(String name) {
        NetworkAddress na = NetworkAddress.parse(name);
        if (na != null) {
            return new IPAddressMatcher(na);
        }
        if (name.startsWith(".")) {
            return new DomainNameMatcher(name);
        }
        return new HostNameMatcher(name);
    }

    static class NetworkAddress {
        final int address;
        final int mask;

        static NetworkAddress parse(String adrSpec) {
            Matcher nameMatcher = ProxySelector.IP_MASK_PATTERN.matcher(adrSpec);
            if (nameMatcher.matches()) {
                try {
                    int i1 = NetworkAddress.toInt(nameMatcher.group(1), 255);
                    int i2 = NetworkAddress.toInt(nameMatcher.group(2), 255);
                    int i3 = NetworkAddress.toInt(nameMatcher.group(3), 255);
                    int i4 = NetworkAddress.toInt(nameMatcher.group(4), 255);
                    int ip = i1 << 24 | i2 << 16 | i3 << 8 | i4;
                    int mask = NetworkAddress.toInt(nameMatcher.group(6), 32);
                    mask = mask == 32 ? -1 : -1 - (-1 >>> mask);
                    return new NetworkAddress(ip, mask);
                }
                catch (NumberFormatException nfe) {
                    // empty catch block
                }
            }
            return null;
        }

        private static int toInt(String value, int max) {
            if (value == null || value.length() == 0) {
                return max;
            }
            int number = Integer.parseInt(value);
            if (number > max) {
                number = max;
            }
            return number;
        }

        NetworkAddress(int address, int mask) {
            this.address = address;
            this.mask = mask;
        }
    }

    static class IPAddressMatcher
    implements HostMatcher {
        private final NetworkAddress address;

        IPAddressMatcher(NetworkAddress address) {
            this.address = address;
        }

        public boolean matches(String host) {
            NetworkAddress hostAddress = NetworkAddress.parse(host);
            return hostAddress != null && this.address.address == (hostAddress.address & this.address.mask);
        }

        public int getIpAddress() {
            return this.address.address;
        }

        public int getNetMask() {
            return this.address.mask;
        }
    }

    static class DomainNameMatcher
    implements HostMatcher {
        private final String domainName;

        DomainNameMatcher(String domainName) {
            this.domainName = domainName.toLowerCase();
        }

        public boolean matches(String host) {
            return host.toLowerCase().endsWith(this.domainName);
        }

        public String getDomainName() {
            return this.domainName;
        }
    }

    static class HostNameMatcher
    implements HostMatcher {
        private final String hostName;

        HostNameMatcher(String hostName) {
            this.hostName = hostName;
        }

        public boolean matches(String host) {
            return this.hostName.equalsIgnoreCase(host);
        }

        public String getHostName() {
            return this.hostName;
        }
    }

    static interface HostMatcher {
        public boolean matches(String var1);
    }

}