diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2013-10-01 Omair Majid <omajid@redhat.com> + + * netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java + (BrowserAwareProxySelector): Split off browser-specific work into .. + (initialize): New method. + (initFromBrowserConfig): Delegate reading browser preferences to .. + (parseBrowserPreferences): New method. + (getFromBrowserConfiguration): Delegate to + JNLPProxySelector.getFromArguments. + * netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java + (getFromConfiguration): Move logic into getFromArguments; delegate to it. + (getFromArguments): Renamed from getFromConfiguration. Handle optionally + using the http host/port for socket addresses. + * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java + (initialize): Call BrowserAwareProxySelector.initialize. + * tests/netx/unit/net/sourceforge/jnlp/browser/BrowserAwareProxySelectorTest.java: + New file. + 2013-10-01 Omair Majid <omajid@redhat.com> * plugin/icedteanp/java/sun/applet/PluginProxySelector.java diff --git a/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java b/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java --- a/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java +++ b/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java @@ -40,13 +40,10 @@ import java.io.File; import java.io.IOException; -import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.Proxy; -import java.net.SocketAddress; import java.net.URI; import java.net.URL; -import java.net.Proxy.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -79,6 +76,7 @@ private int browserProxyType = BROWSER_PROXY_TYPE_NONE; private URL browserAutoConfigUrl; + /** Whether the http proxy should be used for http, https, ftp and socket protocols */ private Boolean browserUseSameProxy; private String browserHttpProxyHost; private int browserHttpProxyPort; @@ -96,6 +94,9 @@ */ public BrowserAwareProxySelector(DeploymentConfiguration config) { super(config); + } + + public void initialize() { try { initFromBrowserConfig(); } catch (IOException e) { @@ -110,11 +111,7 @@ */ private void initFromBrowserConfig() throws IOException { - File preferencesFile = FirefoxPreferencesFinder.find(); - - FirefoxPreferencesParser parser = new FirefoxPreferencesParser(preferencesFile); - parser.parse(); - Map<String, String> prefs = parser.getPreferences(); + Map<String, String> prefs = parseBrowserPreferences(); String type = prefs.get("network.proxy.type"); if (type != null) { @@ -150,6 +147,13 @@ browserSocks4ProxyPort = stringToPort(prefs.get("network.proxy.socks_port")); } + Map<String, String> parseBrowserPreferences() throws IOException { + File preferencesFile = FirefoxPreferencesFinder.find(); + FirefoxPreferencesParser parser = new FirefoxPreferencesParser(preferencesFile); + parser.parse(); + return parser.getPreferences(); + } + /** * Returns port inside a string. Unlike {@link Integer#valueOf(String)}, * it will not throw exceptions. @@ -244,36 +248,11 @@ * the browser's preferences file. */ private List<Proxy> getFromBrowserConfiguration(URI uri) { - List<Proxy> proxies = new ArrayList<Proxy>(); - - String scheme = uri.getScheme(); - - if (browserUseSameProxy) { - SocketAddress sa = new InetSocketAddress(browserHttpProxyHost, browserHttpProxyPort); - Proxy proxy; - if (scheme.equals("socket")) { - proxy = new Proxy(Type.SOCKS, sa); - } else { - proxy = new Proxy(Type.HTTP, sa); - } - proxies.add(proxy); - } else if (scheme.equals("http")) { - SocketAddress sa = new InetSocketAddress(browserHttpProxyHost, browserHttpProxyPort); - proxies.add(new Proxy(Type.HTTP, sa)); - } else if (scheme.equals("https")) { - SocketAddress sa = new InetSocketAddress(browserHttpsProxyHost, browserHttpsProxyPort); - proxies.add(new Proxy(Type.HTTP, sa)); - } else if (scheme.equals("ftp")) { - SocketAddress sa = new InetSocketAddress(browserFtpProxyHost, browserFtpProxyPort); - proxies.add(new Proxy(Type.HTTP, sa)); - } else if (scheme.equals("socket")) { - SocketAddress sa = new InetSocketAddress(browserSocks4ProxyHost, browserSocks4ProxyPort); - proxies.add(new Proxy(Type.SOCKS, sa)); - } else { - proxies.add(Proxy.NO_PROXY); - } - - return proxies; + return getFromArguments(uri, browserUseSameProxy, true, + browserHttpsProxyHost, browserHttpsProxyPort, + browserHttpProxyHost, browserHttpProxyPort, + browserFtpProxyHost, browserFtpProxyPort, + browserSocks4ProxyHost, browserSocks4ProxyPort); } } diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java b/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java --- a/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java @@ -288,15 +288,42 @@ * @return a List of Proxy objects */ private List<Proxy> getFromConfiguration(URI uri) { + return getFromArguments(uri, sameProxy, false, + proxyHttpsHost, proxyHttpsPort, + proxyHttpHost, proxyHttpPort, + proxyFtpHost, proxyFtpPort, + proxySocks4Host, proxySocks4Port); + } + + /** + * Returns a list of proxies by using the arguments + * + * @return a List of Proxy objects + */ + protected static List<Proxy> getFromArguments(URI uri, + boolean sameProxy, boolean sameProxyIncludesSocket, + String proxyHttpsHost, int proxyHttpsPort, + String proxyHttpHost, int proxyHttpPort, + String proxyFtpHost, int proxyFtpPort, + String proxySocks4Host, int proxySocks4Port) { + List<Proxy> proxies = new ArrayList<Proxy>(); String scheme = uri.getScheme(); + boolean socksProxyAdded = false; + if (sameProxy) { - if (proxyHttpHost != null && (scheme.equals("https") || scheme.equals("http") || scheme.equals("ftp"))) { + if (proxyHttpHost != null) { SocketAddress sa = new InetSocketAddress(proxyHttpHost, proxyHttpPort); - Proxy proxy = new Proxy(Type.HTTP, sa); - proxies.add(proxy); + if ((scheme.equals("https") || scheme.equals("http") || scheme.equals("ftp"))) { + Proxy proxy = new Proxy(Type.HTTP, sa); + proxies.add(proxy); + } else if (scheme.equals("socket") && sameProxyIncludesSocket) { + Proxy proxy = new Proxy(Type.SOCKS, sa); + proxies.add(proxy); + socksProxyAdded = true; + } } } else if (scheme.equals("http") && proxyHttpHost != null) { SocketAddress sa = new InetSocketAddress(proxyHttpHost, proxyHttpPort); @@ -309,9 +336,10 @@ proxies.add(new Proxy(Type.HTTP, sa)); } - if (proxySocks4Host != null) { + if (!socksProxyAdded && (proxySocks4Host != null)) { SocketAddress sa = new InetSocketAddress(proxySocks4Host, proxySocks4Port); proxies.add(new Proxy(Type.SOCKS, sa)); + socksProxyAdded = true; } if (proxies.size() == 0) { diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java --- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java @@ -266,7 +266,9 @@ // plug in a custom authenticator and proxy selector Authenticator.setDefault(new JNLPAuthenticator()); - ProxySelector.setDefault(new BrowserAwareProxySelector(config)); + BrowserAwareProxySelector proxySelector = new BrowserAwareProxySelector(config); + proxySelector.initialize(); + ProxySelector.setDefault(proxySelector); // Restrict access to netx classes Security.setProperty("package.access", diff --git a/tests/netx/unit/net/sourceforge/jnlp/browser/BrowserAwareProxySelectorTest.java b/tests/netx/unit/net/sourceforge/jnlp/browser/BrowserAwareProxySelectorTest.java new file mode 100644 --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/browser/BrowserAwareProxySelectorTest.java @@ -0,0 +1,227 @@ +/* BrowserAwareProxySelectorTest.java + Copyright (C) 2013 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.browser; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.Proxy.Type; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.jnlp.config.DeploymentConfiguration; +import net.sourceforge.jnlp.runtime.JNLPProxySelector; + +import org.junit.Before; +import org.junit.Test; + +public class BrowserAwareProxySelectorTest { + + static class TestBrowserAwareProxySelector extends BrowserAwareProxySelector { + + private final Map<String, String> browserPrefs; + + public TestBrowserAwareProxySelector(DeploymentConfiguration config, Map<String, String> browserPrefs) { + super(config); + this.browserPrefs = browserPrefs; + } + + @Override + protected Map<String, String> parseBrowserPreferences() throws IOException { + return browserPrefs; + } + } + + private static final String PROXY_HOST = "foo"; + private static final int PROXY_PORT = 42; + private static final InetSocketAddress PROXY_ADDRESS = new InetSocketAddress(PROXY_HOST, PROXY_PORT); + + private DeploymentConfiguration config; + private Map<String, String> browserPrefs; + + @Before + public void setUp() { + config = new DeploymentConfiguration(); + config.setProperty(DeploymentConfiguration.KEY_PROXY_TYPE, String.valueOf(JNLPProxySelector.PROXY_TYPE_BROWSER)); + + browserPrefs = new HashMap<String, String>(); + } + + @Test + public void testNoBrowserProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "0" /* none */); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("https://example.org")); + + assertEquals(1, result.size()); + assertEquals(Proxy.NO_PROXY, result.get(0)); + } + + @Test + public void testBrowserManualSameProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + browserPrefs.put("network.proxy.share_proxy_settings", "true"); + browserPrefs.put("network.proxy.http", PROXY_HOST); + browserPrefs.put("network.proxy.http_port", String.valueOf(PROXY_PORT)); + + List<Proxy> result; + + result = getProxy(config, browserPrefs, new URI("https://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.HTTP, PROXY_ADDRESS), result.get(0)); + + result = getProxy(config, browserPrefs, new URI("socket://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.SOCKS, PROXY_ADDRESS), result.get(0)); + + } + + @Test + public void testBrowserManualHttpsProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + browserPrefs.put("network.proxy.ssl", PROXY_HOST); + browserPrefs.put("network.proxy.ssl_port", String.valueOf(PROXY_PORT)); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("https://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.HTTP, PROXY_ADDRESS), result.get(0)); + } + + @Test + public void testBrowserManualHttpProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + browserPrefs.put("network.proxy.http", PROXY_HOST); + browserPrefs.put("network.proxy.http_port", String.valueOf(PROXY_PORT)); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("http://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.HTTP, PROXY_ADDRESS), result.get(0)); + } + + @Test + public void testBrowserManualFtpProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + browserPrefs.put("network.proxy.ftp", PROXY_HOST); + browserPrefs.put("network.proxy.ftp_port", String.valueOf(PROXY_PORT)); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("ftp://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.HTTP, PROXY_ADDRESS), result.get(0)); + } + + @Test + public void testBrowserManualSocksProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + browserPrefs.put("network.proxy.socks", PROXY_HOST); + browserPrefs.put("network.proxy.socks_port", String.valueOf(PROXY_PORT)); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("socket://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.SOCKS, PROXY_ADDRESS), result.get(0)); + } + + @Test + public void testBrowserManualHttpProxyFallsBackToSocksProxy() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + browserPrefs.put("network.proxy.socks", PROXY_HOST); + browserPrefs.put("network.proxy.socks_port", String.valueOf(PROXY_PORT)); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("http://example.org")); + + assertEquals(1, result.size()); + assertEquals(new Proxy(Type.SOCKS, PROXY_ADDRESS), result.get(0)); + } + + @Test + public void testBrowserManualProxyUnknownProtocol() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "1" /* = manual */); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("gopher://example.org")); + + assertEquals(1, result.size()); + assertEquals(Proxy.NO_PROXY, result.get(0)); + } + + @Test + public void testBrowserAutoProxyUnimplemented() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "4" /* = auto */); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("http://example.org")); + + assertEquals(1, result.size()); + assertEquals(Proxy.NO_PROXY, result.get(0)); + } + + @Test + public void testBrowserSystemProxyUnimplemented() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "5" /* = system */); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("http://example.org")); + + assertEquals(1, result.size()); + assertEquals(Proxy.NO_PROXY, result.get(0)); + } + + @Test + public void testBrowserPacProxyUnimplemented() throws URISyntaxException { + browserPrefs.put("network.proxy.type", "2" /* = pac */); + + List<Proxy> result = getProxy(config, browserPrefs, new URI("http://example.org")); + + assertEquals(1, result.size()); + assertEquals(Proxy.NO_PROXY, result.get(0)); + } + + private static List<Proxy> getProxy(DeploymentConfiguration config, Map<String, String> browserPrefs, URI uri) { + BrowserAwareProxySelector selector = new TestBrowserAwareProxySelector(config, browserPrefs); + selector.initialize(); + + return selector.getFromBrowser(uri); + } +}