1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /** 6 * Test suite for Android's default ProxySelector implementation. The purpose of these tests 7 * is to check that the behaviour of the ProxySelector implementation matches what we have 8 * implemented in net/proxy_resolution/proxy_config_service_android.cc. 9 * 10 * IMPORTANT: These test cases are generated from net/android/tools/proxy_test_cases.py, so if any 11 * of these tests fail, please be sure to edit that file and regenerate the test cases here and also 12 * in net/proxy_resolution/proxy_config_service_android_unittests.cc if required. 13 */ 14 package org.chromium.net; 15 16 import android.os.Build; 17 18 import androidx.test.filters.SmallTest; 19 20 import org.junit.After; 21 import org.junit.Assert; 22 import org.junit.Before; 23 import org.junit.Test; 24 import org.junit.runner.RunWith; 25 26 import org.chromium.base.test.BaseJUnit4ClassRunner; 27 import org.chromium.base.test.util.Batch; 28 import org.chromium.base.test.util.Feature; 29 30 import java.net.Proxy; 31 import java.net.ProxySelector; 32 import java.net.URI; 33 import java.net.URISyntaxException; 34 import java.util.List; 35 import java.util.Properties; 36 37 @RunWith(BaseJUnit4ClassRunner.class) 38 @Batch(Batch.PER_CLASS) 39 public class AndroidProxySelectorTest { 40 Properties mProperties; 41 AndroidProxySelectorTest()42 public AndroidProxySelectorTest() { 43 // Start with a clean slate in case there is a system proxy configured. 44 mProperties = new Properties(); 45 } 46 47 @Before setUp()48 public void setUp() { 49 System.setProperties(mProperties); 50 } 51 52 @After tearDown()53 public void tearDown() { 54 System.setProperties(mProperties); 55 } 56 toString(Proxy proxy)57 static String toString(Proxy proxy) { 58 if (proxy.equals(Proxy.NO_PROXY)) return "DIRECT"; 59 // java.net.Proxy only knows about http and socks proxies. 60 Proxy.Type type = proxy.type(); 61 switch (type) { 62 case HTTP: 63 return "PROXY " + proxy.address().toString(); 64 case SOCKS: 65 return "SOCKS5 " + proxy.address().toString(); 66 case DIRECT: 67 return "DIRECT"; 68 default: 69 // If a new proxy type is supported in future, add a case to match it. 70 Assert.fail("Unknown proxy type" + type); 71 return "unknown://"; 72 } 73 } 74 toString(List<Proxy> proxies)75 static String toString(List<Proxy> proxies) { 76 StringBuilder builder = new StringBuilder(); 77 for (Proxy proxy : proxies) { 78 if (builder.length() > 0) builder.append(';'); 79 builder.append(toString(proxy)); 80 } 81 return builder.toString(); 82 } 83 checkMapping(String url, String expected)84 static void checkMapping(String url, String expected) throws URISyntaxException { 85 URI uri = new URI(url); 86 List<Proxy> proxies = ProxySelector.getDefault().select(uri); 87 Assert.assertEquals("Mapping", expected, toString(proxies)); 88 } 89 90 /** 91 * Test direct mapping when no proxy defined. 92 * 93 * @throws Exception 94 */ 95 @Test 96 @SmallTest 97 @Feature({"AndroidWebView"}) testNoProxy()98 public void testNoProxy() throws Exception { 99 checkMapping("ftp://example.com/", "DIRECT"); 100 checkMapping("http://example.com/", "DIRECT"); 101 checkMapping("https://example.com/", "DIRECT"); 102 } 103 104 /** 105 * Test http.proxyHost and http.proxyPort works. 106 * 107 * @throws Exception 108 */ 109 @Test 110 @SmallTest 111 @Feature({"AndroidWebView"}) testHttpProxyHostAndPort()112 public void testHttpProxyHostAndPort() throws Exception { 113 System.setProperty("http.proxyHost", "httpproxy.com"); 114 System.setProperty("http.proxyPort", "8080"); 115 checkMapping("ftp://example.com/", "DIRECT"); 116 checkMapping("http://example.com/", "PROXY httpproxy.com:8080"); 117 checkMapping("https://example.com/", "DIRECT"); 118 } 119 120 /** 121 * We should get the default port (80) for proxied hosts. 122 * 123 * @throws Exception 124 */ 125 @Test 126 @SmallTest 127 @Feature({"AndroidWebView"}) testHttpProxyHostOnly()128 public void testHttpProxyHostOnly() throws Exception { 129 System.setProperty("http.proxyHost", "httpproxy.com"); 130 checkMapping("ftp://example.com/", "DIRECT"); 131 checkMapping("http://example.com/", "PROXY httpproxy.com:80"); 132 checkMapping("https://example.com/", "DIRECT"); 133 } 134 135 /** 136 * http.proxyPort only should not result in any hosts being proxied. 137 * 138 * @throws Exception 139 */ 140 @Test 141 @SmallTest 142 @Feature({"AndroidWebView"}) testHttpProxyPortOnly()143 public void testHttpProxyPortOnly() throws Exception { 144 System.setProperty("http.proxyPort", "8080"); 145 checkMapping("ftp://example.com/", "DIRECT"); 146 checkMapping("http://example.com/", "DIRECT"); 147 checkMapping("https://example.com/", "DIRECT"); 148 } 149 150 /** 151 * Test that HTTP non proxy hosts are mapped correctly 152 * 153 * @throws Exception 154 */ 155 @Test 156 @SmallTest 157 @Feature({"AndroidWebView"}) testHttpNonProxyHosts1()158 public void testHttpNonProxyHosts1() throws Exception { 159 System.setProperty("http.nonProxyHosts", "slashdot.org"); 160 System.setProperty("http.proxyHost", "httpproxy.com"); 161 System.setProperty("http.proxyPort", "8080"); 162 checkMapping("http://example.com/", "PROXY httpproxy.com:8080"); 163 checkMapping("http://slashdot.org/", "DIRECT"); 164 } 165 166 /** 167 * Test that | pattern works. 168 * 169 * @throws Exception 170 */ 171 @Test 172 @SmallTest 173 @Feature({"AndroidWebView"}) testHttpNonProxyHosts2()174 public void testHttpNonProxyHosts2() throws Exception { 175 System.setProperty("http.nonProxyHosts", "slashdot.org|freecode.net"); 176 System.setProperty("http.proxyHost", "httpproxy.com"); 177 System.setProperty("http.proxyPort", "8080"); 178 checkMapping("http://example.com/", "PROXY httpproxy.com:8080"); 179 checkMapping("http://freecode.net/", "DIRECT"); 180 checkMapping("http://slashdot.org/", "DIRECT"); 181 } 182 183 /** 184 * Test that * pattern works. 185 * 186 * @throws Exception 187 */ 188 @Test 189 @SmallTest 190 @Feature({"AndroidWebView"}) testHttpNonProxyHosts3()191 public void testHttpNonProxyHosts3() throws Exception { 192 System.setProperty("http.nonProxyHosts", "*example.com"); 193 System.setProperty("http.proxyHost", "httpproxy.com"); 194 System.setProperty("http.proxyPort", "8080"); 195 // TODO(jbudorick): Find an appropriate upper bound for this. crbug.com/726360 196 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 197 checkMapping("http://example.com/", "DIRECT"); 198 } 199 checkMapping("http://slashdot.org/", "PROXY httpproxy.com:8080"); 200 checkMapping("http://www.example.com/", "DIRECT"); 201 } 202 203 /** 204 * Test that FTP non proxy hosts are mapped correctly 205 * 206 * @throws Exception 207 */ 208 @Test 209 @SmallTest 210 @Feature({"AndroidWebView"}) testFtpNonProxyHosts()211 public void testFtpNonProxyHosts() throws Exception { 212 System.setProperty("ftp.nonProxyHosts", "slashdot.org"); 213 System.setProperty("ftp.proxyHost", "httpproxy.com"); 214 System.setProperty("ftp.proxyPort", "8080"); 215 checkMapping("ftp://example.com/", "PROXY httpproxy.com:8080"); 216 checkMapping("http://example.com/", "DIRECT"); 217 } 218 219 /** 220 * Test ftp.proxyHost and ftp.proxyPort works. 221 * 222 * @throws Exception 223 */ 224 @Test 225 @SmallTest 226 @Feature({"AndroidWebView"}) testFtpProxyHostAndPort()227 public void testFtpProxyHostAndPort() throws Exception { 228 System.setProperty("ftp.proxyHost", "httpproxy.com"); 229 System.setProperty("ftp.proxyPort", "8080"); 230 checkMapping("ftp://example.com/", "PROXY httpproxy.com:8080"); 231 checkMapping("http://example.com/", "DIRECT"); 232 checkMapping("https://example.com/", "DIRECT"); 233 } 234 235 /** 236 * Test ftp.proxyHost and default port. 237 * 238 * @throws Exception 239 */ 240 @Test 241 @SmallTest 242 @Feature({"AndroidWebView"}) testFtpProxyHostOnly()243 public void testFtpProxyHostOnly() throws Exception { 244 System.setProperty("ftp.proxyHost", "httpproxy.com"); 245 checkMapping("ftp://example.com/", "PROXY httpproxy.com:80"); 246 checkMapping("http://example.com/", "DIRECT"); 247 checkMapping("https://example.com/", "DIRECT"); 248 } 249 250 /** 251 * Test https.proxyHost and https.proxyPort works. 252 * 253 * @throws Exception 254 */ 255 @Test 256 @SmallTest 257 @Feature({"AndroidWebView"}) testHttpsProxyHostAndPort()258 public void testHttpsProxyHostAndPort() throws Exception { 259 System.setProperty("https.proxyHost", "httpproxy.com"); 260 System.setProperty("https.proxyPort", "8080"); 261 checkMapping("ftp://example.com/", "DIRECT"); 262 checkMapping("http://example.com/", "DIRECT"); 263 checkMapping("https://example.com/", "PROXY httpproxy.com:8080"); 264 } 265 266 /** 267 * Default http proxy is used if a scheme-specific one is not found. 268 * 269 * @throws Exception 270 */ 271 @Test 272 @SmallTest 273 @Feature({"AndroidWebView"}) testDefaultProxyExplictPort()274 public void testDefaultProxyExplictPort() throws Exception { 275 System.setProperty("ftp.proxyHost", "httpproxy.com"); 276 System.setProperty("ftp.proxyPort", "8080"); 277 System.setProperty("proxyHost", "defaultproxy.com"); 278 System.setProperty("proxyPort", "8080"); 279 checkMapping("ftp://example.com/", "PROXY httpproxy.com:8080"); 280 checkMapping("http://example.com/", "PROXY defaultproxy.com:8080"); 281 checkMapping("https://example.com/", "PROXY defaultproxy.com:8080"); 282 } 283 284 /** 285 * SOCKS proxy is used if scheme-specific one is not found. 286 * 287 * @throws Exception 288 */ 289 @Test 290 @SmallTest 291 @Feature({"AndroidWebView"}) testFallbackToSocks()292 public void testFallbackToSocks() throws Exception { 293 System.setProperty("http.proxyHost", "defaultproxy.com"); 294 System.setProperty("socksProxyHost", "socksproxy.com"); 295 checkMapping("ftp://example.com", "SOCKS5 socksproxy.com:1080"); 296 checkMapping("http://example.com/", "PROXY defaultproxy.com:80"); 297 checkMapping("https://example.com/", "SOCKS5 socksproxy.com:1080"); 298 } 299 300 /** 301 * SOCKS proxy port is used if specified 302 * 303 * @throws Exception 304 */ 305 @Test 306 @SmallTest 307 @Feature({"AndroidWebView"}) testSocksExplicitPort()308 public void testSocksExplicitPort() throws Exception { 309 System.setProperty("socksProxyHost", "socksproxy.com"); 310 System.setProperty("socksProxyPort", "9000"); 311 checkMapping("http://example.com/", "SOCKS5 socksproxy.com:9000"); 312 } 313 314 /** 315 * SOCKS proxy is ignored if default HTTP proxy defined. 316 * 317 * @throws Exception 318 */ 319 @Test 320 @SmallTest 321 @Feature({"AndroidWebView"}) testHttpProxySupercedesSocks()322 public void testHttpProxySupercedesSocks() throws Exception { 323 System.setProperty("proxyHost", "defaultproxy.com"); 324 System.setProperty("socksProxyHost", "socksproxy.com"); 325 System.setProperty("socksProxyPort", "9000"); 326 checkMapping("http://example.com/", "PROXY defaultproxy.com:80"); 327 } 328 } 329