1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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/proxy_config_service_linux.h" 6 7 #include <map> 8 #include <string> 9 #include <vector> 10 11 #include "base/bind.h" 12 #include "base/compiler_specific.h" 13 #include "base/files/file_path.h" 14 #include "base/files/file_util.h" 15 #include "base/format_macros.h" 16 #include "base/logging.h" 17 #include "base/strings/string_util.h" 18 #include "base/strings/stringprintf.h" 19 #include "base/synchronization/waitable_event.h" 20 #include "base/threading/thread.h" 21 #include "net/proxy/proxy_config.h" 22 #include "net/proxy/proxy_config_service_common_unittest.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/platform_test.h" 25 26 namespace net { 27 namespace { 28 29 // Set of values for all environment variables that we might 30 // query. NULL represents an unset variable. 31 struct EnvVarValues { 32 // The strange capitalization is so that the field matches the 33 // environment variable name exactly. 34 const char *DESKTOP_SESSION, *HOME, 35 *KDEHOME, *KDE_SESSION_VERSION, 36 *auto_proxy, *all_proxy, 37 *http_proxy, *https_proxy, *ftp_proxy, 38 *SOCKS_SERVER, *SOCKS_VERSION, 39 *no_proxy; 40 }; 41 42 // Undo macro pollution from GDK includes (from message_loop.h). 43 #undef TRUE 44 #undef FALSE 45 46 // So as to distinguish between an unset gconf boolean variable and 47 // one that is false. 48 enum BoolSettingValue { 49 UNSET = 0, TRUE, FALSE 50 }; 51 52 // Set of values for all gconf settings that we might query. 53 struct GConfValues { 54 // strings 55 const char *mode, *autoconfig_url, 56 *http_host, *secure_host, *ftp_host, *socks_host; 57 // integers 58 int http_port, secure_port, ftp_port, socks_port; 59 // booleans 60 BoolSettingValue use_proxy, same_proxy, use_auth; 61 // string list 62 std::vector<std::string> ignore_hosts; 63 }; 64 65 // Mapping from a setting name to the location of the corresponding 66 // value (inside a EnvVarValues or GConfValues struct). 67 template<typename key_type, typename value_type> 68 struct SettingsTable { 69 typedef std::map<key_type, value_type*> map_type; 70 71 // Gets the value from its location 72 value_type Get(key_type key) { 73 typename map_type::const_iterator it = settings.find(key); 74 // In case there's a typo or the unittest becomes out of sync. 75 CHECK(it != settings.end()) << "key " << key << " not found"; 76 value_type* value_ptr = it->second; 77 return *value_ptr; 78 } 79 80 map_type settings; 81 }; 82 83 class MockEnvironment : public base::Environment { 84 public: 85 MockEnvironment() { 86 #define ENTRY(x) table[#x] = &values.x 87 ENTRY(DESKTOP_SESSION); 88 ENTRY(HOME); 89 ENTRY(KDEHOME); 90 ENTRY(KDE_SESSION_VERSION); 91 ENTRY(auto_proxy); 92 ENTRY(all_proxy); 93 ENTRY(http_proxy); 94 ENTRY(https_proxy); 95 ENTRY(ftp_proxy); 96 ENTRY(no_proxy); 97 ENTRY(SOCKS_SERVER); 98 ENTRY(SOCKS_VERSION); 99 #undef ENTRY 100 Reset(); 101 } 102 103 // Zeroes all environment values. 104 void Reset() { 105 EnvVarValues zero_values = { 0 }; 106 values = zero_values; 107 } 108 109 // Begin base::Environment implementation. 110 virtual bool GetVar(const char* variable_name, std::string* result) OVERRIDE { 111 std::map<std::string, const char**>::iterator it = 112 table.find(variable_name); 113 if (it != table.end() && *(it->second) != NULL) { 114 // Note that the variable may be defined but empty. 115 *result = *(it->second); 116 return true; 117 } 118 return false; 119 } 120 121 virtual bool SetVar(const char* variable_name, const std::string& new_value) 122 OVERRIDE { 123 ADD_FAILURE(); 124 return false; 125 } 126 127 virtual bool UnSetVar(const char* variable_name) OVERRIDE { 128 ADD_FAILURE(); 129 return false; 130 } 131 // End base::Environment implementation. 132 133 // Intentionally public, for convenience when setting up a test. 134 EnvVarValues values; 135 136 private: 137 std::map<std::string, const char**> table; 138 }; 139 140 class MockSettingGetter 141 : public ProxyConfigServiceLinux::SettingGetter { 142 public: 143 typedef ProxyConfigServiceLinux::SettingGetter SettingGetter; 144 MockSettingGetter() { 145 #define ENTRY(key, field) \ 146 strings_table.settings[SettingGetter::key] = &values.field 147 ENTRY(PROXY_MODE, mode); 148 ENTRY(PROXY_AUTOCONF_URL, autoconfig_url); 149 ENTRY(PROXY_HTTP_HOST, http_host); 150 ENTRY(PROXY_HTTPS_HOST, secure_host); 151 ENTRY(PROXY_FTP_HOST, ftp_host); 152 ENTRY(PROXY_SOCKS_HOST, socks_host); 153 #undef ENTRY 154 #define ENTRY(key, field) \ 155 ints_table.settings[SettingGetter::key] = &values.field 156 ENTRY(PROXY_HTTP_PORT, http_port); 157 ENTRY(PROXY_HTTPS_PORT, secure_port); 158 ENTRY(PROXY_FTP_PORT, ftp_port); 159 ENTRY(PROXY_SOCKS_PORT, socks_port); 160 #undef ENTRY 161 #define ENTRY(key, field) \ 162 bools_table.settings[SettingGetter::key] = &values.field 163 ENTRY(PROXY_USE_HTTP_PROXY, use_proxy); 164 ENTRY(PROXY_USE_SAME_PROXY, same_proxy); 165 ENTRY(PROXY_USE_AUTHENTICATION, use_auth); 166 #undef ENTRY 167 string_lists_table.settings[SettingGetter::PROXY_IGNORE_HOSTS] = 168 &values.ignore_hosts; 169 Reset(); 170 } 171 172 // Zeros all environment values. 173 void Reset() { 174 GConfValues zero_values = { 0 }; 175 values = zero_values; 176 } 177 178 virtual bool Init( 179 const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner, 180 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) 181 OVERRIDE { 182 task_runner_ = glib_task_runner; 183 return true; 184 } 185 186 virtual void ShutDown() OVERRIDE {} 187 188 virtual bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate) 189 OVERRIDE { 190 return true; 191 } 192 193 virtual const scoped_refptr<base::SingleThreadTaskRunner>& 194 GetNotificationTaskRunner() OVERRIDE { 195 return task_runner_; 196 } 197 198 virtual ProxyConfigSource GetConfigSource() OVERRIDE { 199 return PROXY_CONFIG_SOURCE_TEST; 200 } 201 202 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { 203 const char* value = strings_table.Get(key); 204 if (value) { 205 *result = value; 206 return true; 207 } 208 return false; 209 } 210 211 virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE { 212 BoolSettingValue value = bools_table.Get(key); 213 switch (value) { 214 case UNSET: 215 return false; 216 case TRUE: 217 *result = true; 218 break; 219 case FALSE: 220 *result = false; 221 } 222 return true; 223 } 224 225 virtual bool GetInt(IntSetting key, int* result) OVERRIDE { 226 // We don't bother to distinguish unset keys from 0 values. 227 *result = ints_table.Get(key); 228 return true; 229 } 230 231 virtual bool GetStringList(StringListSetting key, 232 std::vector<std::string>* result) OVERRIDE { 233 *result = string_lists_table.Get(key); 234 // We don't bother to distinguish unset keys from empty lists. 235 return !result->empty(); 236 } 237 238 virtual bool BypassListIsReversed() OVERRIDE { 239 return false; 240 } 241 242 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { 243 return false; 244 } 245 246 // Intentionally public, for convenience when setting up a test. 247 GConfValues values; 248 249 private: 250 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 251 SettingsTable<StringSetting, const char*> strings_table; 252 SettingsTable<BoolSetting, BoolSettingValue> bools_table; 253 SettingsTable<IntSetting, int> ints_table; 254 SettingsTable<StringListSetting, 255 std::vector<std::string> > string_lists_table; 256 }; 257 258 } // namespace 259 } // namespace net 260 261 // This helper class runs ProxyConfigServiceLinux::GetLatestProxyConfig() on 262 // the IO thread and synchronously waits for the result. 263 // Some code duplicated from proxy_script_fetcher_unittest.cc. 264 class SynchConfigGetter { 265 public: 266 // Takes ownership of |config_service|. 267 explicit SynchConfigGetter(net::ProxyConfigServiceLinux* config_service) 268 : event_(false, false), 269 io_thread_("IO_Thread"), 270 config_service_(config_service) { 271 // Start an IO thread. 272 base::Thread::Options options; 273 options.message_loop_type = base::MessageLoop::TYPE_IO; 274 io_thread_.StartWithOptions(options); 275 276 // Make sure the thread started. 277 io_thread_.message_loop()->PostTask(FROM_HERE, 278 base::Bind(&SynchConfigGetter::Init, base::Unretained(this))); 279 Wait(); 280 } 281 282 ~SynchConfigGetter() { 283 // Let the config service post a destroy message to the IO thread 284 // before cleaning up that thread. 285 delete config_service_; 286 // Clean up the IO thread. 287 io_thread_.message_loop()->PostTask(FROM_HERE, 288 base::Bind(&SynchConfigGetter::CleanUp, base::Unretained(this))); 289 Wait(); 290 } 291 292 // Does gconf setup and initial fetch of the proxy config, 293 // all on the calling thread (meant to be the thread with the 294 // default glib main loop, which is the UI thread). 295 void SetupAndInitialFetch() { 296 // We pass the mock IO thread as both the IO and file threads. 297 config_service_->SetupAndFetchInitialConfig( 298 base::MessageLoopProxy::current(), 299 io_thread_.message_loop_proxy(), 300 io_thread_.message_loop_proxy()); 301 } 302 // Synchronously gets the proxy config. 303 net::ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig( 304 net::ProxyConfig* config) { 305 io_thread_.message_loop()->PostTask(FROM_HERE, 306 base::Bind(&SynchConfigGetter::GetLatestConfigOnIOThread, 307 base::Unretained(this))); 308 Wait(); 309 *config = proxy_config_; 310 return get_latest_config_result_; 311 } 312 313 private: 314 // [Runs on |io_thread_|] 315 void Init() { 316 event_.Signal(); 317 } 318 319 // Calls GetLatestProxyConfig, running on |io_thread_| Signals |event_| 320 // on completion. 321 void GetLatestConfigOnIOThread() { 322 get_latest_config_result_ = 323 config_service_->GetLatestProxyConfig(&proxy_config_); 324 event_.Signal(); 325 } 326 327 // [Runs on |io_thread_|] Signals |event_| on cleanup completion. 328 void CleanUp() { 329 base::MessageLoop::current()->RunUntilIdle(); 330 event_.Signal(); 331 } 332 333 void Wait() { 334 event_.Wait(); 335 event_.Reset(); 336 } 337 338 base::WaitableEvent event_; 339 base::Thread io_thread_; 340 341 net::ProxyConfigServiceLinux* config_service_; 342 343 // The config obtained by |io_thread_| and read back by the main 344 // thread. 345 net::ProxyConfig proxy_config_; 346 347 // Return value from GetLatestProxyConfig(). 348 net::ProxyConfigService::ConfigAvailability get_latest_config_result_; 349 }; 350 351 namespace net { 352 353 // This test fixture is only really needed for the KDEConfigParser test case, 354 // but all the test cases with the same prefix ("ProxyConfigServiceLinuxTest") 355 // must use the same test fixture class (also "ProxyConfigServiceLinuxTest"). 356 class ProxyConfigServiceLinuxTest : public PlatformTest { 357 protected: 358 virtual void SetUp() OVERRIDE { 359 PlatformTest::SetUp(); 360 // Set up a temporary KDE home directory. 361 std::string prefix("ProxyConfigServiceLinuxTest_user_home"); 362 base::CreateNewTempDirectory(prefix, &user_home_); 363 kde_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde")); 364 base::FilePath path = kde_home_.Append(FILE_PATH_LITERAL("share")); 365 path = path.Append(FILE_PATH_LITERAL("config")); 366 base::CreateDirectory(path); 367 kioslaverc_ = path.Append(FILE_PATH_LITERAL("kioslaverc")); 368 // Set up paths but do not create the directory for .kde4. 369 kde4_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde4")); 370 path = kde4_home_.Append(FILE_PATH_LITERAL("share")); 371 kde4_config_ = path.Append(FILE_PATH_LITERAL("config")); 372 kioslaverc4_ = kde4_config_.Append(FILE_PATH_LITERAL("kioslaverc")); 373 } 374 375 virtual void TearDown() OVERRIDE { 376 // Delete the temporary KDE home directory. 377 base::DeleteFile(user_home_, true); 378 PlatformTest::TearDown(); 379 } 380 381 base::FilePath user_home_; 382 // KDE3 paths. 383 base::FilePath kde_home_; 384 base::FilePath kioslaverc_; 385 // KDE4 paths. 386 base::FilePath kde4_home_; 387 base::FilePath kde4_config_; 388 base::FilePath kioslaverc4_; 389 }; 390 391 // Builds an identifier for each test in an array. 392 #define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc) 393 394 TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) { 395 std::vector<std::string> empty_ignores; 396 397 std::vector<std::string> google_ignores; 398 google_ignores.push_back("*.google.com"); 399 400 // Inspired from proxy_config_service_win_unittest.cc. 401 // Very neat, but harder to track down failures though. 402 const struct { 403 // Short description to identify the test 404 std::string description; 405 406 // Input. 407 GConfValues values; 408 409 // Expected outputs (availability and fields of ProxyConfig). 410 ProxyConfigService::ConfigAvailability availability; 411 bool auto_detect; 412 GURL pac_url; 413 ProxyRulesExpectation proxy_rules; 414 } tests[] = { 415 { 416 TEST_DESC("No proxying"), 417 { // Input. 418 "none", // mode 419 "", // autoconfig_url 420 "", "", "", "", // hosts 421 0, 0, 0, 0, // ports 422 FALSE, FALSE, FALSE, // use, same, auth 423 empty_ignores, // ignore_hosts 424 }, 425 426 // Expected result. 427 ProxyConfigService::CONFIG_VALID, 428 false, // auto_detect 429 GURL(), // pac_url 430 ProxyRulesExpectation::Empty(), 431 }, 432 433 { 434 TEST_DESC("Auto detect"), 435 { // Input. 436 "auto", // mode 437 "", // autoconfig_url 438 "", "", "", "", // hosts 439 0, 0, 0, 0, // ports 440 FALSE, FALSE, FALSE, // use, same, auth 441 empty_ignores, // ignore_hosts 442 }, 443 444 // Expected result. 445 ProxyConfigService::CONFIG_VALID, 446 true, // auto_detect 447 GURL(), // pac_url 448 ProxyRulesExpectation::Empty(), 449 }, 450 451 { 452 TEST_DESC("Valid PAC URL"), 453 { // Input. 454 "auto", // mode 455 "http://wpad/wpad.dat", // autoconfig_url 456 "", "", "", "", // hosts 457 0, 0, 0, 0, // ports 458 FALSE, FALSE, FALSE, // use, same, auth 459 empty_ignores, // ignore_hosts 460 }, 461 462 // Expected result. 463 ProxyConfigService::CONFIG_VALID, 464 false, // auto_detect 465 GURL("http://wpad/wpad.dat"), // pac_url 466 ProxyRulesExpectation::Empty(), 467 }, 468 469 { 470 TEST_DESC("Invalid PAC URL"), 471 { // Input. 472 "auto", // mode 473 "wpad.dat", // autoconfig_url 474 "", "", "", "", // hosts 475 0, 0, 0, 0, // ports 476 FALSE, FALSE, FALSE, // use, same, auth 477 empty_ignores, // ignore_hosts 478 }, 479 480 // Expected result. 481 ProxyConfigService::CONFIG_VALID, 482 false, // auto_detect 483 GURL(), // pac_url 484 ProxyRulesExpectation::Empty(), 485 }, 486 487 { 488 TEST_DESC("Single-host in proxy list"), 489 { // Input. 490 "manual", // mode 491 "", // autoconfig_url 492 "www.google.com", "", "", "", // hosts 493 80, 0, 0, 0, // ports 494 TRUE, TRUE, FALSE, // use, same, auth 495 empty_ignores, // ignore_hosts 496 }, 497 498 // Expected result. 499 ProxyConfigService::CONFIG_VALID, 500 false, // auto_detect 501 GURL(), // pac_url 502 ProxyRulesExpectation::Single( 503 "www.google.com:80", // single proxy 504 ""), // bypass rules 505 }, 506 507 { 508 TEST_DESC("use_http_proxy is honored"), 509 { // Input. 510 "manual", // mode 511 "", // autoconfig_url 512 "www.google.com", "", "", "", // hosts 513 80, 0, 0, 0, // ports 514 FALSE, TRUE, FALSE, // use, same, auth 515 empty_ignores, // ignore_hosts 516 }, 517 518 // Expected result. 519 ProxyConfigService::CONFIG_VALID, 520 false, // auto_detect 521 GURL(), // pac_url 522 ProxyRulesExpectation::Empty(), 523 }, 524 525 { 526 TEST_DESC("use_http_proxy and use_same_proxy are optional"), 527 { // Input. 528 "manual", // mode 529 "", // autoconfig_url 530 "www.google.com", "", "", "", // hosts 531 80, 0, 0, 0, // ports 532 UNSET, UNSET, FALSE, // use, same, auth 533 empty_ignores, // ignore_hosts 534 }, 535 536 // Expected result. 537 ProxyConfigService::CONFIG_VALID, 538 false, // auto_detect 539 GURL(), // pac_url 540 ProxyRulesExpectation::PerScheme( 541 "www.google.com:80", // http 542 "", // https 543 "", // ftp 544 ""), // bypass rules 545 }, 546 547 { 548 TEST_DESC("Single-host, different port"), 549 { // Input. 550 "manual", // mode 551 "", // autoconfig_url 552 "www.google.com", "", "", "", // hosts 553 88, 0, 0, 0, // ports 554 TRUE, TRUE, FALSE, // use, same, auth 555 empty_ignores, // ignore_hosts 556 }, 557 558 // Expected result. 559 ProxyConfigService::CONFIG_VALID, 560 false, // auto_detect 561 GURL(), // pac_url 562 ProxyRulesExpectation::Single( 563 "www.google.com:88", // single proxy 564 ""), // bypass rules 565 }, 566 567 { 568 TEST_DESC("Per-scheme proxy rules"), 569 { // Input. 570 "manual", // mode 571 "", // autoconfig_url 572 "www.google.com", // http_host 573 "www.foo.com", // secure_host 574 "ftp.foo.com", // ftp 575 "", // socks 576 88, 110, 121, 0, // ports 577 TRUE, FALSE, FALSE, // use, same, auth 578 empty_ignores, // ignore_hosts 579 }, 580 581 // Expected result. 582 ProxyConfigService::CONFIG_VALID, 583 false, // auto_detect 584 GURL(), // pac_url 585 ProxyRulesExpectation::PerScheme( 586 "www.google.com:88", // http 587 "www.foo.com:110", // https 588 "ftp.foo.com:121", // ftp 589 ""), // bypass rules 590 }, 591 592 { 593 TEST_DESC("socks"), 594 { // Input. 595 "manual", // mode 596 "", // autoconfig_url 597 "", "", "", "socks.com", // hosts 598 0, 0, 0, 99, // ports 599 TRUE, FALSE, FALSE, // use, same, auth 600 empty_ignores, // ignore_hosts 601 }, 602 603 // Expected result. 604 ProxyConfigService::CONFIG_VALID, 605 false, // auto_detect 606 GURL(), // pac_url 607 ProxyRulesExpectation::Single( 608 "socks5://socks.com:99", // single proxy 609 "") // bypass rules 610 }, 611 612 { 613 TEST_DESC("Per-scheme proxy rules with fallback to SOCKS"), 614 { // Input. 615 "manual", // mode 616 "", // autoconfig_url 617 "www.google.com", // http_host 618 "www.foo.com", // secure_host 619 "ftp.foo.com", // ftp 620 "foobar.net", // socks 621 88, 110, 121, 99, // ports 622 TRUE, FALSE, FALSE, // use, same, auth 623 empty_ignores, // ignore_hosts 624 }, 625 626 // Expected result. 627 ProxyConfigService::CONFIG_VALID, 628 false, // auto_detect 629 GURL(), // pac_url 630 ProxyRulesExpectation::PerSchemeWithSocks( 631 "www.google.com:88", // http 632 "www.foo.com:110", // https 633 "ftp.foo.com:121", // ftp 634 "socks5://foobar.net:99", // socks 635 ""), // bypass rules 636 }, 637 638 { 639 TEST_DESC("Per-scheme proxy rules (just HTTP) with fallback to SOCKS"), 640 { // Input. 641 "manual", // mode 642 "", // autoconfig_url 643 "www.google.com", // http_host 644 "", // secure_host 645 "", // ftp 646 "foobar.net", // socks 647 88, 0, 0, 99, // ports 648 TRUE, FALSE, FALSE, // use, same, auth 649 empty_ignores, // ignore_hosts 650 }, 651 652 // Expected result. 653 ProxyConfigService::CONFIG_VALID, 654 false, // auto_detect 655 GURL(), // pac_url 656 ProxyRulesExpectation::PerSchemeWithSocks( 657 "www.google.com:88", // http 658 "", // https 659 "", // ftp 660 "socks5://foobar.net:99", // socks 661 ""), // bypass rules 662 }, 663 664 { 665 TEST_DESC("Bypass *.google.com"), 666 { // Input. 667 "manual", // mode 668 "", // autoconfig_url 669 "www.google.com", "", "", "", // hosts 670 80, 0, 0, 0, // ports 671 TRUE, TRUE, FALSE, // use, same, auth 672 google_ignores, // ignore_hosts 673 }, 674 675 ProxyConfigService::CONFIG_VALID, 676 false, // auto_detect 677 GURL(), // pac_url 678 ProxyRulesExpectation::Single( 679 "www.google.com:80", // single proxy 680 "*.google.com"), // bypass rules 681 }, 682 }; 683 684 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 685 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i, 686 tests[i].description.c_str())); 687 MockEnvironment* env = new MockEnvironment; 688 MockSettingGetter* setting_getter = new MockSettingGetter; 689 SynchConfigGetter sync_config_getter( 690 new ProxyConfigServiceLinux(env, setting_getter)); 691 ProxyConfig config; 692 setting_getter->values = tests[i].values; 693 sync_config_getter.SetupAndInitialFetch(); 694 ProxyConfigService::ConfigAvailability availability = 695 sync_config_getter.SyncGetLatestProxyConfig(&config); 696 EXPECT_EQ(tests[i].availability, availability); 697 698 if (availability == ProxyConfigService::CONFIG_VALID) { 699 EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); 700 EXPECT_EQ(tests[i].pac_url, config.pac_url()); 701 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); 702 } 703 } 704 } 705 706 TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) { 707 // Inspired from proxy_config_service_win_unittest.cc. 708 const struct { 709 // Short description to identify the test 710 std::string description; 711 712 // Input. 713 EnvVarValues values; 714 715 // Expected outputs (availability and fields of ProxyConfig). 716 ProxyConfigService::ConfigAvailability availability; 717 bool auto_detect; 718 GURL pac_url; 719 ProxyRulesExpectation proxy_rules; 720 } tests[] = { 721 { 722 TEST_DESC("No proxying"), 723 { // Input. 724 NULL, // DESKTOP_SESSION 725 NULL, // HOME 726 NULL, // KDEHOME 727 NULL, // KDE_SESSION_VERSION 728 NULL, // auto_proxy 729 NULL, // all_proxy 730 NULL, NULL, NULL, // per-proto proxies 731 NULL, NULL, // SOCKS 732 "*", // no_proxy 733 }, 734 735 // Expected result. 736 ProxyConfigService::CONFIG_VALID, 737 false, // auto_detect 738 GURL(), // pac_url 739 ProxyRulesExpectation::Empty(), 740 }, 741 742 { 743 TEST_DESC("Auto detect"), 744 { // Input. 745 NULL, // DESKTOP_SESSION 746 NULL, // HOME 747 NULL, // KDEHOME 748 NULL, // KDE_SESSION_VERSION 749 "", // auto_proxy 750 NULL, // all_proxy 751 NULL, NULL, NULL, // per-proto proxies 752 NULL, NULL, // SOCKS 753 NULL, // no_proxy 754 }, 755 756 // Expected result. 757 ProxyConfigService::CONFIG_VALID, 758 true, // auto_detect 759 GURL(), // pac_url 760 ProxyRulesExpectation::Empty(), 761 }, 762 763 { 764 TEST_DESC("Valid PAC URL"), 765 { // Input. 766 NULL, // DESKTOP_SESSION 767 NULL, // HOME 768 NULL, // KDEHOME 769 NULL, // KDE_SESSION_VERSION 770 "http://wpad/wpad.dat", // auto_proxy 771 NULL, // all_proxy 772 NULL, NULL, NULL, // per-proto proxies 773 NULL, NULL, // SOCKS 774 NULL, // no_proxy 775 }, 776 777 // Expected result. 778 ProxyConfigService::CONFIG_VALID, 779 false, // auto_detect 780 GURL("http://wpad/wpad.dat"), // pac_url 781 ProxyRulesExpectation::Empty(), 782 }, 783 784 { 785 TEST_DESC("Invalid PAC URL"), 786 { // Input. 787 NULL, // DESKTOP_SESSION 788 NULL, // HOME 789 NULL, // KDEHOME 790 NULL, // KDE_SESSION_VERSION 791 "wpad.dat", // auto_proxy 792 NULL, // all_proxy 793 NULL, NULL, NULL, // per-proto proxies 794 NULL, NULL, // SOCKS 795 NULL, // no_proxy 796 }, 797 798 // Expected result. 799 ProxyConfigService::CONFIG_VALID, 800 false, // auto_detect 801 GURL(), // pac_url 802 ProxyRulesExpectation::Empty(), 803 }, 804 805 { 806 TEST_DESC("Single-host in proxy list"), 807 { // Input. 808 NULL, // DESKTOP_SESSION 809 NULL, // HOME 810 NULL, // KDEHOME 811 NULL, // KDE_SESSION_VERSION 812 NULL, // auto_proxy 813 "www.google.com", // all_proxy 814 NULL, NULL, NULL, // per-proto proxies 815 NULL, NULL, // SOCKS 816 NULL, // no_proxy 817 }, 818 819 // Expected result. 820 ProxyConfigService::CONFIG_VALID, 821 false, // auto_detect 822 GURL(), // pac_url 823 ProxyRulesExpectation::Single( 824 "www.google.com:80", // single proxy 825 ""), // bypass rules 826 }, 827 828 { 829 TEST_DESC("Single-host, different port"), 830 { // Input. 831 NULL, // DESKTOP_SESSION 832 NULL, // HOME 833 NULL, // KDEHOME 834 NULL, // KDE_SESSION_VERSION 835 NULL, // auto_proxy 836 "www.google.com:99", // all_proxy 837 NULL, NULL, NULL, // per-proto proxies 838 NULL, NULL, // SOCKS 839 NULL, // no_proxy 840 }, 841 842 // Expected result. 843 ProxyConfigService::CONFIG_VALID, 844 false, // auto_detect 845 GURL(), // pac_url 846 ProxyRulesExpectation::Single( 847 "www.google.com:99", // single 848 ""), // bypass rules 849 }, 850 851 { 852 TEST_DESC("Tolerate a scheme"), 853 { // Input. 854 NULL, // DESKTOP_SESSION 855 NULL, // HOME 856 NULL, // KDEHOME 857 NULL, // KDE_SESSION_VERSION 858 NULL, // auto_proxy 859 "http://www.google.com:99", // all_proxy 860 NULL, NULL, NULL, // per-proto proxies 861 NULL, NULL, // SOCKS 862 NULL, // no_proxy 863 }, 864 865 // Expected result. 866 ProxyConfigService::CONFIG_VALID, 867 false, // auto_detect 868 GURL(), // pac_url 869 ProxyRulesExpectation::Single( 870 "www.google.com:99", // single proxy 871 ""), // bypass rules 872 }, 873 874 { 875 TEST_DESC("Per-scheme proxy rules"), 876 { // Input. 877 NULL, // DESKTOP_SESSION 878 NULL, // HOME 879 NULL, // KDEHOME 880 NULL, // KDE_SESSION_VERSION 881 NULL, // auto_proxy 882 NULL, // all_proxy 883 "www.google.com:80", "www.foo.com:110", "ftp.foo.com:121", // per-proto 884 NULL, NULL, // SOCKS 885 NULL, // no_proxy 886 }, 887 888 // Expected result. 889 ProxyConfigService::CONFIG_VALID, 890 false, // auto_detect 891 GURL(), // pac_url 892 ProxyRulesExpectation::PerScheme( 893 "www.google.com:80", // http 894 "www.foo.com:110", // https 895 "ftp.foo.com:121", // ftp 896 ""), // bypass rules 897 }, 898 899 { 900 TEST_DESC("socks"), 901 { // Input. 902 NULL, // DESKTOP_SESSION 903 NULL, // HOME 904 NULL, // KDEHOME 905 NULL, // KDE_SESSION_VERSION 906 NULL, // auto_proxy 907 "", // all_proxy 908 NULL, NULL, NULL, // per-proto proxies 909 "socks.com:888", NULL, // SOCKS 910 NULL, // no_proxy 911 }, 912 913 // Expected result. 914 ProxyConfigService::CONFIG_VALID, 915 false, // auto_detect 916 GURL(), // pac_url 917 ProxyRulesExpectation::Single( 918 "socks5://socks.com:888", // single proxy 919 ""), // bypass rules 920 }, 921 922 { 923 TEST_DESC("socks4"), 924 { // Input. 925 NULL, // DESKTOP_SESSION 926 NULL, // HOME 927 NULL, // KDEHOME 928 NULL, // KDE_SESSION_VERSION 929 NULL, // auto_proxy 930 "", // all_proxy 931 NULL, NULL, NULL, // per-proto proxies 932 "socks.com:888", "4", // SOCKS 933 NULL, // no_proxy 934 }, 935 936 // Expected result. 937 ProxyConfigService::CONFIG_VALID, 938 false, // auto_detect 939 GURL(), // pac_url 940 ProxyRulesExpectation::Single( 941 "socks4://socks.com:888", // single proxy 942 ""), // bypass rules 943 }, 944 945 { 946 TEST_DESC("socks default port"), 947 { // Input. 948 NULL, // DESKTOP_SESSION 949 NULL, // HOME 950 NULL, // KDEHOME 951 NULL, // KDE_SESSION_VERSION 952 NULL, // auto_proxy 953 "", // all_proxy 954 NULL, NULL, NULL, // per-proto proxies 955 "socks.com", NULL, // SOCKS 956 NULL, // no_proxy 957 }, 958 959 // Expected result. 960 ProxyConfigService::CONFIG_VALID, 961 false, // auto_detect 962 GURL(), // pac_url 963 ProxyRulesExpectation::Single( 964 "socks5://socks.com:1080", // single proxy 965 ""), // bypass rules 966 }, 967 968 { 969 TEST_DESC("bypass"), 970 { // Input. 971 NULL, // DESKTOP_SESSION 972 NULL, // HOME 973 NULL, // KDEHOME 974 NULL, // KDE_SESSION_VERSION 975 NULL, // auto_proxy 976 "www.google.com", // all_proxy 977 NULL, NULL, NULL, // per-proto 978 NULL, NULL, // SOCKS 979 ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8", // no_proxy 980 }, 981 982 // Expected result. 983 ProxyConfigService::CONFIG_VALID, 984 false, // auto_detect 985 GURL(), // pac_url 986 ProxyRulesExpectation::Single( 987 "www.google.com:80", 988 "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8"), 989 }, 990 }; 991 992 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 993 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i, 994 tests[i].description.c_str())); 995 MockEnvironment* env = new MockEnvironment; 996 MockSettingGetter* setting_getter = new MockSettingGetter; 997 SynchConfigGetter sync_config_getter( 998 new ProxyConfigServiceLinux(env, setting_getter)); 999 ProxyConfig config; 1000 env->values = tests[i].values; 1001 sync_config_getter.SetupAndInitialFetch(); 1002 ProxyConfigService::ConfigAvailability availability = 1003 sync_config_getter.SyncGetLatestProxyConfig(&config); 1004 EXPECT_EQ(tests[i].availability, availability); 1005 1006 if (availability == ProxyConfigService::CONFIG_VALID) { 1007 EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); 1008 EXPECT_EQ(tests[i].pac_url, config.pac_url()); 1009 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); 1010 } 1011 } 1012 } 1013 1014 TEST_F(ProxyConfigServiceLinuxTest, GconfNotification) { 1015 MockEnvironment* env = new MockEnvironment; 1016 MockSettingGetter* setting_getter = new MockSettingGetter; 1017 ProxyConfigServiceLinux* service = 1018 new ProxyConfigServiceLinux(env, setting_getter); 1019 SynchConfigGetter sync_config_getter(service); 1020 ProxyConfig config; 1021 1022 // Start with no proxy. 1023 setting_getter->values.mode = "none"; 1024 sync_config_getter.SetupAndInitialFetch(); 1025 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1026 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1027 EXPECT_FALSE(config.auto_detect()); 1028 1029 // Now set to auto-detect. 1030 setting_getter->values.mode = "auto"; 1031 // Simulate setting change notification callback. 1032 service->OnCheckProxyConfigSettings(); 1033 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1034 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1035 EXPECT_TRUE(config.auto_detect()); 1036 } 1037 1038 TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) { 1039 // One of the tests below needs a worst-case long line prefix. We build it 1040 // programmatically so that it will always be the right size. 1041 std::string long_line; 1042 size_t limit = ProxyConfigServiceLinux::SettingGetter::BUFFER_SIZE - 1; 1043 for (size_t i = 0; i < limit; ++i) 1044 long_line += "-"; 1045 1046 // Inspired from proxy_config_service_win_unittest.cc. 1047 const struct { 1048 // Short description to identify the test 1049 std::string description; 1050 1051 // Input. 1052 std::string kioslaverc; 1053 EnvVarValues env_values; 1054 1055 // Expected outputs (availability and fields of ProxyConfig). 1056 ProxyConfigService::ConfigAvailability availability; 1057 bool auto_detect; 1058 GURL pac_url; 1059 ProxyRulesExpectation proxy_rules; 1060 } tests[] = { 1061 { 1062 TEST_DESC("No proxying"), 1063 1064 // Input. 1065 "[Proxy Settings]\nProxyType=0\n", 1066 {}, // env_values 1067 1068 // Expected result. 1069 ProxyConfigService::CONFIG_VALID, 1070 false, // auto_detect 1071 GURL(), // pac_url 1072 ProxyRulesExpectation::Empty(), 1073 }, 1074 1075 { 1076 TEST_DESC("Auto detect"), 1077 1078 // Input. 1079 "[Proxy Settings]\nProxyType=3\n", 1080 {}, // env_values 1081 1082 // Expected result. 1083 ProxyConfigService::CONFIG_VALID, 1084 true, // auto_detect 1085 GURL(), // pac_url 1086 ProxyRulesExpectation::Empty(), 1087 }, 1088 1089 { 1090 TEST_DESC("Valid PAC URL"), 1091 1092 // Input. 1093 "[Proxy Settings]\nProxyType=2\n" 1094 "Proxy Config Script=http://wpad/wpad.dat\n", 1095 {}, // env_values 1096 1097 // Expected result. 1098 ProxyConfigService::CONFIG_VALID, 1099 false, // auto_detect 1100 GURL("http://wpad/wpad.dat"), // pac_url 1101 ProxyRulesExpectation::Empty(), 1102 }, 1103 1104 { 1105 TEST_DESC("Valid PAC file without file://"), 1106 1107 // Input. 1108 "[Proxy Settings]\nProxyType=2\n" 1109 "Proxy Config Script=/wpad/wpad.dat\n", 1110 {}, // env_values 1111 1112 // Expected result. 1113 ProxyConfigService::CONFIG_VALID, 1114 false, // auto_detect 1115 GURL("file:///wpad/wpad.dat"), // pac_url 1116 ProxyRulesExpectation::Empty(), 1117 }, 1118 1119 { 1120 TEST_DESC("Per-scheme proxy rules"), 1121 1122 // Input. 1123 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1124 "httpsProxy=www.foo.com\nftpProxy=ftp.foo.com\n", 1125 {}, // env_values 1126 1127 // Expected result. 1128 ProxyConfigService::CONFIG_VALID, 1129 false, // auto_detect 1130 GURL(), // pac_url 1131 ProxyRulesExpectation::PerScheme( 1132 "www.google.com:80", // http 1133 "www.foo.com:80", // https 1134 "ftp.foo.com:80", // http 1135 ""), // bypass rules 1136 }, 1137 1138 { 1139 TEST_DESC("Only HTTP proxy specified"), 1140 1141 // Input. 1142 "[Proxy Settings]\nProxyType=1\n" 1143 "httpProxy=www.google.com\n", 1144 {}, // env_values 1145 1146 // Expected result. 1147 ProxyConfigService::CONFIG_VALID, 1148 false, // auto_detect 1149 GURL(), // pac_url 1150 ProxyRulesExpectation::PerScheme( 1151 "www.google.com:80", // http 1152 "", // https 1153 "", // ftp 1154 ""), // bypass rules 1155 }, 1156 1157 { 1158 TEST_DESC("Only HTTP proxy specified, different port"), 1159 1160 // Input. 1161 "[Proxy Settings]\nProxyType=1\n" 1162 "httpProxy=www.google.com:88\n", 1163 {}, // env_values 1164 1165 // Expected result. 1166 ProxyConfigService::CONFIG_VALID, 1167 false, // auto_detect 1168 GURL(), // pac_url 1169 ProxyRulesExpectation::PerScheme( 1170 "www.google.com:88", // http 1171 "", // https 1172 "", // ftp 1173 ""), // bypass rules 1174 }, 1175 1176 { 1177 TEST_DESC("Only HTTP proxy specified, different port, space-delimited"), 1178 1179 // Input. 1180 "[Proxy Settings]\nProxyType=1\n" 1181 "httpProxy=www.google.com 88\n", 1182 {}, // env_values 1183 1184 // Expected result. 1185 ProxyConfigService::CONFIG_VALID, 1186 false, // auto_detect 1187 GURL(), // pac_url 1188 ProxyRulesExpectation::PerScheme( 1189 "www.google.com:88", // http 1190 "", // https 1191 "", // ftp 1192 ""), // bypass rules 1193 }, 1194 1195 { 1196 TEST_DESC("Bypass *.google.com"), 1197 1198 // Input. 1199 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1200 "NoProxyFor=.google.com\n", 1201 {}, // env_values 1202 1203 // Expected result. 1204 ProxyConfigService::CONFIG_VALID, 1205 false, // auto_detect 1206 GURL(), // pac_url 1207 ProxyRulesExpectation::PerScheme( 1208 "www.google.com:80", // http 1209 "", // https 1210 "", // ftp 1211 "*.google.com"), // bypass rules 1212 }, 1213 1214 { 1215 TEST_DESC("Bypass *.google.com and *.kde.org"), 1216 1217 // Input. 1218 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1219 "NoProxyFor=.google.com,.kde.org\n", 1220 {}, // env_values 1221 1222 // Expected result. 1223 ProxyConfigService::CONFIG_VALID, 1224 false, // auto_detect 1225 GURL(), // pac_url 1226 ProxyRulesExpectation::PerScheme( 1227 "www.google.com:80", // http 1228 "", // https 1229 "", // ftp 1230 "*.google.com,*.kde.org"), // bypass rules 1231 }, 1232 1233 { 1234 TEST_DESC("Correctly parse bypass list with ReversedException"), 1235 1236 // Input. 1237 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1238 "NoProxyFor=.google.com\nReversedException=true\n", 1239 {}, // env_values 1240 1241 // Expected result. 1242 ProxyConfigService::CONFIG_VALID, 1243 false, // auto_detect 1244 GURL(), // pac_url 1245 ProxyRulesExpectation::PerSchemeWithBypassReversed( 1246 "www.google.com:80", // http 1247 "", // https 1248 "", // ftp 1249 "*.google.com"), // bypass rules 1250 }, 1251 1252 { 1253 TEST_DESC("socks"), 1254 1255 // Input. 1256 "[Proxy Settings]\nProxyType=1\nsocksProxy=socks.com 888\n", 1257 {}, // env_values 1258 1259 // Expected result. 1260 ProxyConfigService::CONFIG_VALID, 1261 false, // auto_detect 1262 GURL(), // pac_url 1263 ProxyRulesExpectation::Single( 1264 "socks5://socks.com:888", // single proxy 1265 ""), // bypass rules 1266 }, 1267 1268 { 1269 TEST_DESC("socks4"), 1270 1271 // Input. 1272 "[Proxy Settings]\nProxyType=1\nsocksProxy=socks4://socks.com 888\n", 1273 {}, // env_values 1274 1275 // Expected result. 1276 ProxyConfigService::CONFIG_VALID, 1277 false, // auto_detect 1278 GURL(), // pac_url 1279 ProxyRulesExpectation::Single( 1280 "socks4://socks.com:888", // single proxy 1281 ""), // bypass rules 1282 }, 1283 1284 { 1285 TEST_DESC("Treat all hostname patterns as wildcard patterns"), 1286 1287 // Input. 1288 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1289 "NoProxyFor=google.com,kde.org,<local>\n", 1290 {}, // env_values 1291 1292 // Expected result. 1293 ProxyConfigService::CONFIG_VALID, 1294 false, // auto_detect 1295 GURL(), // pac_url 1296 ProxyRulesExpectation::PerScheme( 1297 "www.google.com:80", // http 1298 "", // https 1299 "", // ftp 1300 "*google.com,*kde.org,<local>"), // bypass rules 1301 }, 1302 1303 { 1304 TEST_DESC("Allow trailing whitespace after boolean value"), 1305 1306 // Input. 1307 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1308 "NoProxyFor=.google.com\nReversedException=true \n", 1309 {}, // env_values 1310 1311 // Expected result. 1312 ProxyConfigService::CONFIG_VALID, 1313 false, // auto_detect 1314 GURL(), // pac_url 1315 ProxyRulesExpectation::PerSchemeWithBypassReversed( 1316 "www.google.com:80", // http 1317 "", // https 1318 "", // ftp 1319 "*.google.com"), // bypass rules 1320 }, 1321 1322 { 1323 TEST_DESC("Ignore settings outside [Proxy Settings]"), 1324 1325 // Input. 1326 "httpsProxy=www.foo.com\n[Proxy Settings]\nProxyType=1\n" 1327 "httpProxy=www.google.com\n[Other Section]\nftpProxy=ftp.foo.com\n", 1328 {}, // env_values 1329 1330 // Expected result. 1331 ProxyConfigService::CONFIG_VALID, 1332 false, // auto_detect 1333 GURL(), // pac_url 1334 ProxyRulesExpectation::PerScheme( 1335 "www.google.com:80", // http 1336 "", // https 1337 "", // ftp 1338 ""), // bypass rules 1339 }, 1340 1341 { 1342 TEST_DESC("Handle CRLF line endings"), 1343 1344 // Input. 1345 "[Proxy Settings]\r\nProxyType=1\r\nhttpProxy=www.google.com\r\n", 1346 {}, // env_values 1347 1348 // Expected result. 1349 ProxyConfigService::CONFIG_VALID, 1350 false, // auto_detect 1351 GURL(), // pac_url 1352 ProxyRulesExpectation::PerScheme( 1353 "www.google.com:80", // http 1354 "", // https 1355 "", // ftp 1356 ""), // bypass rules 1357 }, 1358 1359 { 1360 TEST_DESC("Handle blank lines and mixed line endings"), 1361 1362 // Input. 1363 "[Proxy Settings]\r\n\nProxyType=1\n\r\nhttpProxy=www.google.com\n\n", 1364 {}, // env_values 1365 1366 // Expected result. 1367 ProxyConfigService::CONFIG_VALID, 1368 false, // auto_detect 1369 GURL(), // pac_url 1370 ProxyRulesExpectation::PerScheme( 1371 "www.google.com:80", // http 1372 "", // https 1373 "", // ftp 1374 ""), // bypass rules 1375 }, 1376 1377 { 1378 TEST_DESC("Handle localized settings"), 1379 1380 // Input. 1381 "[Proxy Settings]\nProxyType[$e]=1\nhttpProxy[$e]=www.google.com\n", 1382 {}, // env_values 1383 1384 // Expected result. 1385 ProxyConfigService::CONFIG_VALID, 1386 false, // auto_detect 1387 GURL(), // pac_url 1388 ProxyRulesExpectation::PerScheme( 1389 "www.google.com:80", // http 1390 "", // https 1391 "", // ftp 1392 ""), // bypass rules 1393 }, 1394 1395 { 1396 TEST_DESC("Ignore malformed localized settings"), 1397 1398 // Input. 1399 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1400 "httpsProxy$e]=www.foo.com\nftpProxy=ftp.foo.com\n", 1401 {}, // env_values 1402 1403 // Expected result. 1404 ProxyConfigService::CONFIG_VALID, 1405 false, // auto_detect 1406 GURL(), // pac_url 1407 ProxyRulesExpectation::PerScheme( 1408 "www.google.com:80", // http 1409 "", // https 1410 "ftp.foo.com:80", // ftp 1411 ""), // bypass rules 1412 }, 1413 1414 { 1415 TEST_DESC("Handle strange whitespace"), 1416 1417 // Input. 1418 "[Proxy Settings]\nProxyType [$e] =2\n" 1419 " Proxy Config Script = http:// foo\n", 1420 {}, // env_values 1421 1422 // Expected result. 1423 ProxyConfigService::CONFIG_VALID, 1424 false, // auto_detect 1425 GURL("http:// foo"), // pac_url 1426 ProxyRulesExpectation::Empty(), 1427 }, 1428 1429 { 1430 TEST_DESC("Ignore all of a line which is too long"), 1431 1432 // Input. 1433 std::string("[Proxy Settings]\nProxyType=1\nftpProxy=ftp.foo.com\n") + 1434 long_line + "httpsProxy=www.foo.com\nhttpProxy=www.google.com\n", 1435 {}, // env_values 1436 1437 // Expected result. 1438 ProxyConfigService::CONFIG_VALID, 1439 false, // auto_detect 1440 GURL(), // pac_url 1441 ProxyRulesExpectation::PerScheme( 1442 "www.google.com:80", // http 1443 "", // https 1444 "ftp.foo.com:80", // ftp 1445 ""), // bypass rules 1446 }, 1447 1448 { 1449 TEST_DESC("Indirect Proxy - no env vars set"), 1450 1451 // Input. 1452 "[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n" 1453 "httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n", 1454 {}, // env_values 1455 1456 // Expected result. 1457 ProxyConfigService::CONFIG_VALID, 1458 false, // auto_detect 1459 GURL(), // pac_url 1460 ProxyRulesExpectation::Empty(), 1461 }, 1462 1463 { 1464 TEST_DESC("Indirect Proxy - with env vars set"), 1465 1466 // Input. 1467 "[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n" 1468 "httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n", 1469 { // env_values 1470 NULL, // DESKTOP_SESSION 1471 NULL, // HOME 1472 NULL, // KDEHOME 1473 NULL, // KDE_SESSION_VERSION 1474 NULL, // auto_proxy 1475 NULL, // all_proxy 1476 "www.normal.com", // http_proxy 1477 "www.secure.com", // https_proxy 1478 "ftp.foo.com", // ftp_proxy 1479 NULL, NULL, // SOCKS 1480 ".google.com, .kde.org", // no_proxy 1481 }, 1482 1483 // Expected result. 1484 ProxyConfigService::CONFIG_VALID, 1485 false, // auto_detect 1486 GURL(), // pac_url 1487 ProxyRulesExpectation::PerScheme( 1488 "www.normal.com:80", // http 1489 "www.secure.com:80", // https 1490 "ftp.foo.com:80", // ftp 1491 "*.google.com,*.kde.org"), // bypass rules 1492 }, 1493 1494 }; 1495 1496 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 1497 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i, 1498 tests[i].description.c_str())); 1499 MockEnvironment* env = new MockEnvironment; 1500 env->values = tests[i].env_values; 1501 // Force the KDE getter to be used and tell it where the test is. 1502 env->values.DESKTOP_SESSION = "kde4"; 1503 env->values.KDEHOME = kde_home_.value().c_str(); 1504 SynchConfigGetter sync_config_getter( 1505 new ProxyConfigServiceLinux(env)); 1506 ProxyConfig config; 1507 // Overwrite the kioslaverc file. 1508 base::WriteFile(kioslaverc_, tests[i].kioslaverc.c_str(), 1509 tests[i].kioslaverc.length()); 1510 sync_config_getter.SetupAndInitialFetch(); 1511 ProxyConfigService::ConfigAvailability availability = 1512 sync_config_getter.SyncGetLatestProxyConfig(&config); 1513 EXPECT_EQ(tests[i].availability, availability); 1514 1515 if (availability == ProxyConfigService::CONFIG_VALID) { 1516 EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); 1517 EXPECT_EQ(tests[i].pac_url, config.pac_url()); 1518 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); 1519 } 1520 } 1521 } 1522 1523 TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) { 1524 // Auto detect proxy settings. 1525 std::string slaverc3 = "[Proxy Settings]\nProxyType=3\n"; 1526 // Valid PAC URL. 1527 std::string slaverc4 = "[Proxy Settings]\nProxyType=2\n" 1528 "Proxy Config Script=http://wpad/wpad.dat\n"; 1529 GURL slaverc4_pac_url("http://wpad/wpad.dat"); 1530 1531 // Overwrite the .kde kioslaverc file. 1532 base::WriteFile(kioslaverc_, slaverc3.c_str(), slaverc3.length()); 1533 1534 // If .kde4 exists it will mess up the first test. It should not, as 1535 // we created the directory for $HOME in the test setup. 1536 CHECK(!base::DirectoryExists(kde4_home_)); 1537 1538 { SCOPED_TRACE("KDE4, no .kde4 directory, verify fallback"); 1539 MockEnvironment* env = new MockEnvironment; 1540 env->values.DESKTOP_SESSION = "kde4"; 1541 env->values.HOME = user_home_.value().c_str(); 1542 SynchConfigGetter sync_config_getter( 1543 new ProxyConfigServiceLinux(env)); 1544 ProxyConfig config; 1545 sync_config_getter.SetupAndInitialFetch(); 1546 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1547 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1548 EXPECT_TRUE(config.auto_detect()); 1549 EXPECT_EQ(GURL(), config.pac_url()); 1550 } 1551 1552 // Now create .kde4 and put a kioslaverc in the config directory. 1553 // Note that its timestamp will be at least as new as the .kde one. 1554 base::CreateDirectory(kde4_config_); 1555 base::WriteFile(kioslaverc4_, slaverc4.c_str(), slaverc4.length()); 1556 CHECK(base::PathExists(kioslaverc4_)); 1557 1558 { SCOPED_TRACE("KDE4, .kde4 directory present, use it"); 1559 MockEnvironment* env = new MockEnvironment; 1560 env->values.DESKTOP_SESSION = "kde4"; 1561 env->values.HOME = user_home_.value().c_str(); 1562 SynchConfigGetter sync_config_getter( 1563 new ProxyConfigServiceLinux(env)); 1564 ProxyConfig config; 1565 sync_config_getter.SetupAndInitialFetch(); 1566 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1567 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1568 EXPECT_FALSE(config.auto_detect()); 1569 EXPECT_EQ(slaverc4_pac_url, config.pac_url()); 1570 } 1571 1572 { SCOPED_TRACE("KDE3, .kde4 directory present, ignore it"); 1573 MockEnvironment* env = new MockEnvironment; 1574 env->values.DESKTOP_SESSION = "kde"; 1575 env->values.HOME = user_home_.value().c_str(); 1576 SynchConfigGetter sync_config_getter( 1577 new ProxyConfigServiceLinux(env)); 1578 ProxyConfig config; 1579 sync_config_getter.SetupAndInitialFetch(); 1580 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1581 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1582 EXPECT_TRUE(config.auto_detect()); 1583 EXPECT_EQ(GURL(), config.pac_url()); 1584 } 1585 1586 { SCOPED_TRACE("KDE4, .kde4 directory present, KDEHOME set to .kde"); 1587 MockEnvironment* env = new MockEnvironment; 1588 env->values.DESKTOP_SESSION = "kde4"; 1589 env->values.HOME = user_home_.value().c_str(); 1590 env->values.KDEHOME = kde_home_.value().c_str(); 1591 SynchConfigGetter sync_config_getter( 1592 new ProxyConfigServiceLinux(env)); 1593 ProxyConfig config; 1594 sync_config_getter.SetupAndInitialFetch(); 1595 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1596 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1597 EXPECT_TRUE(config.auto_detect()); 1598 EXPECT_EQ(GURL(), config.pac_url()); 1599 } 1600 1601 // Finally, make the .kde4 config directory older than the .kde directory 1602 // and make sure we then use .kde instead of .kde4 since it's newer. 1603 base::TouchFile(kde4_config_, base::Time(), base::Time()); 1604 1605 { SCOPED_TRACE("KDE4, very old .kde4 directory present, use .kde"); 1606 MockEnvironment* env = new MockEnvironment; 1607 env->values.DESKTOP_SESSION = "kde4"; 1608 env->values.HOME = user_home_.value().c_str(); 1609 SynchConfigGetter sync_config_getter( 1610 new ProxyConfigServiceLinux(env)); 1611 ProxyConfig config; 1612 sync_config_getter.SetupAndInitialFetch(); 1613 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1614 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1615 EXPECT_TRUE(config.auto_detect()); 1616 EXPECT_EQ(GURL(), config.pac_url()); 1617 } 1618 } 1619 1620 } // namespace net 1621