package com.btr.proxy.search; import java.awt.GraphicsEnvironment; import java.net.ProxySelector; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import com.btr.proxy.search.browser.firefox.FirefoxProxySearchStrategy; import com.btr.proxy.search.browser.ie.IEProxySearchStrategy; import com.btr.proxy.search.desktop.DesktopProxySearchStrategy; import com.btr.proxy.search.desktop.gnome.GnomeProxySearchStrategy; import com.btr.proxy.search.desktop.kde.KdeProxySearchStrategy; import com.btr.proxy.search.desktop.win.WinProxySearchStrategy; import com.btr.proxy.search.env.EnvProxySearchStrategy; import com.btr.proxy.search.java.JavaProxySearchStrategy; import com.btr.proxy.selector.misc.BufferedProxySelector; import com.btr.proxy.selector.misc.ProxyListFallbackSelector; import com.btr.proxy.selector.pac.PacProxySelector; import com.btr.proxy.util.Logger; import com.btr.proxy.util.PlatformUtil; import com.btr.proxy.util.ProxyException; import com.btr.proxy.util.Logger.LogBackEnd; import com.btr.proxy.util.Logger.LogLevel; /***************************************************************************** * Main class to setup and initialize the proxy detection system.
* This class can be used to select a proxy discovery strategy.
* Implements the "Builder" pattern.
* Use addStrategy to add one or more search strategies.
* If you are done call the getProxySelector method.
* Then the strategies are asked one after the other for a ProxySelector until * an valid selector is found.
*

* Invoke the static getDefaultProxySearch method to use a default search strategy. *

* @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 ****************************************************************************/ public class ProxySearch implements ProxySearchStrategy { private static final int DEFAULT_PAC_CACHE_SIZE = 20; private static final long DEFAULT_PAC_CACHE_TTL = 1000*60*10; // 10 Minutes private List strategies; private int pacCacheSize; private long pacCacheTTL; /***************************************************************************** * Types of proxy detection supported by the builder. ****************************************************************************/ public enum Strategy { /// Use the platform settings. OS_DEFAULT, /// Use the settings of the platforms default browser. BROWSER, /// Use Firefox settings FIREFOX, /// Use InternetExplorer settings IE, /// Use environment variables for proxy settings. ENV_VAR, /// Use windows default proxy settings. WIN, /// Use KDE desktop default proxy settings. KDE, /// Use KDE desktop default proxy settings. GNOME, /// Use Java Networking system properties JAVA } /************************************************************************* * Constructor ************************************************************************/ public ProxySearch() { super(); this.strategies = new ArrayList(); this.pacCacheSize = DEFAULT_PAC_CACHE_SIZE; this.pacCacheTTL = DEFAULT_PAC_CACHE_TTL; } /************************************************************************* * Sets up a ProxySearch that uses a default search strategy suitable for * every platform. * @return a ProxySearch initialized with default settings. ************************************************************************/ public static ProxySearch getDefaultProxySearch() { ProxySearch s = new ProxySearch(); // Test if we are a server or a client. boolean headless = GraphicsEnvironment.isHeadless(); if (headless) { s.addStrategy(Strategy.JAVA); s.addStrategy(Strategy.OS_DEFAULT); s.addStrategy(Strategy.ENV_VAR); } else { s.addStrategy(Strategy.JAVA); s.addStrategy(Strategy.BROWSER); s.addStrategy(Strategy.OS_DEFAULT); s.addStrategy(Strategy.ENV_VAR); } Logger.log(ProxySearch.class, LogLevel.TRACE, "Using default search priority: {0}", s); return s; } /************************************************************************* * Adds an search strategy to the list of proxy searches strategies. * @param strategy the search strategy to add. ************************************************************************/ public void addStrategy(Strategy strategy) { switch (strategy) { case OS_DEFAULT: this.strategies.add(new DesktopProxySearchStrategy()); break; case BROWSER: this.strategies.add(getDefaultBrowserStrategy()); break; case FIREFOX: this.strategies.add(new FirefoxProxySearchStrategy()); break; case IE: this.strategies.add(new IEProxySearchStrategy()); break; case ENV_VAR: this.strategies.add(new EnvProxySearchStrategy()); break; case WIN: this.strategies.add(new WinProxySearchStrategy()); break; case KDE: this.strategies.add(new KdeProxySearchStrategy()); break; case GNOME: this.strategies.add(new GnomeProxySearchStrategy()); break; case JAVA: this.strategies.add(new JavaProxySearchStrategy()); break; default: throw new IllegalArgumentException("Unknown strategy code!"); } } /************************************************************************* * Sets the cache size of the PAC proxy selector cache. * This defines the number of URLs that are cached together with the PAC * script result. This improves performance because for URLs that are * in the cache the script is not executed again. * You have to set this before you add any strategies that may create a * PAC script proxy selector. * @param size of the cache. Set it to 0 to disable caching. * @param ttl is the time to live of the cache entries as amount of milliseconds. ************************************************************************/ public void setPacCacheSettings(int size, long ttl) { this.pacCacheSize = size; this.pacCacheTTL = ttl; } /************************************************************************* * Gets the search strategy for the platforms default browser. * @return a ProxySearchStrategy, null if no supported browser was found. ************************************************************************/ private ProxySearchStrategy getDefaultBrowserStrategy() { switch (PlatformUtil.getDefaultBrowser()) { case IE: return new IEProxySearchStrategy(); case FIREFOX: return new FirefoxProxySearchStrategy(); } return null; } /************************************************************************* * Gets the proxy selector that will use the configured search order. * @return a ProxySelector, null if none was found for the current * builder configuration. ************************************************************************/ public ProxySelector getProxySelector() { Logger.log(getClass(), LogLevel.TRACE, "Executing search strategies to find proxy selector"); for (ProxySearchStrategy strat : this.strategies) { try { ProxySelector selector = strat.getProxySelector(); if (selector != null) { selector = installBufferingAndFallbackBehaviour(selector); return selector; } } catch (ProxyException e) { Logger.log(getClass(), LogLevel.DEBUG, "Strategy {0} failed trying next one.", e); // Ignore and try next strategy. } } return null; } /************************************************************************* * If it is PAC and we have caching enabled set it here. * @param selector * @return ************************************************************************/ private ProxySelector installBufferingAndFallbackBehaviour(ProxySelector selector) { if (selector instanceof PacProxySelector) { if (this.pacCacheSize > 0) { selector = new BufferedProxySelector(this.pacCacheSize, this.pacCacheTTL, selector); } selector = new ProxyListFallbackSelector(selector); } return selector; } /************************************************************************* * toString * @see java.lang.Object#toString() ************************************************************************/ @Override public String toString() { StringBuilder sb = new StringBuilder("Proxy search: "); for (ProxySearchStrategy strat : this.strategies) { sb.append(strat); sb.append(" "); } return sb.toString(); } /************************************************************************* * For testing only. Will print the logging & proxy information to the console. * @param args the command line arguments. ************************************************************************/ public static void main(String[] args) { ProxySearch ps = ProxySearch.getDefaultProxySearch(); Logger.setBackend(new LogBackEnd() { public void log(Class clazz, LogLevel loglevel, String msg, Object... params) { System.out.println(MessageFormat.format(msg, params)); } public boolean isLogginEnabled(LogLevel logLevel) { return true; } }); ps.getProxySelector(); } }