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 #include "net/proxy_resolution/proxy_config_service_android.h"
6
7 #include <map>
8 #include <memory>
9 #include <string>
10
11 #include "base/compiler_specific.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback_helpers.h"
14 #include "base/run_loop.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "net/proxy_resolution/proxy_config_with_annotation.h"
17 #include "net/proxy_resolution/proxy_info.h"
18 #include "net/test/test_with_task_environment.h"
19 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 // Must come after all headers that specialize FromJniType() / ToJniType().
23 #include "net/android/net_tests_jni/AndroidProxyConfigServiceTestUtil_jni.h"
24
25 namespace net {
26
27 namespace {
28
29 class TestObserver : public ProxyConfigService::Observer {
30 public:
TestObserver()31 TestObserver() : availability_(ProxyConfigService::CONFIG_UNSET) {}
32
33 // ProxyConfigService::Observer:
OnProxyConfigChanged(const ProxyConfigWithAnnotation & config,ProxyConfigService::ConfigAvailability availability)34 void OnProxyConfigChanged(
35 const ProxyConfigWithAnnotation& config,
36 ProxyConfigService::ConfigAvailability availability) override {
37 config_ = config;
38 availability_ = availability;
39 }
40
availability() const41 ProxyConfigService::ConfigAvailability availability() const {
42 return availability_;
43 }
44
config() const45 const ProxyConfigWithAnnotation& config() const { return config_; }
46
47 private:
48 ProxyConfigWithAnnotation config_;
49 ProxyConfigService::ConfigAvailability availability_;
50 };
51
52 // Helper class that simply prepares Java's Looper on construction.
53 class JavaLooperPreparer {
54 public:
JavaLooperPreparer()55 JavaLooperPreparer() {
56 Java_AndroidProxyConfigServiceTestUtil_prepareLooper(
57 base::android::AttachCurrentThread());
58 }
59 };
60
61 } // namespace
62
63 typedef std::map<std::string, std::string> StringMap;
64
65 class ProxyConfigServiceAndroidTestBase : public TestWithTaskEnvironment {
66 protected:
67 // Note that the current thread's message loop is initialized by the test
68 // suite (see net/test/net_test_suite.cc).
ProxyConfigServiceAndroidTestBase(const StringMap & initial_configuration)69 explicit ProxyConfigServiceAndroidTestBase(
70 const StringMap& initial_configuration)
71 : configuration_(initial_configuration),
72 service_(
73 base::SingleThreadTaskRunner::GetCurrentDefault(),
74 base::SingleThreadTaskRunner::GetCurrentDefault(),
75 base::BindRepeating(&ProxyConfigServiceAndroidTestBase::GetProperty,
76 base::Unretained(this))) {}
77
78 ~ProxyConfigServiceAndroidTestBase() override = default;
79
80 // testing::Test:
SetUp()81 void SetUp() override {
82 base::RunLoop().RunUntilIdle();
83 service_.AddObserver(&observer_);
84 }
85
TearDown()86 void TearDown() override { service_.RemoveObserver(&observer_); }
87
ClearConfiguration()88 void ClearConfiguration() {
89 configuration_.clear();
90 }
91
AddProperty(const std::string & key,const std::string & value)92 void AddProperty(const std::string& key, const std::string& value) {
93 configuration_[key] = value;
94 }
95
GetProperty(const std::string & key)96 std::string GetProperty(const std::string& key) {
97 StringMap::const_iterator it = configuration_.find(key);
98 if (it == configuration_.end())
99 return std::string();
100 return it->second;
101 }
102
ProxySettingsChangedTo(const std::string & host,int port,const std::string & pac_url,const std::vector<std::string> & exclusion_list)103 void ProxySettingsChangedTo(const std::string& host,
104 int port,
105 const std::string& pac_url,
106 const std::vector<std::string>& exclusion_list) {
107 service_.ProxySettingsChangedTo(host, port, pac_url, exclusion_list);
108 base::RunLoop().RunUntilIdle();
109 }
110
ProxySettingsChanged()111 void ProxySettingsChanged() {
112 service_.ProxySettingsChanged();
113 base::RunLoop().RunUntilIdle();
114 }
115
TestMapping(const std::string & url,const std::string & expected)116 void TestMapping(const std::string& url, const std::string& expected) {
117 ProxyConfigService::ConfigAvailability availability;
118 ProxyConfigWithAnnotation proxy_config;
119 availability = service_.GetLatestProxyConfig(&proxy_config);
120 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, availability);
121 ProxyInfo proxy_info;
122 proxy_config.value().proxy_rules().Apply(GURL(url), &proxy_info);
123 EXPECT_EQ(expected, proxy_info.ToDebugString());
124 }
125
SetProxyOverride(const ProxyConfigServiceAndroid::ProxyOverrideRule & rule,const std::vector<std::string> & bypass_rules,const bool reverse_bypass,base::OnceClosure callback)126 void SetProxyOverride(
127 const ProxyConfigServiceAndroid::ProxyOverrideRule& rule,
128 const std::vector<std::string>& bypass_rules,
129 const bool reverse_bypass,
130 base::OnceClosure callback) {
131 std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> rules;
132 rules.push_back(rule);
133 SetProxyOverride(rules, bypass_rules, reverse_bypass, std::move(callback));
134 }
135
SetProxyOverride(const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> & rules,const std::vector<std::string> & bypass_rules,const bool reverse_bypass,base::OnceClosure callback)136 void SetProxyOverride(
137 const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>& rules,
138 const std::vector<std::string>& bypass_rules,
139 const bool reverse_bypass,
140 base::OnceClosure callback) {
141 service_.SetProxyOverride(rules, bypass_rules, reverse_bypass,
142 std::move(callback));
143 base::RunLoop().RunUntilIdle();
144 }
145
ClearProxyOverride(base::OnceClosure callback)146 void ClearProxyOverride(base::OnceClosure callback) {
147 service_.ClearProxyOverride(std::move(callback));
148 base::RunLoop().RunUntilIdle();
149 }
150
151 StringMap configuration_;
152 TestObserver observer_;
153 // |java_looper_preparer_| appears before |service_| so that Java's Looper is
154 // prepared before constructing |service_| as it creates a ProxyChangeListener
155 // which requires a Looper.
156 JavaLooperPreparer java_looper_preparer_;
157 ProxyConfigServiceAndroid service_;
158 };
159
160 class ProxyConfigServiceAndroidTest : public ProxyConfigServiceAndroidTestBase {
161 public:
ProxyConfigServiceAndroidTest()162 ProxyConfigServiceAndroidTest()
163 : ProxyConfigServiceAndroidTestBase(StringMap()) {}
164 };
165
166 class ProxyConfigServiceAndroidWithInitialConfigTest
167 : public ProxyConfigServiceAndroidTestBase {
168 public:
ProxyConfigServiceAndroidWithInitialConfigTest()169 ProxyConfigServiceAndroidWithInitialConfigTest()
170 : ProxyConfigServiceAndroidTestBase(MakeInitialConfiguration()) {}
171
172 private:
MakeInitialConfiguration()173 StringMap MakeInitialConfiguration() {
174 StringMap initial_configuration;
175 initial_configuration["http.proxyHost"] = "httpproxy.com";
176 initial_configuration["http.proxyPort"] = "8080";
177 return initial_configuration;
178 }
179 };
180
TEST_F(ProxyConfigServiceAndroidTest,TestChangePropertiesNotification)181 TEST_F(ProxyConfigServiceAndroidTest, TestChangePropertiesNotification) {
182 // Set up a non-empty configuration
183 AddProperty("http.proxyHost", "localhost");
184 ProxySettingsChanged();
185 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, observer_.availability());
186 EXPECT_FALSE(observer_.config().value().proxy_rules().empty());
187
188 // Set up an empty configuration
189 ClearConfiguration();
190 ProxySettingsChanged();
191 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, observer_.availability());
192 EXPECT_TRUE(observer_.config().value().proxy_rules().empty());
193 }
194
TEST_F(ProxyConfigServiceAndroidWithInitialConfigTest,TestInitialConfig)195 TEST_F(ProxyConfigServiceAndroidWithInitialConfigTest, TestInitialConfig) {
196 // Make sure that the initial config is set.
197 TestMapping("ftp://example.com/", "DIRECT");
198 TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
199
200 // Override the initial configuration.
201 ClearConfiguration();
202 AddProperty("http.proxyHost", "httpproxy.com");
203 ProxySettingsChanged();
204 TestMapping("http://example.com/", "PROXY httpproxy.com:80");
205 }
206
TEST_F(ProxyConfigServiceAndroidTest,TestClearProxy)207 TEST_F(ProxyConfigServiceAndroidTest, TestClearProxy) {
208 AddProperty("http.proxyHost", "httpproxy.com");
209 ProxySettingsChanged();
210 TestMapping("http://example.com/", "PROXY httpproxy.com:80");
211
212 // These values are used in ProxyChangeListener.java to indicate a direct
213 // proxy connection.
214 ProxySettingsChangedTo("", 0, "", {});
215 TestMapping("http://example.com/", "DIRECT");
216 }
217
218 struct ProxyCallback {
ProxyCallbacknet::ProxyCallback219 ProxyCallback()
220 : callback(base::BindOnce(&ProxyCallback::Call, base::Unretained(this))) {
221 }
222
Callnet::ProxyCallback223 void Call() { called = true; }
224
225 bool called = false;
226 base::OnceClosure callback;
227 };
228
TEST_F(ProxyConfigServiceAndroidTest,TestProxyOverrideCallback)229 TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideCallback) {
230 ProxyCallback proxyCallback;
231 ASSERT_FALSE(proxyCallback.called);
232 ClearProxyOverride(std::move(proxyCallback.callback));
233 base::RunLoop().RunUntilIdle();
234 EXPECT_TRUE(proxyCallback.called);
235 }
236
TEST_F(ProxyConfigServiceAndroidTest,TestProxyOverrideSchemes)237 TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideSchemes) {
238 std::vector<std::string> bypass_rules;
239
240 // Check that webview uses the default proxy
241 TestMapping("http://example.com/", "DIRECT");
242 TestMapping("https://example.com/", "DIRECT");
243 TestMapping("ftp://example.com/", "DIRECT");
244
245 SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, false,
246 base::DoNothing());
247 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
248 TestMapping("https://example.com/", "PROXY httpoverrideproxy.com:200");
249 TestMapping("ftp://example.com/", "PROXY httpoverrideproxy.com:200");
250
251 // Check that webview uses the custom proxy only for https
252 SetProxyOverride({"https", "httpoverrideproxy.com:200"}, bypass_rules, false,
253 base::DoNothing());
254 TestMapping("http://example.com/", "DIRECT");
255 TestMapping("https://example.com/", "PROXY httpoverrideproxy.com:200");
256 TestMapping("ftp://example.com/", "DIRECT");
257
258 // Check that webview uses the default proxy
259 ClearProxyOverride(base::DoNothing());
260 TestMapping("http://example.com/", "DIRECT");
261 TestMapping("https://example.com/", "DIRECT");
262 TestMapping("ftp://example.com/", "DIRECT");
263 }
264
TEST_F(ProxyConfigServiceAndroidTest,TestProxyOverridePorts)265 TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverridePorts) {
266 std::vector<std::string> bypass_rules;
267
268 // Check that webview uses the default proxy
269 TestMapping("http://example.com/", "DIRECT");
270 TestMapping("https://example.com/", "DIRECT");
271 TestMapping("ftp://example.com/", "DIRECT");
272
273 // Check that webview uses port 80 for http proxies
274 SetProxyOverride({"*", "httpoverrideproxy.com"}, bypass_rules, false,
275 base::DoNothing());
276 TestMapping("http://example.com:444", "PROXY httpoverrideproxy.com:80");
277 TestMapping("https://example.com:2222", "PROXY httpoverrideproxy.com:80");
278 TestMapping("ftp://example.com:15", "PROXY httpoverrideproxy.com:80");
279
280 // Check that webview uses port 443 for https proxies
281 SetProxyOverride({"*", "https://httpoverrideproxy.com"}, bypass_rules, false,
282 base::DoNothing());
283 TestMapping("http://example.com:8080", "HTTPS httpoverrideproxy.com:443");
284 TestMapping("https://example.com:1111", "HTTPS httpoverrideproxy.com:443");
285 TestMapping("ftp://example.com:752", "HTTPS httpoverrideproxy.com:443");
286
287 // Check that webview uses custom port
288 SetProxyOverride({"*", "https://httpoverrideproxy.com:777"}, bypass_rules,
289 false, base::DoNothing());
290 TestMapping("http://example.com:8080", "HTTPS httpoverrideproxy.com:777");
291 TestMapping("https://example.com:1111", "HTTPS httpoverrideproxy.com:777");
292 TestMapping("ftp://example.com:752", "HTTPS httpoverrideproxy.com:777");
293
294 ClearProxyOverride(base::DoNothing());
295 }
296
TEST_F(ProxyConfigServiceAndroidTest,TestProxyOverrideMultipleRules)297 TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideMultipleRules) {
298 std::vector<std::string> bypass_rules;
299
300 // Multiple rules with schemes are valid
301 std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> rules;
302 rules.emplace_back("http", "httpoverrideproxy.com");
303 rules.emplace_back("https", "https://httpoverrideproxy.com");
304 SetProxyOverride(rules, bypass_rules, false, base::DoNothing());
305 TestMapping("https://example.com/", "HTTPS httpoverrideproxy.com:443");
306 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:80");
307
308 // Rules with and without scheme can be combined
309 rules.clear();
310 rules.emplace_back("http", "overrideproxy1.com");
311 rules.emplace_back("*", "overrideproxy2.com");
312 SetProxyOverride(rules, bypass_rules, false, base::DoNothing());
313 TestMapping("https://example.com/", "PROXY overrideproxy2.com:80");
314 TestMapping("http://example.com/", "PROXY overrideproxy1.com:80");
315
316 ClearProxyOverride(base::DoNothing());
317 }
318
TEST_F(ProxyConfigServiceAndroidTest,TestProxyOverrideListOfRules)319 TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideListOfRules) {
320 std::vector<std::string> bypass_rules;
321
322 std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> rules;
323 rules.emplace_back("http", "httpproxy1");
324 rules.emplace_back("*", "socks5://fallback1");
325 rules.emplace_back("http", "httpproxy2");
326 rules.emplace_back("*", "fallback2");
327 rules.emplace_back("*", "direct://");
328 SetProxyOverride(rules, bypass_rules, false, base::DoNothing());
329
330 TestMapping("http://example.com", "PROXY httpproxy1:80;PROXY httpproxy2:80");
331 TestMapping("https://example.com",
332 "SOCKS5 fallback1:1080;PROXY fallback2:80;DIRECT");
333 }
334
TEST_F(ProxyConfigServiceAndroidTest,TestOverrideAndProxy)335 TEST_F(ProxyConfigServiceAndroidTest, TestOverrideAndProxy) {
336 std::vector<std::string> bypass_rules;
337 bypass_rules.push_back("www.excluded.com");
338
339 // Check that webview uses the default proxy
340 TestMapping("http://example.com/", "DIRECT");
341
342 // Check that webview uses the custom proxy
343 SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, false,
344 base::DoNothing());
345 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
346
347 // Check that webview continues to use the custom proxy
348 AddProperty("http.proxyHost", "httpsomeproxy.com");
349 ProxySettingsChanged();
350 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
351 TestMapping("http://www.excluded.com/", "DIRECT");
352
353 // Check that webview uses the non default proxy
354 ClearProxyOverride(base::DoNothing());
355 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
356 }
357
TEST_F(ProxyConfigServiceAndroidTest,TestProxyAndOverride)358 TEST_F(ProxyConfigServiceAndroidTest, TestProxyAndOverride) {
359 std::vector<std::string> bypass_rules;
360
361 // Check that webview uses the default proxy
362 TestMapping("http://example.com/", "DIRECT");
363
364 // Check that webview uses the non default proxy
365 AddProperty("http.proxyHost", "httpsomeproxy.com");
366 ProxySettingsChanged();
367 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
368
369 // Check that webview uses the custom proxy
370 SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, false,
371 base::DoNothing());
372 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
373
374 // Check that webview uses the non default proxy
375 ClearProxyOverride(base::DoNothing());
376 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
377 }
378
TEST_F(ProxyConfigServiceAndroidTest,TestOverrideThenProxy)379 TEST_F(ProxyConfigServiceAndroidTest, TestOverrideThenProxy) {
380 std::vector<std::string> bypass_rules;
381
382 // Check that webview uses the default proxy
383 TestMapping("http://example.com/", "DIRECT");
384
385 // Check that webview uses the custom proxy
386 SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, false,
387 base::DoNothing());
388 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
389
390 // Check that webview uses the default proxy
391 ClearProxyOverride(base::DoNothing());
392 TestMapping("http://example.com/", "DIRECT");
393
394 // Check that webview uses the non default proxy
395 AddProperty("http.proxyHost", "httpsomeproxy.com");
396 ProxySettingsChanged();
397 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
398 }
399
TEST_F(ProxyConfigServiceAndroidTest,TestClearOverride)400 TEST_F(ProxyConfigServiceAndroidTest, TestClearOverride) {
401 std::vector<std::string> bypass_rules;
402
403 // Check that webview uses the default proxy
404 TestMapping("http://example.com/", "DIRECT");
405
406 // Check that webview uses the default proxy
407 ClearProxyOverride(base::DoNothing());
408 TestMapping("http://example.com/", "DIRECT");
409 }
410
TEST_F(ProxyConfigServiceAndroidTest,TestProxyAndClearOverride)411 TEST_F(ProxyConfigServiceAndroidTest, TestProxyAndClearOverride) {
412 std::vector<std::string> bypass_rules;
413
414 // Check that webview uses the non default proxy
415 AddProperty("http.proxyHost", "httpsomeproxy.com");
416 ProxySettingsChanged();
417 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
418
419 // Check that webview uses the non default proxy
420 ClearProxyOverride(base::DoNothing());
421 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
422 }
423
TEST_F(ProxyConfigServiceAndroidTest,TestOverrideBypassRules)424 TEST_F(ProxyConfigServiceAndroidTest, TestOverrideBypassRules) {
425 std::vector<std::string> bypass_rules;
426 bypass_rules.push_back("excluded.com");
427
428 // Check that webview uses the default proxy
429 TestMapping("http://excluded.com/", "DIRECT");
430 TestMapping("http://example.com/", "DIRECT");
431
432 // Check that webview handles the bypass rules correctly
433 SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, false,
434 base::DoNothing());
435 TestMapping("http://excluded.com/", "DIRECT");
436 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
437
438 // Check that webview uses the default proxy
439 ClearProxyOverride(base::DoNothing());
440 TestMapping("http://excluded.com/", "DIRECT");
441 TestMapping("http://example.com/", "DIRECT");
442 }
443
TEST_F(ProxyConfigServiceAndroidTest,TestOverrideToDirect)444 TEST_F(ProxyConfigServiceAndroidTest, TestOverrideToDirect) {
445 std::vector<std::string> bypass_rules;
446
447 // Check that webview uses the non default proxy
448 AddProperty("http.proxyHost", "httpsomeproxy.com");
449 ProxySettingsChanged();
450 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
451
452 // Check that webview uses no proxy
453 TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80");
454 SetProxyOverride({"*", "direct://"}, bypass_rules, false, base::DoNothing());
455 TestMapping("http://example.com/", "DIRECT");
456
457 ClearProxyOverride(base::DoNothing());
458 }
459
TEST_F(ProxyConfigServiceAndroidTest,TestReverseBypass)460 TEST_F(ProxyConfigServiceAndroidTest, TestReverseBypass) {
461 std::vector<std::string> bypass_rules;
462
463 // Check that webview uses the default proxy
464 TestMapping("http://example.com/", "DIRECT");
465 TestMapping("http://other.com/", "DIRECT");
466
467 // Use a reverse bypass list, that is, WebView will only apply the proxy
468 // settings to URLs in the bypass list
469 bypass_rules.push_back("http://example.com");
470 SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, true,
471 base::DoNothing());
472
473 // Check that URLs in the bypass list use the proxy
474 TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200");
475 TestMapping("http://other.com/", "DIRECT");
476 }
477
478 // !! The following test cases are automatically generated from
479 // !! net/android/tools/proxy_test_cases.py.
480 // !! Please edit that file instead of editing the test cases below and
481 // !! update also the corresponding Java unit tests in
482 // !! AndroidProxySelectorTest.java
483
TEST_F(ProxyConfigServiceAndroidTest,NoProxy)484 TEST_F(ProxyConfigServiceAndroidTest, NoProxy) {
485 // Test direct mapping when no proxy defined.
486 ProxySettingsChanged();
487 TestMapping("ftp://example.com/", "DIRECT");
488 TestMapping("http://example.com/", "DIRECT");
489 TestMapping("https://example.com/", "DIRECT");
490 }
491
TEST_F(ProxyConfigServiceAndroidTest,HttpProxyHostAndPort)492 TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostAndPort) {
493 // Test http.proxyHost and http.proxyPort works.
494 AddProperty("http.proxyHost", "httpproxy.com");
495 AddProperty("http.proxyPort", "8080");
496 ProxySettingsChanged();
497 TestMapping("ftp://example.com/", "DIRECT");
498 TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
499 TestMapping("https://example.com/", "DIRECT");
500 }
501
TEST_F(ProxyConfigServiceAndroidTest,HttpProxyHostOnly)502 TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostOnly) {
503 // We should get the default port (80) for proxied hosts.
504 AddProperty("http.proxyHost", "httpproxy.com");
505 ProxySettingsChanged();
506 TestMapping("ftp://example.com/", "DIRECT");
507 TestMapping("http://example.com/", "PROXY httpproxy.com:80");
508 TestMapping("https://example.com/", "DIRECT");
509 }
510
TEST_F(ProxyConfigServiceAndroidTest,HttpProxyPortOnly)511 TEST_F(ProxyConfigServiceAndroidTest, HttpProxyPortOnly) {
512 // http.proxyPort only should not result in any hosts being proxied.
513 AddProperty("http.proxyPort", "8080");
514 ProxySettingsChanged();
515 TestMapping("ftp://example.com/", "DIRECT");
516 TestMapping("http://example.com/", "DIRECT");
517 TestMapping("https://example.com/", "DIRECT");
518 }
519
TEST_F(ProxyConfigServiceAndroidTest,HttpNonProxyHosts1)520 TEST_F(ProxyConfigServiceAndroidTest, HttpNonProxyHosts1) {
521 // Test that HTTP non proxy hosts are mapped correctly
522 AddProperty("http.nonProxyHosts", "slashdot.org");
523 AddProperty("http.proxyHost", "httpproxy.com");
524 AddProperty("http.proxyPort", "8080");
525 ProxySettingsChanged();
526 TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
527 TestMapping("http://slashdot.org/", "DIRECT");
528 }
529
TEST_F(ProxyConfigServiceAndroidTest,HttpNonProxyHosts2)530 TEST_F(ProxyConfigServiceAndroidTest, HttpNonProxyHosts2) {
531 // Test that | pattern works.
532 AddProperty("http.nonProxyHosts", "slashdot.org|freecode.net");
533 AddProperty("http.proxyHost", "httpproxy.com");
534 AddProperty("http.proxyPort", "8080");
535 ProxySettingsChanged();
536 TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
537 TestMapping("http://freecode.net/", "DIRECT");
538 TestMapping("http://slashdot.org/", "DIRECT");
539 }
540
TEST_F(ProxyConfigServiceAndroidTest,HttpNonProxyHosts3)541 TEST_F(ProxyConfigServiceAndroidTest, HttpNonProxyHosts3) {
542 // Test that * pattern works.
543 AddProperty("http.nonProxyHosts", "*example.com");
544 AddProperty("http.proxyHost", "httpproxy.com");
545 AddProperty("http.proxyPort", "8080");
546 ProxySettingsChanged();
547 TestMapping("http://example.com/", "DIRECT");
548 TestMapping("http://slashdot.org/", "PROXY httpproxy.com:8080");
549 TestMapping("http://www.example.com/", "DIRECT");
550 }
551
TEST_F(ProxyConfigServiceAndroidTest,FtpNonProxyHosts)552 TEST_F(ProxyConfigServiceAndroidTest, FtpNonProxyHosts) {
553 // Test that FTP non proxy hosts are mapped correctly
554 AddProperty("ftp.nonProxyHosts", "slashdot.org");
555 AddProperty("ftp.proxyHost", "httpproxy.com");
556 AddProperty("ftp.proxyPort", "8080");
557 ProxySettingsChanged();
558 TestMapping("ftp://example.com/", "PROXY httpproxy.com:8080");
559 TestMapping("http://example.com/", "DIRECT");
560 }
561
TEST_F(ProxyConfigServiceAndroidTest,FtpProxyHostAndPort)562 TEST_F(ProxyConfigServiceAndroidTest, FtpProxyHostAndPort) {
563 // Test ftp.proxyHost and ftp.proxyPort works.
564 AddProperty("ftp.proxyHost", "httpproxy.com");
565 AddProperty("ftp.proxyPort", "8080");
566 ProxySettingsChanged();
567 TestMapping("ftp://example.com/", "PROXY httpproxy.com:8080");
568 TestMapping("http://example.com/", "DIRECT");
569 TestMapping("https://example.com/", "DIRECT");
570 }
571
TEST_F(ProxyConfigServiceAndroidTest,FtpProxyHostOnly)572 TEST_F(ProxyConfigServiceAndroidTest, FtpProxyHostOnly) {
573 // Test ftp.proxyHost and default port.
574 AddProperty("ftp.proxyHost", "httpproxy.com");
575 ProxySettingsChanged();
576 TestMapping("ftp://example.com/", "PROXY httpproxy.com:80");
577 TestMapping("http://example.com/", "DIRECT");
578 TestMapping("https://example.com/", "DIRECT");
579 }
580
TEST_F(ProxyConfigServiceAndroidTest,HttpsProxyHostAndPort)581 TEST_F(ProxyConfigServiceAndroidTest, HttpsProxyHostAndPort) {
582 // Test https.proxyHost and https.proxyPort works.
583 AddProperty("https.proxyHost", "httpproxy.com");
584 AddProperty("https.proxyPort", "8080");
585 ProxySettingsChanged();
586 TestMapping("ftp://example.com/", "DIRECT");
587 TestMapping("http://example.com/", "DIRECT");
588 TestMapping("https://example.com/", "PROXY httpproxy.com:8080");
589 }
590
TEST_F(ProxyConfigServiceAndroidTest,HttpsProxyHostOnly)591 TEST_F(ProxyConfigServiceAndroidTest, HttpsProxyHostOnly) {
592 // Test https.proxyHost and default port.
593 AddProperty("https.proxyHost", "httpproxy.com");
594 ProxySettingsChanged();
595 TestMapping("ftp://example.com/", "DIRECT");
596 TestMapping("http://example.com/", "DIRECT");
597 TestMapping("https://example.com/", "PROXY httpproxy.com:80");
598 }
599
TEST_F(ProxyConfigServiceAndroidTest,HttpProxyHostIPv6)600 TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostIPv6) {
601 // Test IPv6 https.proxyHost and default port.
602 AddProperty("http.proxyHost", "a:b:c::d:1");
603 ProxySettingsChanged();
604 TestMapping("ftp://example.com/", "DIRECT");
605 TestMapping("http://example.com/", "PROXY [a:b:c::d:1]:80");
606 }
607
TEST_F(ProxyConfigServiceAndroidTest,HttpProxyHostAndPortIPv6)608 TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostAndPortIPv6) {
609 // Test IPv6 http.proxyHost and http.proxyPort works.
610 AddProperty("http.proxyHost", "a:b:c::d:1");
611 AddProperty("http.proxyPort", "8080");
612 ProxySettingsChanged();
613 TestMapping("ftp://example.com/", "DIRECT");
614 TestMapping("http://example.com/", "PROXY [a:b:c::d:1]:8080");
615 }
616
TEST_F(ProxyConfigServiceAndroidTest,HttpProxyHostAndInvalidPort)617 TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostAndInvalidPort) {
618 // Test invalid http.proxyPort does not crash.
619 AddProperty("http.proxyHost", "a:b:c::d:1");
620 AddProperty("http.proxyPort", "65536");
621 ProxySettingsChanged();
622 TestMapping("ftp://example.com/", "DIRECT");
623 TestMapping("http://example.com/", "DIRECT");
624 }
625
TEST_F(ProxyConfigServiceAndroidTest,DefaultProxyExplictPort)626 TEST_F(ProxyConfigServiceAndroidTest, DefaultProxyExplictPort) {
627 // Default http proxy is used if a scheme-specific one is not found.
628 AddProperty("ftp.proxyHost", "httpproxy.com");
629 AddProperty("ftp.proxyPort", "8080");
630 AddProperty("proxyHost", "defaultproxy.com");
631 AddProperty("proxyPort", "8080");
632 ProxySettingsChanged();
633 TestMapping("ftp://example.com/", "PROXY httpproxy.com:8080");
634 TestMapping("http://example.com/", "PROXY defaultproxy.com:8080");
635 TestMapping("https://example.com/", "PROXY defaultproxy.com:8080");
636 }
637
TEST_F(ProxyConfigServiceAndroidTest,DefaultProxyDefaultPort)638 TEST_F(ProxyConfigServiceAndroidTest, DefaultProxyDefaultPort) {
639 // Check that the default proxy port is as expected.
640 AddProperty("proxyHost", "defaultproxy.com");
641 ProxySettingsChanged();
642 TestMapping("http://example.com/", "PROXY defaultproxy.com:80");
643 TestMapping("https://example.com/", "PROXY defaultproxy.com:80");
644 }
645
TEST_F(ProxyConfigServiceAndroidTest,FallbackToSocks)646 TEST_F(ProxyConfigServiceAndroidTest, FallbackToSocks) {
647 // SOCKS proxy is used if scheme-specific one is not found.
648 AddProperty("http.proxyHost", "defaultproxy.com");
649 AddProperty("socksProxyHost", "socksproxy.com");
650 ProxySettingsChanged();
651 TestMapping("ftp://example.com", "SOCKS5 socksproxy.com:1080");
652 TestMapping("http://example.com/", "PROXY defaultproxy.com:80");
653 TestMapping("https://example.com/", "SOCKS5 socksproxy.com:1080");
654 }
655
TEST_F(ProxyConfigServiceAndroidTest,SocksExplicitPort)656 TEST_F(ProxyConfigServiceAndroidTest, SocksExplicitPort) {
657 // SOCKS proxy port is used if specified
658 AddProperty("socksProxyHost", "socksproxy.com");
659 AddProperty("socksProxyPort", "9000");
660 ProxySettingsChanged();
661 TestMapping("http://example.com/", "SOCKS5 socksproxy.com:9000");
662 }
663
TEST_F(ProxyConfigServiceAndroidTest,HttpProxySupercedesSocks)664 TEST_F(ProxyConfigServiceAndroidTest, HttpProxySupercedesSocks) {
665 // SOCKS proxy is ignored if default HTTP proxy defined.
666 AddProperty("proxyHost", "defaultproxy.com");
667 AddProperty("socksProxyHost", "socksproxy.com");
668 AddProperty("socksProxyPort", "9000");
669 ProxySettingsChanged();
670 TestMapping("http://example.com/", "PROXY defaultproxy.com:80");
671 }
672
673 } // namespace net
674