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