diff options
Diffstat (limited to 'src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java')
-rw-r--r-- | src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java new file mode 100644 index 0000000..30c3be1 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/browser/firefox/FirefoxProxySearchStrategy.java @@ -0,0 +1,267 @@ +package com.btr.proxy.search.browser.firefox; + +import java.io.IOException; +import java.net.ProxySelector; +import java.util.Properties; + +import com.btr.proxy.search.ProxySearchStrategy; +import com.btr.proxy.search.desktop.DesktopProxySearchStrategy; +import com.btr.proxy.search.wpad.WpadProxySearchStrategy; +import com.btr.proxy.selector.direct.NoProxySelector; +import com.btr.proxy.selector.fixed.FixedProxySelector; +import com.btr.proxy.selector.fixed.FixedSocksSelector; +import com.btr.proxy.selector.misc.ProtocolDispatchSelector; +import com.btr.proxy.selector.whitelist.ProxyBypassListSelector; +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.Logger.LogLevel; +import com.btr.proxy.util.PlatformUtil; +import com.btr.proxy.util.PlatformUtil.Platform; +import com.btr.proxy.util.ProxyException; +import com.btr.proxy.util.ProxyUtil; + +/***************************************************************************** + * Loads the Firefox3 proxy settings from the users Firefox3 settings. + * This will load the file <i>prefs.js</i> that is located in the + * <p> + * <i>.mozilla/firefox/(profile)/</i> folder. + * </p> + * + * See <a href="https://developer.mozilla.org/En/Mozilla_Networking_Preferences">Mozilla_Networking_Preferences</a> + * for an explanation of the proxy settings. + * <p> + * The following settings are extracted from + * this file: + * </p> + * Some generic settings:<br/> + * <ul> + * <li><i>network.proxy.type</i> -> n/a = use system settings, 0 = direct, 1 = Fixed proxy settings, 2 = proxy script (PAC), 3 = also direct , 4 = auto detect (WPAD)</li> + * <li><i>network.proxy.share_proxy_settings</i> -> true = use same proxy for all protocols</li> + * <li><i>network.proxy.no_proxies_on</i> -> a comma separated ignore list. </li> + * <li><i>network.proxy.autoconfig_url</i> -> a URL to an proxy configuration script</li> + * </ul> + * Host names and ports per protocol are stored in the following settings: + * <ul> + * <li><i>network.proxy.http</i></li> + * <li><i>network.proxy.http_port</i></li> + * <li><i>network.proxy.ssl</i></li> + * <li><i>network.proxy.ssl_port</i></li> + * <li><i>network.proxy.ftp</i></li> + * <li><i>network.proxy.ftp_port</i></li> + * <li><i>network.proxy.gopher</i></li> + * <li><i>network.proxy.gopher_port</i></li> + * <li><i>network.proxy.socks</i></li> + * <li><i>network.proxy.socks_port</i></li> + * <li><i>network.proxy.socks_version</i> -> 4 or 5</li> + * </u> + * <p> + * Note that if there are more than one profile the first profile found will be used. + * </p> + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class FirefoxProxySearchStrategy implements ProxySearchStrategy { + + private FirefoxProfileSource profileScanner; + private FirefoxSettingParser settingsParser; + + /************************************************************************* + * ProxySelector + * @see java.net.ProxySelector#ProxySelector() + ************************************************************************/ + + public FirefoxProxySearchStrategy() { + super(); + if (PlatformUtil.getCurrentPlattform() == Platform.WIN) { + this.profileScanner = new WinFirefoxProfileSource(); + } else { + this.profileScanner = new LinuxFirefoxProfileSource(); + } + this.settingsParser = new FirefoxSettingParser(); + } + + /************************************************************************* + * Loads the proxy settings and initializes a proxy selector for the firefox + * proxy settings. + * @return a configured ProxySelector, null if none is found. + * @throws ProxyException on file reading error. + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + Logger.log(getClass(), LogLevel.TRACE, "Detecting Firefox settings."); + + Properties settings = readSettings(); + + ProxySelector result = null; + int type = Integer.parseInt(settings.getProperty("network.proxy.type", "-1")); + switch (type) { + case -1: // Use system settings + Logger.log(getClass(), LogLevel.TRACE, "Firefox uses system settings"); + result = new DesktopProxySearchStrategy().getProxySelector(); + break; + case 0: // Use no proxy + Logger.log(getClass(), LogLevel.TRACE, "Firefox uses no proxy"); + result = NoProxySelector.getInstance(); + break; + case 1: // Fixed settings + Logger.log(getClass(), LogLevel.TRACE, "Firefox uses manual settings"); + result = setupFixedProxySelector(settings); + break; + case 2: // PAC Script + String pacScriptUrl = settings.getProperty("network.proxy.autoconfig_url", ""); + Logger.log(getClass(), LogLevel.TRACE, "Firefox uses script (PAC) {0}", pacScriptUrl); + result = ProxyUtil.buildPacSelectorForUrl(pacScriptUrl); + break; + case 3: // Backward compatibility to netscape. + Logger.log(getClass(), LogLevel.TRACE, "Netscape compability mode -> uses no proxy"); + result = NoProxySelector.getInstance(); + break; + case 4: // WPAD auto config + Logger.log(getClass(), LogLevel.TRACE, "Firefox uses automatic detection (WPAD)"); + result = new WpadProxySearchStrategy().getProxySelector(); + break; + default: + break; + } + + // Wrap in white list filter. + String noProxyList = settings.getProperty("network.proxy.no_proxies_on", null); + if (result != null && noProxyList != null && noProxyList.trim().length() > 0) { + Logger.log(getClass(), LogLevel.TRACE, "Firefox uses proxy bypass list for: {0}", noProxyList); + result = new ProxyBypassListSelector(noProxyList, result); + } + + return result; + } + + /************************************************************************* + * Reads the settings file and stores all settings in a Properties map. + * @return the parsed settings. + * @throws ProxyException on read error. + ************************************************************************/ + + public Properties readSettings() throws ProxyException { + try { + Properties settings = this.settingsParser.parseSettings(this.profileScanner); + return settings; + } catch (IOException e) { + Logger.log(getClass(), LogLevel.ERROR, "Error parsing settings", e); + throw new ProxyException(e); + } + } + + /************************************************************************* + * Parse the fixed proxy settings and build an ProxySelector for this a + * chained configuration. + * @param settings the proxy settings to evaluate. + ************************************************************************/ + + private ProxySelector setupFixedProxySelector(Properties settings) { + ProtocolDispatchSelector ps = new ProtocolDispatchSelector(); + installHttpProxy(ps, settings); + if (isProxyShared(settings)) { + installSharedProxy(ps); + } else { + installFtpProxy(ps, settings); + installSecureProxy(ps, settings); + installSocksProxy(ps, settings); + } + return ps; + } + + /************************************************************************* + * @param ps + * @param settings + * @throws NumberFormatException + ************************************************************************/ + + private void installFtpProxy(ProtocolDispatchSelector ps, + Properties settings) throws NumberFormatException { + installSelectorForProtocol(ps, settings, "ftp"); + } + + /************************************************************************* + * @param ps + * @param settings + * @throws NumberFormatException + ************************************************************************/ + + private void installHttpProxy(ProtocolDispatchSelector ps, + Properties settings) throws NumberFormatException { + installSelectorForProtocol(ps, settings, "http"); + } + + /************************************************************************* + * @param settings + * @return + ************************************************************************/ + + private boolean isProxyShared(Properties settings) { + return Boolean.TRUE.toString().equals(settings.getProperty("network.proxy.share_proxy_settings", "false").toLowerCase()); + } + + /************************************************************************* + * @param ps + ************************************************************************/ + + private void installSharedProxy(ProtocolDispatchSelector ps) { + ProxySelector httpProxy = ps.getSelector("http"); + if (httpProxy != null) { + ps.setFallbackSelector(httpProxy); + } + } + + /************************************************************************* + * @param ps + * @param settings + * @throws NumberFormatException + ************************************************************************/ + + private void installSocksProxy(ProtocolDispatchSelector ps, + Properties settings) throws NumberFormatException { + String proxyHost = settings.getProperty("network.proxy.socks", null); + int proxyPort = Integer.parseInt(settings.getProperty("network.proxy.socks_port", "0")); + if (proxyHost != null && proxyPort != 0) { + Logger.log(getClass(), LogLevel.TRACE, "Firefox socks proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector("socks", new FixedSocksSelector(proxyHost, proxyPort)); + } + } + + /************************************************************************* + * @param ps + * @param settings + * @throws NumberFormatException + ************************************************************************/ + + private void installSecureProxy(ProtocolDispatchSelector ps, + Properties settings) throws NumberFormatException { + String proxyHost = settings.getProperty("network.proxy.ssl", null); + int proxyPort = Integer.parseInt(settings.getProperty("network.proxy.ssl_port", "0")); + if (proxyHost != null && proxyPort != 0) { + Logger.log(getClass(), LogLevel.TRACE, "Firefox secure proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector("https", new FixedProxySelector(proxyHost, proxyPort)); + ps.setSelector("sftp", new FixedProxySelector(proxyHost, proxyPort)); + } + } + + /************************************************************************* + * Installs a proxy selector for the given protocol when settings are + * available. + * @param ps a ProtocolDispatchSelector to configure. + * @param settings to read the config from. + * @param protocol to configure. + * @throws NumberFormatException + ************************************************************************/ + + private void installSelectorForProtocol(ProtocolDispatchSelector ps, + Properties settings, String protocol) throws NumberFormatException { + + String proxyHost = settings.getProperty("network.proxy."+protocol, null); + int proxyPort = Integer.parseInt(settings.getProperty("network.proxy."+protocol+"_port", "0")); + if (proxyHost != null && proxyPort != 0) { + Logger.log(getClass(), LogLevel.TRACE, "Firefox "+protocol+" proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector(protocol, new FixedProxySelector(proxyHost, proxyPort)); + } + } + + +} |