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