summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2010-10-18 16:55:49 -0700
committerJesse Wilson <jessewilson@google.com>2010-10-18 23:09:07 -0700
commit3b0348d1081a4645aa38da97ee299fadc040c1b4 (patch)
treeb6c696e1dad25fbbaeaf2fabcce21c3a6b615d85
parent4dfae7b3e2b56160646c17d93b32b3ff495c0053 (diff)
downloadlibcore-3b0348d1081a4645aa38da97ee299fadc040c1b4.zip
libcore-3b0348d1081a4645aa38da97ee299fadc040c1b4.tar.gz
libcore-3b0348d1081a4645aa38da97ee299fadc040c1b4.tar.bz2
Rewrite ProxySelector and write a test to go with it.
http://b/3097518 Change-Id: Ic6b28ab21e00b6b55a01ae7927b87ac0d0375b44
-rw-r--r--luni/src/main/java/java/net/ProxySelector.java160
-rw-r--r--luni/src/main/java/java/net/ProxySelectorImpl.java340
-rw-r--r--luni/src/test/java/libcore/java/net/ProxySelectorTest.java207
3 files changed, 375 insertions, 332 deletions
diff --git a/luni/src/main/java/java/net/ProxySelector.java b/luni/src/main/java/java/net/ProxySelector.java
index b9dee5e..5fb1ec5 100644
--- a/luni/src/main/java/java/net/ProxySelector.java
+++ b/luni/src/main/java/java/net/ProxySelector.java
@@ -13,116 +13,132 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package java.net;
import java.io.IOException;
import java.util.List;
/**
- * Selects an applicable proxy server when connecting to a resource specified by
- * a URL. Proxy selectors are concrete subclasses of {@code ProxySelector} and
- * can be set as default by calling the {@code setDefault()} method. If a
- * connection can't be established, the caller should notify the proxy selector
- * by invoking the {@code connectFailed()} method.
+ * Selects the proxy server to use, if any, when connecting to a given URL.
+ *
+ * <h3>System Properties</h3>
+ * <p>The default proxy selector is configured by system properties.
+ *
+ * <table border="1" cellpadding="3" cellspacing="0">
+ * <tr class="TableHeadingColor"><th colspan="4">Hostname patterns</th></tr>
+ * <tr><th>URL scheme</th><th>property name</th><th>description</th><th>default</th></tr>
+ * <tr><td>ftp</td><td>ftp.nonProxyHosts</td><td>Hostname pattern for FTP servers to connect to
+ * directly (without a proxy).</td><td>*</td></tr>
+ * <tr><td>http</td><td>http.nonProxyHosts</td><td>Hostname pattern for HTTP servers to connect to
+ * directly (without a proxy).</td><td>*</td></tr>
+ * <tr><td>https</td><td>https.nonProxyHosts</td><td>Hostname pattern for HTTPS servers to connect
+ * to directly (without a proxy).</td><td>*</td></tr>
+ * <tr><td colspan="4"><br></td></tr>
+ *
+ * <tr class="TableHeadingColor"><th colspan="4">{@linkplain Proxy.Type#HTTP HTTP Proxies}</th></tr>
+ * <tr><th>URL scheme</th><th>property name</th><th>description</th><th>default</th></tr>
+ * <tr><td rowspan="2">ftp</td><td>ftp.proxyHost</td><td>Hostname of the HTTP proxy server used for
+ * FTP requests.</td><td></td></tr>
+ * <tr><td>ftp.proxyPort</td><td>Port number of the HTTP proxy server used for FTP
+ * requests.</td><td>80</td></tr>
+ * <tr><td rowspan="2">http</td><td>http.proxyHost</td><td>Hostname of the HTTP proxy server used
+ * for HTTP requests.</td><td></td></tr>
+ * <tr><td>http.proxyPort</td><td>Port number of the HTTP proxy server used for HTTP
+ * requests.</td><td>80</td></tr>
+ * <tr><td rowspan="2">https</td><td>https.proxyHost</td><td>Hostname of the HTTP proxy server used
+ * for HTTPS requests.</td><td></td></tr>
+ * <tr><td>https.proxyPort</td><td>Port number of the HTTP proxy server used for HTTPS
+ * requests.</td><td>443</td></tr>
+ * <tr><td rowspan="2">ftp, http or https</td><td>proxyHost</td><td>Hostname of the HTTP proxy
+ * server used for FTP, HTTP and HTTPS requests.</td><td></td></tr>
+ * <tr><td>proxyPort</td><td>Port number of the HTTP proxy server.</td><td>80 for FTP and HTTP
+ * <br>443 for HTTPS</td></tr>
+ * <tr><td colspan="4"><br></td></tr>
+ *
+ * <tr class="TableHeadingColor"><th colspan="4">{@linkplain Proxy.Type#SOCKS SOCKS
+ * Proxies}</th></tr>
+ * <tr><th>URL scheme</th><th>property name</th><th>description</th><th>default</th></tr>
+ * <tr><td rowspan="2">ftp, http, https or socket</td><td>socksProxyHost</td><td>Hostname of the
+ * SOCKS proxy server used for FTP, HTTP, HTTPS and raw sockets.<br>Raw socket URLs are of the
+ * form <code>socket://<i>host</i>:<i>port</i></code></td><td></td></tr>
+ * <tr><td>socksProxyPort</td><td>Port number of the SOCKS proxy server.</td><td>1080</td></tr>
+ * </table>
+ *
+ * <p>The default proxy selector always returns exactly one proxy. If no proxy
+ * is applicable, {@link Proxy#NO_PROXY} is returned. If multiple proxies are
+ * applicable, such as when both the {@code proxyHost} and {@code
+ * socksProxyHost} system properties are set, the result is the property listed
+ * earliest in the table above.
+ *
+ * <p>Hostname patterns are lists of hostnames that are separated by {@code |}
+ * and that use {@code *} as a wildcard. For example, setting the {@code
+ * http.nonProxyHosts} property to {@code *.android.com|*.kernel.org} will cause
+ * requests to {@code http://developer.android.com} to be made without a proxy.
+ *
+ * <h3>Alternatives</h3>
+ * <p>To request a URL without involving the system proxy selector, explicitly
+ * specify a proxy or {@link Proxy#NO_PROXY} using {@link
+ * URL#openConnection(Proxy)}.
+ *
+ * <p>Use {@link ProxySelector#setDefault(ProxySelector)} to install a custom
+ * proxy selector.
*/
public abstract class ProxySelector {
private static ProxySelector defaultSelector = new ProxySelectorImpl();
- /*
- * "getProxySelector" permission. getDefault method requires this
- * permission.
- */
- private final static NetPermission getProxySelectorPermission = new NetPermission(
- "getProxySelector");
-
- /*
- * "setProxySelector" permission. setDefault method requires this
- * permission.
- */
- private final static NetPermission setProxySelectorPermission = new NetPermission(
- "setProxySelector");
-
- /**
- * Creates a new {@code ProxySelector} instance.
- */
- public ProxySelector() {
- super();
- }
+ private final static NetPermission getProxySelectorPermission
+ = new NetPermission("getProxySelector");
+ private final static NetPermission setProxySelectorPermission
+ = new NetPermission("setProxySelector");
/**
- * Gets the default {@code ProxySelector} of the system.
+ * Returns the default proxy selector, or null if none exists.
*
- * @return the currently set default {@code ProxySelector}.
- * @throws SecurityException
- * if a security manager is installed but it doesn't have the
- * NetPermission("getProxySelector").
+ * @throws SecurityException if a security manager is installed but it
+ * doesn't have the NetPermission("getProxySelector").
*/
public static ProxySelector getDefault() {
SecurityManager sm = System.getSecurityManager();
- if (null != sm) {
+ if (sm != null) {
sm.checkPermission(getProxySelectorPermission);
}
return defaultSelector;
}
/**
- * Sets the default {@code ProxySelector} of the system. Removes the system
- * default {@code ProxySelector} if the parameter {@code selector} is set to
- * {@code null}.
+ * Sets the default proxy selector. If {@code selector} is null, the current
+ * proxy selector will be removed.
*
- * @param selector
- * the {@code ProxySelector} instance to set as default or
- * {@code null} to remove the current default {@code
- * ProxySelector}.
- * @throws SecurityException
- * if a security manager is installed but it doesn't have the
- * NetPermission("setProxySelector").
+ * @throws SecurityException if a security manager is installed but it
+ * doesn't have the NetPermission("setProxySelector").
*/
public static void setDefault(ProxySelector selector) {
SecurityManager sm = System.getSecurityManager();
- if (null != sm) {
+ if (sm != null) {
sm.checkPermission(setProxySelectorPermission);
}
defaultSelector = selector;
}
/**
- * Gets all applicable proxies based on the accessing protocol of {@code
- * uri}. The format of URI is defined as below:
- * <p>
- * <li>http URI stands for http connection.</li>
- * <li>https URI stands for https connection.</li>
- * <li>ftp URI stands for ftp connection.</li>
- * <li>socket:://ip:port URI stands for tcp client sockets connection.</li>
+ * Returns the proxy servers to use on connections to {@code uri}. This list
+ * will contain {@link Proxy#NO_PROXY} if no proxy server should be used.
*
- * @param uri
- * the target URI object.
- * @return a list containing all applicable proxies. If no proxy is
- * available, the list contains only the {@code Proxy.NO_PROXY}
- * element.
- * @throws IllegalArgumentException
- * if {@code uri} is {@code null}.
+ * @throws IllegalArgumentException if {@code uri} is null.
*/
public abstract List<Proxy> select(URI uri);
/**
- * Notifies the {@code ProxySelector} that a connection to the proxy server
- * could not be established. A concrete implementation should upon this
- * notification maintain the list of available proxies, since an updated
- * version should be provided by {@code select()}.
+ * Notifies this {@code ProxySelector} that a connection to the proxy server
+ * could not be established.
*
- * @param uri
- * the URI to which the connection could not be established.
- * @param sa
- * the address of the proxy.
- * @param ioe
- * the exception which was thrown during connection
- * establishment.
- * @throws IllegalArgumentException
- * if any argument is {@code null}.
- * @see #select(URI)
+ * @param uri the URI to which the connection could not be established.
+ * @param address the address of the proxy.
+ * @param failure the exception which was thrown during connection
+ * establishment.
+ * @throws IllegalArgumentException if any argument is null.
*/
- public abstract void connectFailed(URI uri, SocketAddress sa,
- IOException ioe);
+ public abstract void connectFailed(URI uri, SocketAddress address, IOException failure);
}
diff --git a/luni/src/main/java/java/net/ProxySelectorImpl.java b/luni/src/main/java/java/net/ProxySelectorImpl.java
index 571f32b..772b9e5 100644
--- a/luni/src/main/java/java/net/ProxySelectorImpl.java
+++ b/luni/src/main/java/java/net/ProxySelectorImpl.java
@@ -13,311 +13,131 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package java.net;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import java.util.Properties;
-import org.apache.harmony.luni.util.PriviAction;
-
-/**
- * Default implementation for {@code ProxySelector}.
- */
-@SuppressWarnings("unchecked")
-class ProxySelectorImpl extends ProxySelector {
-
- private static final int HTTP_PROXY_PORT = 80;
-
- private static final int HTTPS_PROXY_PORT = 443;
-
- private static final int FTP_PROXY_PORT = 80;
-
- private static final int SOCKS_PROXY_PORT = 1080;
- // Net properties read from net.properties file.
- private static Properties netProps = null;
+final class ProxySelectorImpl extends ProxySelector {
- // read net.properties file
- static {
- AccessController.doPrivileged(new java.security.PrivilegedAction() {
- public Object run() {
- File f = new File(System.getProperty("java.home")
- + File.separator + "lib" + File.separator
- + "net.properties");
-
- if (f.exists()) {
- try {
- FileInputStream fis = new FileInputStream(f);
- InputStream is = new BufferedInputStream(fis);
- netProps = new Properties();
- netProps.load(is);
- is.close();
- } catch (IOException e) {
- }
- }
- return null;
- }
- });
- }
-
- public ProxySelectorImpl() {
- super();
- }
-
- @Override
- public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+ @Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
if (uri == null || sa == null || ioe == null) {
throw new IllegalArgumentException();
}
}
- @Override
- public List<Proxy> select(URI uri) {
- // argument check
+ @Override public List<Proxy> select(URI uri) {
+ return Collections.singletonList(selectOneProxy(uri));
+ }
+
+ private Proxy selectOneProxy(URI uri) {
if (uri == null) {
throw new IllegalArgumentException("uri == null");
}
- // check scheme
String scheme = uri.getScheme();
- if (null == scheme) {
- throw new IllegalArgumentException();
+ if (scheme == null) {
+ throw new IllegalArgumentException("scheme == null");
}
- String host = uri.getHost();
- Proxy proxy = Proxy.NO_PROXY;
-
- if ("http".equals(scheme)) {
- proxy = selectHttpProxy(host);
- } else if ("https".equals(scheme)) {
- proxy = selectHttpsProxy();
- } else if ("ftp".equals(scheme)) {
- proxy = selectFtpProxy(host);
- } else if ("socket".equals(scheme)) {
- proxy = selectSocksProxy();
+ int port = -1;
+ Proxy proxy = null;
+ String nonProxyHostsKey = null;
+ boolean httpProxyOkay = true;
+ if ("http".equalsIgnoreCase(scheme)) {
+ port = 80;
+ nonProxyHostsKey = "http.nonProxyHosts";
+ proxy = lookupProxy("http.proxyHost", "http.proxyPort", Proxy.Type.HTTP, port);
+ } else if ("https".equalsIgnoreCase(scheme)) {
+ port = 443;
+ nonProxyHostsKey = "https.nonProxyHosts"; // RI doesn't support this
+ proxy = lookupProxy("https.proxyHost", "https.proxyPort", Proxy.Type.HTTP, port);
+ } else if ("ftp".equalsIgnoreCase(scheme)) {
+ port = 80; // not 21 as you might guess
+ nonProxyHostsKey = "ftp.nonProxyHosts";
+ proxy = lookupProxy("ftp.proxyHost", "ftp.proxyPort", Proxy.Type.HTTP, port);
+ } else if ("socket".equalsIgnoreCase(scheme)) {
+ httpProxyOkay = false;
+ } else {
+ return Proxy.NO_PROXY;
}
- List<Proxy> proxyList = new ArrayList<Proxy>(1);
- proxyList.add(proxy);
- return proxyList;
- }
-
- /*
- * Gets proxy for http request. 1. gets from "http.proxyHost", then gets
- * port from "http.proxyPort", or from "proxyPort" if "http.proxyPort" is
- * unavailable. 2. gets from "proxyHost" if 1 is unavailable,then get port
- * from "proxyPort", or from "http.proxyPort" if "proxyPort" is unavailable.
- * 3. gets from "socksProxyHost" if 2 is unavailable.
- */
-
- private Proxy selectHttpProxy(String uriHost) {
- String host;
- String port = null;
- Proxy.Type type = Proxy.Type.DIRECT;
- String nonProxyHosts = getSystemProperty("http.nonProxyHosts");
- // if host is in non proxy host list, returns Proxy.NO_PROXY
- if (isNonProxyHost(uriHost, nonProxyHosts)) {
+ if (nonProxyHostsKey != null
+ && isNonProxyHost(uri.getHost(), System.getProperty(nonProxyHostsKey))) {
return Proxy.NO_PROXY;
}
- host = getSystemProperty("http.proxyHost");
- if (null != host) {
- // case 1: http.proxyHost is set, use exact http proxy
- type = Proxy.Type.HTTP;
- port = getSystemPropertyOrAlternative("http.proxyPort",
- "proxyPort", String.valueOf(HTTP_PROXY_PORT));
- } else if ((host = getSystemProperty("proxyHost", null)) != null) {
- // case 2: proxyHost is set, use exact http proxy
- type = Proxy.Type.HTTP;
- port = getSystemPropertyOrAlternative("proxyPort",
- "http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
-
- } else if ((host = getSystemProperty("socksProxyHost")) != null) {
- // case 3: use socks proxy instead
- type = Proxy.Type.SOCKS;
- port = getSystemProperty(
- "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+ if (proxy != null) {
+ return proxy;
}
- int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT
- : HTTP_PROXY_PORT;
- return createProxy(type, host, port, defaultPort);
- }
- /*
- * Gets proxy for https request.
- */
- private Proxy selectHttpsProxy() {
- String host;
- String port = null;
- Proxy.Type type = Proxy.Type.DIRECT;
-
- host = getSystemProperty("https.proxyHost");
- if (null != host) {
- // case 1: use exact https proxy
- type = Proxy.Type.HTTP;
- port = getSystemProperty(
- "https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
- } else {
- host = getSystemProperty("socksProxyHost");
- if (null != host) {
- // case 2: use socks proxy instead
- type = Proxy.Type.SOCKS;
- port = getSystemProperty(
- "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+ if (httpProxyOkay) {
+ proxy = lookupProxy("proxyHost", "proxyPort", Proxy.Type.HTTP, port);
+ if (proxy != null) {
+ return proxy;
}
}
- int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT
- : HTTPS_PROXY_PORT;
- return createProxy(type, host, port, defaultPort);
- }
- /*
- * Gets proxy for ftp request.
- */
- private Proxy selectFtpProxy(String uriHost) {
- String host;
- String port = null;
- Proxy.Type type = Proxy.Type.DIRECT;
- String nonProxyHosts = getSystemProperty("ftp.nonProxyHosts");
- // if host is in non proxy host list, returns Proxy.NO_PROXY
- if (isNonProxyHost(uriHost, nonProxyHosts)) {
- return Proxy.NO_PROXY;
+ proxy = lookupProxy("socksProxyHost", "socksProxyPort", Proxy.Type.SOCKS, 1080);
+ if (proxy != null) {
+ return proxy;
}
- host = getSystemProperty("ftp.proxyHost");
- if (null != host) {
- // case 1: use exact ftp proxy
- type = Proxy.Type.HTTP;
- port = getSystemProperty(
- "ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
- } else {
- host = getSystemProperty("socksProxyHost");
- if (null != host) {
- // case 2: use socks proxy instead
- type = Proxy.Type.SOCKS;
- port = getSystemProperty(
- "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
- }
- }
- int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT
- : FTP_PROXY_PORT;
- return createProxy(type, host, port, defaultPort);
+ return Proxy.NO_PROXY;
}
- /*
- * Gets proxy for socks request.
+ /**
+ * Returns the proxy identified by the {@code hostKey} system property, or
+ * null.
*/
- private Proxy selectSocksProxy() {
- String host;
- String port = null;
- Proxy.Type type = Proxy.Type.DIRECT;
-
- host = getSystemProperty("socksProxyHost");
- if (null != host) {
- type = Proxy.Type.SOCKS;
- port = getSystemProperty(
- "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+ private Proxy lookupProxy(String hostKey, String portKey, Proxy.Type type, int defaultPort) {
+ String host = System.getProperty(hostKey);
+ if (host == null || host.isEmpty()) {
+ return null;
}
- return createProxy(type, host, port, SOCKS_PROXY_PORT);
- }
- /*
- * checks whether the host needs proxy. return true if it doesn't need a
- * proxy.
- */
- private boolean isNonProxyHost(String host, String nonProxyHosts) {
- // nonProxyHosts is not set
- if (null == host || null == nonProxyHosts) {
- return false;
- }
- // Construct regex expression of nonProxyHosts
- int length = nonProxyHosts.length();
- char ch;
- StringBuilder buf = new StringBuilder(length);
- for (int i = 0; i < nonProxyHosts.length(); i++) {
- ch = nonProxyHosts.charAt(i);
- switch (ch) {
- case '.':
- buf.append("\\.");
- break;
- case '*':
- buf.append(".*");
- break;
- default:
- buf.append(ch);
- }
- }
- String nonProxyHostsReg = buf.toString();
- // check whether the host is the nonProxyHosts.
- return host.matches(nonProxyHostsReg);
+ int port = getSystemPropertyInt(portKey, defaultPort);
+ return new Proxy(type, InetSocketAddress.createUnresolved(host, port));
}
- /*
- * Create Proxy by "type","host" and "port".
- */
- private Proxy createProxy(Proxy.Type type, String host, String port,
- int defaultPort) {
- Proxy proxy;
- if (type == Proxy.Type.DIRECT) {
- proxy = Proxy.NO_PROXY;
- } else {
- int iPort;
+ private int getSystemPropertyInt(String key, int defaultValue) {
+ String string = System.getProperty(key);
+ if (string != null) {
try {
- // BEGIN android-changed
- iPort = Integer.parseInt(port);
- // END android-changed
- } catch (NumberFormatException e) {
- iPort = defaultPort;
+ return Integer.parseInt(string);
+ } catch (NumberFormatException ignored) {
}
- proxy = new Proxy(type, InetSocketAddress.createUnresolved(host,
- iPort));
}
- return proxy;
- }
-
- /*
- * gets system property, privileged operation. If the value of the property
- * is null or empty String, it returns defaultValue.
- */
- private String getSystemProperty(final String property) {
- return getSystemProperty(property, null);
+ return defaultValue;
}
- /*
- * gets system property, privileged operation. If the value of the property
- * is null or empty String, it returns defaultValue.
+ /**
+ * Returns true if the {@code nonProxyHosts} system property pattern exists
+ * and matches {@code host}.
*/
- private String getSystemProperty(final String property,
- final String defaultValue) {
- String value = AccessController.doPrivileged(new PriviAction<String>(
- property));
- if (value == null || value.isEmpty()) {
- value = (netProps != null)
- ? netProps.getProperty(property, defaultValue)
- : defaultValue;
+ private boolean isNonProxyHost(String host, String nonProxyHosts) {
+ if (host == null || nonProxyHosts == null) {
+ return false;
}
- return value;
- }
- /*
- * gets system property, privileged operation. If the value of "key"
- * property is null, then retrieve value from "alternative" property.
- * Finally, if the value is null or empty String, it returns defaultValue.
- */
- private String getSystemPropertyOrAlternative(final String key,
- final String alternativeKey, final String defaultValue) {
- String value = getSystemProperty(key);
- if (value == null) {
- value = getSystemProperty(alternativeKey);
- if (null == value) {
- value = defaultValue;
+ // construct pattern
+ StringBuilder patternBuilder = new StringBuilder();
+ for (int i = 0; i < nonProxyHosts.length(); i++) {
+ char c = nonProxyHosts.charAt(i);
+ switch (c) {
+ case '.':
+ patternBuilder.append("\\.");
+ break;
+ case '*':
+ patternBuilder.append(".*");
+ break;
+ default:
+ patternBuilder.append(c);
}
}
- return value;
+ // check whether the host is the nonProxyHosts.
+ String pattern = patternBuilder.toString();
+ return host.matches(pattern);
}
}
diff --git a/luni/src/test/java/libcore/java/net/ProxySelectorTest.java b/luni/src/test/java/libcore/java/net/ProxySelectorTest.java
new file mode 100644
index 0000000..491cb8d
--- /dev/null
+++ b/luni/src/test/java/libcore/java/net/ProxySelectorTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.net;
+
+import static java.net.InetSocketAddress.createUnresolved;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+public final class ProxySelectorTest extends TestCase {
+
+ private ProxySelector proxySelector;
+
+ private URI httpUri;
+ private URI ftpUri;
+ private URI httpsUri;
+ private URI socketUri;
+ private URI otherUri;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ proxySelector = ProxySelector.getDefault();
+ httpUri = new URI("http://android.com");
+ ftpUri = new URI("ftp://android.com");
+ httpsUri = new URI("https://android.com");
+ socketUri = new URI("socket://android.com");
+ otherUri = new URI("other://android.com");
+ }
+
+ @Override protected void tearDown() throws Exception {
+ System.clearProperty("ftp.proxyHost");
+ System.clearProperty("ftp.proxyPort");
+ System.clearProperty("ftp.nonProxyHosts");
+ System.clearProperty("http.proxyHost");
+ System.clearProperty("http.proxyPort");
+ System.clearProperty("http.nonProxyHosts");
+ System.clearProperty("https.proxyHost");
+ System.clearProperty("https.proxyPort");
+ System.clearProperty("https.nonProxyHosts");
+ System.clearProperty("other.proxyHost");
+ System.clearProperty("other.proxyPort");
+ System.clearProperty("socket.proxyHost");
+ System.clearProperty("socket.proxyPort");
+ System.clearProperty("proxyHost");
+ System.clearProperty("proxyPort");
+ }
+
+ public void testNoProxySystemProperty() throws URISyntaxException {
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(socketUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ }
+
+ public void testProxyHostOnly() throws URISyntaxException {
+ System.setProperty("ftp.proxyHost", "a");
+ System.setProperty("http.proxyHost", "b");
+ System.setProperty("https.proxyHost", "c");
+ System.setProperty("other.proxyHost", "d");
+ System.setProperty("socket.proxyHost", "d");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("b", 80))),
+ proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("c", 443))),
+ proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(socketUri));
+ }
+
+ public void testProxyHostPort() throws URISyntaxException {
+ System.setProperty("ftp.proxyHost", "a");
+ System.setProperty("ftp.proxyPort", "1001");
+ System.setProperty("http.proxyHost", "b");
+ System.setProperty("http.proxyPort", "1002");
+ System.setProperty("https.proxyHost", "c");
+ System.setProperty("https.proxyPort", "1003");
+ System.setProperty("other.proxyHost", "d");
+ System.setProperty("other.proxyPort", "1004");
+ System.setProperty("socket.proxyHost", "e");
+ System.setProperty("socket.proxyPort", "1005");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 1001))),
+ proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("b", 1002))),
+ proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("c", 1003))),
+ proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(socketUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ }
+
+ public void testProxyPortOnly() throws URISyntaxException {
+ System.setProperty("ftp.proxyPort", "1001");
+ System.setProperty("http.proxyPort", "1002");
+ System.setProperty("https.proxyPort", "1003");
+ System.setProperty("other.proxyPort", "1004");
+ System.setProperty("socket.proxyPort", "1005");
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(socketUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ }
+
+ public void testHttpsDoesNotUseHttpProperties() throws URISyntaxException {
+ System.setProperty("http.proxyHost", "a");
+ System.setProperty("http.proxyPort", "1001");
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(httpsUri));
+ }
+
+ public void testProxyHost() throws URISyntaxException {
+ System.setProperty("proxyHost", "a");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 443))),
+ proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(socketUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ }
+
+ public void testHttpProxyHostPreferredOverProxyHost() throws URISyntaxException {
+ System.setProperty("http.proxyHost", "a");
+ System.setProperty("proxyHost", "b");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(httpUri));
+ }
+
+ public void testSocksProxyHost() throws URISyntaxException {
+ System.setProperty("socksProxyHost", "a");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1080))),
+ proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1080))),
+ proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1080))),
+ proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1080))),
+ proxySelector.select(socketUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ }
+
+ public void testSocksProxyHostAndPort() throws URISyntaxException {
+ System.setProperty("socksProxyHost", "a");
+ System.setProperty("socksProxyPort", "1001");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1001))),
+ proxySelector.select(ftpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1001))),
+ proxySelector.select(httpUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1001))),
+ proxySelector.select(httpsUri));
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.SOCKS, createUnresolved("a", 1001))),
+ proxySelector.select(socketUri));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY), proxySelector.select(otherUri));
+ }
+
+ public void testNonProxyHostsFtp() throws URISyntaxException {
+ System.setProperty("ftp.nonProxyHosts", "*.com");
+ System.setProperty("ftp.proxyHost", "a");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(new URI("ftp://foo.net")));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY),
+ proxySelector.select(new URI("ftp://foo.com")));
+ }
+
+ public void testNonProxyHostsHttp() throws URISyntaxException {
+ System.setProperty("http.nonProxyHosts", "*.com");
+ System.setProperty("http.proxyHost", "a");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(new URI("http://foo.net")));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY),
+ proxySelector.select(new URI("http://foo.com")));
+ }
+
+ public void testNonProxyHostsHttps() throws URISyntaxException {
+ System.setProperty("https.nonProxyHosts", "*.com");
+ System.setProperty("https.proxyHost", "a");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 443))),
+ proxySelector.select(new URI("https://foo.net")));
+ assertEquals(Arrays.asList(Proxy.NO_PROXY),
+ proxySelector.select(new URI("https://foo.com")));
+ }
+
+ public void testSchemeCaseSensitive() throws URISyntaxException {
+ System.setProperty("http.proxyHost", "a");
+ assertEquals(Arrays.asList(new Proxy(Proxy.Type.HTTP, createUnresolved("a", 80))),
+ proxySelector.select(new URI("HTTP://foo.net")));
+ }
+}