This source file includes following definitions.
- Reset
- GetVar
- SetVar
- UnSetVar
- Reset
- Init
- ShutDown
- SetUpNotifications
- GetNotificationTaskRunner
- GetConfigSource
- GetString
- GetBool
- GetInt
- GetStringList
- BypassListIsReversed
- MatchHostsUsingSuffixMatching
- config_service_
- SetupAndInitialFetch
- SyncGetLatestProxyConfig
- Init
- GetLatestConfigOnIOThread
- CleanUp
- Wait
- SetUp
- TearDown
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "net/proxy/proxy_config_service_linux.h"
#include <map>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_config_service_common_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
namespace net {
namespace {
struct EnvVarValues {
const char *DESKTOP_SESSION, *HOME,
*KDEHOME, *KDE_SESSION_VERSION,
*auto_proxy, *all_proxy,
*http_proxy, *https_proxy, *ftp_proxy,
*SOCKS_SERVER, *SOCKS_VERSION,
*no_proxy;
};
#undef TRUE
#undef FALSE
enum BoolSettingValue {
UNSET = 0, TRUE, FALSE
};
struct GConfValues {
const char *mode, *autoconfig_url,
*http_host, *secure_host, *ftp_host, *socks_host;
int http_port, secure_port, ftp_port, socks_port;
BoolSettingValue use_proxy, same_proxy, use_auth;
std::vector<std::string> ignore_hosts;
};
template<typename key_type, typename value_type>
struct SettingsTable {
typedef std::map<key_type, value_type*> map_type;
value_type Get(key_type key) {
typename map_type::const_iterator it = settings.find(key);
CHECK(it != settings.end()) << "key " << key << " not found";
value_type* value_ptr = it->second;
return *value_ptr;
}
map_type settings;
};
class MockEnvironment : public base::Environment {
public:
MockEnvironment() {
#define ENTRY(x) table[#x] = &values.x
ENTRY(DESKTOP_SESSION);
ENTRY(HOME);
ENTRY(KDEHOME);
ENTRY(KDE_SESSION_VERSION);
ENTRY(auto_proxy);
ENTRY(all_proxy);
ENTRY(http_proxy);
ENTRY(https_proxy);
ENTRY(ftp_proxy);
ENTRY(no_proxy);
ENTRY(SOCKS_SERVER);
ENTRY(SOCKS_VERSION);
#undef ENTRY
Reset();
}
void Reset() {
EnvVarValues zero_values = { 0 };
values = zero_values;
}
virtual bool GetVar(const char* variable_name, std::string* result) OVERRIDE {
std::map<std::string, const char**>::iterator it =
table.find(variable_name);
if (it != table.end() && *(it->second) != NULL) {
*result = *(it->second);
return true;
}
return false;
}
virtual bool SetVar(const char* variable_name, const std::string& new_value)
OVERRIDE {
ADD_FAILURE();
return false;
}
virtual bool UnSetVar(const char* variable_name) OVERRIDE {
ADD_FAILURE();
return false;
}
EnvVarValues values;
private:
std::map<std::string, const char**> table;
};
class MockSettingGetter
: public ProxyConfigServiceLinux::SettingGetter {
public:
typedef ProxyConfigServiceLinux::SettingGetter SettingGetter;
MockSettingGetter() {
#define ENTRY(key, field) \
strings_table.settings[SettingGetter::key] = &values.field
ENTRY(PROXY_MODE, mode);
ENTRY(PROXY_AUTOCONF_URL, autoconfig_url);
ENTRY(PROXY_HTTP_HOST, http_host);
ENTRY(PROXY_HTTPS_HOST, secure_host);
ENTRY(PROXY_FTP_HOST, ftp_host);
ENTRY(PROXY_SOCKS_HOST, socks_host);
#undef ENTRY
#define ENTRY(key, field) \
ints_table.settings[SettingGetter::key] = &values.field
ENTRY(PROXY_HTTP_PORT, http_port);
ENTRY(PROXY_HTTPS_PORT, secure_port);
ENTRY(PROXY_FTP_PORT, ftp_port);
ENTRY(PROXY_SOCKS_PORT, socks_port);
#undef ENTRY
#define ENTRY(key, field) \
bools_table.settings[SettingGetter::key] = &values.field
ENTRY(PROXY_USE_HTTP_PROXY, use_proxy);
ENTRY(PROXY_USE_SAME_PROXY, same_proxy);
ENTRY(PROXY_USE_AUTHENTICATION, use_auth);
#undef ENTRY
string_lists_table.settings[SettingGetter::PROXY_IGNORE_HOSTS] =
&values.ignore_hosts;
Reset();
}
void Reset() {
GConfValues zero_values = { 0 };
values = zero_values;
}
virtual bool Init(base::SingleThreadTaskRunner* glib_thread_task_runner,
base::MessageLoopForIO* file_loop) OVERRIDE {
return true;
}
virtual void ShutDown() OVERRIDE {}
virtual bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate)
OVERRIDE {
return true;
}
virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE {
return NULL;
}
virtual ProxyConfigSource GetConfigSource() OVERRIDE {
return PROXY_CONFIG_SOURCE_TEST;
}
virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
const char* value = strings_table.Get(key);
if (value) {
*result = value;
return true;
}
return false;
}
virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE {
BoolSettingValue value = bools_table.Get(key);
switch (value) {
case UNSET:
return false;
case TRUE:
*result = true;
break;
case FALSE:
*result = false;
}
return true;
}
virtual bool GetInt(IntSetting key, int* result) OVERRIDE {
*result = ints_table.Get(key);
return true;
}
virtual bool GetStringList(StringListSetting key,
std::vector<std::string>* result) OVERRIDE {
*result = string_lists_table.Get(key);
return !result->empty();
}
virtual bool BypassListIsReversed() OVERRIDE {
return false;
}
virtual bool MatchHostsUsingSuffixMatching() OVERRIDE {
return false;
}
GConfValues values;
private:
SettingsTable<StringSetting, const char*> strings_table;
SettingsTable<BoolSetting, BoolSettingValue> bools_table;
SettingsTable<IntSetting, int> ints_table;
SettingsTable<StringListSetting,
std::vector<std::string> > string_lists_table;
};
}
}
class SynchConfigGetter {
public:
explicit SynchConfigGetter(net::ProxyConfigServiceLinux* config_service)
: event_(false, false),
io_thread_("IO_Thread"),
config_service_(config_service) {
base::Thread::Options options;
options.message_loop_type = base::MessageLoop::TYPE_IO;
io_thread_.StartWithOptions(options);
io_thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&SynchConfigGetter::Init, base::Unretained(this)));
Wait();
}
~SynchConfigGetter() {
delete config_service_;
io_thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&SynchConfigGetter::CleanUp, base::Unretained(this)));
Wait();
}
void SetupAndInitialFetch() {
base::MessageLoop* file_loop = io_thread_.message_loop();
DCHECK_EQ(base::MessageLoop::TYPE_IO, file_loop->type());
config_service_->SetupAndFetchInitialConfig(
base::MessageLoopProxy::current().get(),
io_thread_.message_loop_proxy().get(),
static_cast<base::MessageLoopForIO*>(file_loop));
}
net::ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig(
net::ProxyConfig* config) {
io_thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&SynchConfigGetter::GetLatestConfigOnIOThread,
base::Unretained(this)));
Wait();
*config = proxy_config_;
return get_latest_config_result_;
}
private:
void Init() {
event_.Signal();
}
void GetLatestConfigOnIOThread() {
get_latest_config_result_ =
config_service_->GetLatestProxyConfig(&proxy_config_);
event_.Signal();
}
void CleanUp() {
base::MessageLoop::current()->RunUntilIdle();
event_.Signal();
}
void Wait() {
event_.Wait();
event_.Reset();
}
base::WaitableEvent event_;
base::Thread io_thread_;
net::ProxyConfigServiceLinux* config_service_;
net::ProxyConfig proxy_config_;
net::ProxyConfigService::ConfigAvailability get_latest_config_result_;
};
namespace net {
class ProxyConfigServiceLinuxTest : public PlatformTest {
protected:
virtual void SetUp() OVERRIDE {
PlatformTest::SetUp();
std::string prefix("ProxyConfigServiceLinuxTest_user_home");
base::CreateNewTempDirectory(prefix, &user_home_);
kde_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde"));
base::FilePath path = kde_home_.Append(FILE_PATH_LITERAL("share"));
path = path.Append(FILE_PATH_LITERAL("config"));
base::CreateDirectory(path);
kioslaverc_ = path.Append(FILE_PATH_LITERAL("kioslaverc"));
kde4_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde4"));
path = kde4_home_.Append(FILE_PATH_LITERAL("share"));
kde4_config_ = path.Append(FILE_PATH_LITERAL("config"));
kioslaverc4_ = kde4_config_.Append(FILE_PATH_LITERAL("kioslaverc"));
}
virtual void TearDown() OVERRIDE {
base::DeleteFile(user_home_, true);
PlatformTest::TearDown();
}
base::FilePath user_home_;
base::FilePath kde_home_;
base::FilePath kioslaverc_;
base::FilePath kde4_home_;
base::FilePath kde4_config_;
base::FilePath kioslaverc4_;
};
#define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc)
TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
std::vector<std::string> empty_ignores;
std::vector<std::string> google_ignores;
google_ignores.push_back("*.google.com");
const struct {
std::string description;
GConfValues values;
ProxyConfigService::ConfigAvailability availability;
bool auto_detect;
GURL pac_url;
ProxyRulesExpectation proxy_rules;
} tests[] = {
{
TEST_DESC("No proxying"),
{
"none",
"",
"", "", "", "",
0, 0, 0, 0,
FALSE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Auto detect"),
{
"auto",
"",
"", "", "", "",
0, 0, 0, 0,
FALSE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
true,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Valid PAC URL"),
{
"auto",
"http://wpad/wpad.dat",
"", "", "", "",
0, 0, 0, 0,
FALSE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL("http://wpad/wpad.dat"),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Invalid PAC URL"),
{
"auto",
"wpad.dat",
"", "", "", "",
0, 0, 0, 0,
FALSE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Single-host in proxy list"),
{
"manual",
"",
"www.google.com", "", "", "",
80, 0, 0, 0,
TRUE, TRUE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:80",
""),
},
{
TEST_DESC("use_http_proxy is honored"),
{
"manual",
"",
"www.google.com", "", "", "",
80, 0, 0, 0,
FALSE, TRUE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("use_http_proxy and use_same_proxy are optional"),
{
"manual",
"",
"www.google.com", "", "", "",
80, 0, 0, 0,
UNSET, UNSET, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
""),
},
{
TEST_DESC("Single-host, different port"),
{
"manual",
"",
"www.google.com", "", "", "",
88, 0, 0, 0,
TRUE, TRUE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:88",
""),
},
{
TEST_DESC("Per-scheme proxy rules"),
{
"manual",
"",
"www.google.com",
"www.foo.com",
"ftp.foo.com",
"",
88, 110, 121, 0,
TRUE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:88",
"www.foo.com:110",
"ftp.foo.com:121",
""),
},
{
TEST_DESC("socks"),
{
"manual",
"",
"", "", "", "socks.com",
0, 0, 0, 99,
TRUE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"socks5://socks.com:99",
"")
},
{
TEST_DESC("Per-scheme proxy rules with fallback to SOCKS"),
{
"manual",
"",
"www.google.com",
"www.foo.com",
"ftp.foo.com",
"foobar.net",
88, 110, 121, 99,
TRUE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerSchemeWithSocks(
"www.google.com:88",
"www.foo.com:110",
"ftp.foo.com:121",
"socks5://foobar.net:99",
""),
},
{
TEST_DESC("Per-scheme proxy rules (just HTTP) with fallback to SOCKS"),
{
"manual",
"",
"www.google.com",
"",
"",
"foobar.net",
88, 0, 0, 99,
TRUE, FALSE, FALSE,
empty_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerSchemeWithSocks(
"www.google.com:88",
"",
"",
"socks5://foobar.net:99",
""),
},
{
TEST_DESC("Bypass *.google.com"),
{
"manual",
"",
"www.google.com", "", "", "",
80, 0, 0, 0,
TRUE, TRUE, FALSE,
google_ignores,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:80",
"*.google.com"),
},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
tests[i].description.c_str()));
MockEnvironment* env = new MockEnvironment;
MockSettingGetter* setting_getter = new MockSettingGetter;
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env, setting_getter));
ProxyConfig config;
setting_getter->values = tests[i].values;
sync_config_getter.SetupAndInitialFetch();
ProxyConfigService::ConfigAvailability availability =
sync_config_getter.SyncGetLatestProxyConfig(&config);
EXPECT_EQ(tests[i].availability, availability);
if (availability == ProxyConfigService::CONFIG_VALID) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
EXPECT_EQ(tests[i].pac_url, config.pac_url());
EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
}
}
}
TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
const struct {
std::string description;
EnvVarValues values;
ProxyConfigService::ConfigAvailability availability;
bool auto_detect;
GURL pac_url;
ProxyRulesExpectation proxy_rules;
} tests[] = {
{
TEST_DESC("No proxying"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL, NULL, NULL,
NULL, NULL,
"*",
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Auto detect"),
{
NULL,
NULL,
NULL,
NULL,
"",
NULL,
NULL, NULL, NULL,
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
true,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Valid PAC URL"),
{
NULL,
NULL,
NULL,
NULL,
"http://wpad/wpad.dat",
NULL,
NULL, NULL, NULL,
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL("http://wpad/wpad.dat"),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Invalid PAC URL"),
{
NULL,
NULL,
NULL,
NULL,
"wpad.dat",
NULL,
NULL, NULL, NULL,
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Single-host in proxy list"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"www.google.com",
NULL, NULL, NULL,
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:80",
""),
},
{
TEST_DESC("Single-host, different port"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"www.google.com:99",
NULL, NULL, NULL,
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:99",
""),
},
{
TEST_DESC("Tolerate a scheme"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"http://www.google.com:99",
NULL, NULL, NULL,
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:99",
""),
},
{
TEST_DESC("Per-scheme proxy rules"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"www.google.com:80", "www.foo.com:110", "ftp.foo.com:121",
NULL, NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"www.foo.com:110",
"ftp.foo.com:121",
""),
},
{
TEST_DESC("socks"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"",
NULL, NULL, NULL,
"socks.com:888", NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"socks5://socks.com:888",
""),
},
{
TEST_DESC("socks4"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"",
NULL, NULL, NULL,
"socks.com:888", "4",
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"socks4://socks.com:888",
""),
},
{
TEST_DESC("socks default port"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"",
NULL, NULL, NULL,
"socks.com", NULL,
NULL,
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"socks5://socks.com:1080",
""),
},
{
TEST_DESC("bypass"),
{
NULL,
NULL,
NULL,
NULL,
NULL,
"www.google.com",
NULL, NULL, NULL,
NULL, NULL,
".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8",
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"www.google.com:80",
"*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8"),
},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
tests[i].description.c_str()));
MockEnvironment* env = new MockEnvironment;
MockSettingGetter* setting_getter = new MockSettingGetter;
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env, setting_getter));
ProxyConfig config;
env->values = tests[i].values;
sync_config_getter.SetupAndInitialFetch();
ProxyConfigService::ConfigAvailability availability =
sync_config_getter.SyncGetLatestProxyConfig(&config);
EXPECT_EQ(tests[i].availability, availability);
if (availability == ProxyConfigService::CONFIG_VALID) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
EXPECT_EQ(tests[i].pac_url, config.pac_url());
EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
}
}
}
TEST_F(ProxyConfigServiceLinuxTest, GconfNotification) {
MockEnvironment* env = new MockEnvironment;
MockSettingGetter* setting_getter = new MockSettingGetter;
ProxyConfigServiceLinux* service =
new ProxyConfigServiceLinux(env, setting_getter);
SynchConfigGetter sync_config_getter(service);
ProxyConfig config;
setting_getter->values.mode = "none";
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_FALSE(config.auto_detect());
setting_getter->values.mode = "auto";
service->OnCheckProxyConfigSettings();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_TRUE(config.auto_detect());
}
TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
std::string long_line;
size_t limit = ProxyConfigServiceLinux::SettingGetter::BUFFER_SIZE - 1;
for (size_t i = 0; i < limit; ++i)
long_line += "-";
const struct {
std::string description;
std::string kioslaverc;
EnvVarValues env_values;
ProxyConfigService::ConfigAvailability availability;
bool auto_detect;
GURL pac_url;
ProxyRulesExpectation proxy_rules;
} tests[] = {
{
TEST_DESC("No proxying"),
"[Proxy Settings]\nProxyType=0\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Auto detect"),
"[Proxy Settings]\nProxyType=3\n",
{},
ProxyConfigService::CONFIG_VALID,
true,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Valid PAC URL"),
"[Proxy Settings]\nProxyType=2\n"
"Proxy Config Script=http://wpad/wpad.dat\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL("http://wpad/wpad.dat"),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Valid PAC file without file://"),
"[Proxy Settings]\nProxyType=2\n"
"Proxy Config Script=/wpad/wpad.dat\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL("file:///wpad/wpad.dat"),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Per-scheme proxy rules"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"httpsProxy=www.foo.com\nftpProxy=ftp.foo.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"www.foo.com:80",
"ftp.foo.com:80",
""),
},
{
TEST_DESC("Only HTTP proxy specified"),
"[Proxy Settings]\nProxyType=1\n"
"httpProxy=www.google.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
""),
},
{
TEST_DESC("Only HTTP proxy specified, different port"),
"[Proxy Settings]\nProxyType=1\n"
"httpProxy=www.google.com:88\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:88",
"",
"",
""),
},
{
TEST_DESC("Only HTTP proxy specified, different port, space-delimited"),
"[Proxy Settings]\nProxyType=1\n"
"httpProxy=www.google.com 88\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:88",
"",
"",
""),
},
{
TEST_DESC("Bypass *.google.com"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"NoProxyFor=.google.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
"*.google.com"),
},
{
TEST_DESC("Bypass *.google.com and *.kde.org"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"NoProxyFor=.google.com,.kde.org\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
"*.google.com,*.kde.org"),
},
{
TEST_DESC("Correctly parse bypass list with ReversedException"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"NoProxyFor=.google.com\nReversedException=true\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerSchemeWithBypassReversed(
"www.google.com:80",
"",
"",
"*.google.com"),
},
{
TEST_DESC("socks"),
"[Proxy Settings]\nProxyType=1\nsocksProxy=socks.com 888\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"socks5://socks.com:888",
""),
},
{
TEST_DESC("socks4"),
"[Proxy Settings]\nProxyType=1\nsocksProxy=socks4://socks.com 888\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Single(
"socks4://socks.com:888",
""),
},
{
TEST_DESC("Treat all hostname patterns as wildcard patterns"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"NoProxyFor=google.com,kde.org,<local>\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
"*google.com,*kde.org,<local>"),
},
{
TEST_DESC("Allow trailing whitespace after boolean value"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"NoProxyFor=.google.com\nReversedException=true \n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerSchemeWithBypassReversed(
"www.google.com:80",
"",
"",
"*.google.com"),
},
{
TEST_DESC("Ignore settings outside [Proxy Settings]"),
"httpsProxy=www.foo.com\n[Proxy Settings]\nProxyType=1\n"
"httpProxy=www.google.com\n[Other Section]\nftpProxy=ftp.foo.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
""),
},
{
TEST_DESC("Handle CRLF line endings"),
"[Proxy Settings]\r\nProxyType=1\r\nhttpProxy=www.google.com\r\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
""),
},
{
TEST_DESC("Handle blank lines and mixed line endings"),
"[Proxy Settings]\r\n\nProxyType=1\n\r\nhttpProxy=www.google.com\n\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
""),
},
{
TEST_DESC("Handle localized settings"),
"[Proxy Settings]\nProxyType[$e]=1\nhttpProxy[$e]=www.google.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"",
""),
},
{
TEST_DESC("Ignore malformed localized settings"),
"[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
"httpsProxy$e]=www.foo.com\nftpProxy=ftp.foo.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"ftp.foo.com:80",
""),
},
{
TEST_DESC("Handle strange whitespace"),
"[Proxy Settings]\nProxyType [$e] =2\n"
" Proxy Config Script = http:// foo\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL("http:// foo"),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Ignore all of a line which is too long"),
std::string("[Proxy Settings]\nProxyType=1\nftpProxy=ftp.foo.com\n") +
long_line + "httpsProxy=www.foo.com\nhttpProxy=www.google.com\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.google.com:80",
"",
"ftp.foo.com:80",
""),
},
{
TEST_DESC("Indirect Proxy - no env vars set"),
"[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n"
"httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n",
{},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::Empty(),
},
{
TEST_DESC("Indirect Proxy - with env vars set"),
"[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n"
"httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n",
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"www.normal.com",
"www.secure.com",
"ftp.foo.com",
NULL, NULL,
".google.com, .kde.org",
},
ProxyConfigService::CONFIG_VALID,
false,
GURL(),
ProxyRulesExpectation::PerScheme(
"www.normal.com:80",
"www.secure.com:80",
"ftp.foo.com:80",
"*.google.com,*.kde.org"),
},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
tests[i].description.c_str()));
MockEnvironment* env = new MockEnvironment;
env->values = tests[i].env_values;
env->values.DESKTOP_SESSION = "kde4";
env->values.KDEHOME = kde_home_.value().c_str();
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env));
ProxyConfig config;
base::WriteFile(kioslaverc_, tests[i].kioslaverc.c_str(),
tests[i].kioslaverc.length());
sync_config_getter.SetupAndInitialFetch();
ProxyConfigService::ConfigAvailability availability =
sync_config_getter.SyncGetLatestProxyConfig(&config);
EXPECT_EQ(tests[i].availability, availability);
if (availability == ProxyConfigService::CONFIG_VALID) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
EXPECT_EQ(tests[i].pac_url, config.pac_url());
EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
}
}
}
TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
std::string slaverc3 = "[Proxy Settings]\nProxyType=3\n";
std::string slaverc4 = "[Proxy Settings]\nProxyType=2\n"
"Proxy Config Script=http://wpad/wpad.dat\n";
GURL slaverc4_pac_url("http://wpad/wpad.dat");
base::WriteFile(kioslaverc_, slaverc3.c_str(), slaverc3.length());
CHECK(!base::DirectoryExists(kde4_home_));
{ SCOPED_TRACE("KDE4, no .kde4 directory, verify fallback");
MockEnvironment* env = new MockEnvironment;
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env));
ProxyConfig config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_TRUE(config.auto_detect());
EXPECT_EQ(GURL(), config.pac_url());
}
base::CreateDirectory(kde4_config_);
base::WriteFile(kioslaverc4_, slaverc4.c_str(), slaverc4.length());
CHECK(base::PathExists(kioslaverc4_));
{ SCOPED_TRACE("KDE4, .kde4 directory present, use it");
MockEnvironment* env = new MockEnvironment;
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env));
ProxyConfig config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_FALSE(config.auto_detect());
EXPECT_EQ(slaverc4_pac_url, config.pac_url());
}
{ SCOPED_TRACE("KDE3, .kde4 directory present, ignore it");
MockEnvironment* env = new MockEnvironment;
env->values.DESKTOP_SESSION = "kde";
env->values.HOME = user_home_.value().c_str();
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env));
ProxyConfig config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_TRUE(config.auto_detect());
EXPECT_EQ(GURL(), config.pac_url());
}
{ SCOPED_TRACE("KDE4, .kde4 directory present, KDEHOME set to .kde");
MockEnvironment* env = new MockEnvironment;
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
env->values.KDEHOME = kde_home_.value().c_str();
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env));
ProxyConfig config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_TRUE(config.auto_detect());
EXPECT_EQ(GURL(), config.pac_url());
}
base::TouchFile(kde4_config_, base::Time(), base::Time());
{ SCOPED_TRACE("KDE4, very old .kde4 directory present, use .kde");
MockEnvironment* env = new MockEnvironment;
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
SynchConfigGetter sync_config_getter(
new ProxyConfigServiceLinux(env));
ProxyConfig config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
EXPECT_TRUE(config.auto_detect());
EXPECT_EQ(GURL(), config.pac_url());
}
}
}