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 "base/prefs/pref_service.h" 6#include "chrome/browser/extensions/extension_apitest.h" 7#include "chrome/browser/extensions/extension_util.h" 8#include "chrome/browser/prefs/proxy_config_dictionary.h" 9#include "chrome/browser/profiles/profile.h" 10#include "chrome/browser/ui/browser.h" 11#include "chrome/common/chrome_switches.h" 12#include "chrome/common/pref_names.h" 13#include "extensions/common/extension.h" 14 15namespace extensions { 16 17namespace { 18 19const char kNoServer[] = ""; 20const char kNoBypass[] = ""; 21const char kNoPac[] = ""; 22 23} // namespace 24 25class ProxySettingsApiTest : public ExtensionApiTest { 26 protected: 27 void ValidateSettings(int expected_mode, 28 const std::string& expected_server, 29 const std::string& bypass, 30 const std::string& expected_pac_url, 31 PrefService* pref_service) { 32 const PrefService::Preference* pref = 33 pref_service->FindPreference(prefs::kProxy); 34 ASSERT_TRUE(pref != NULL); 35 EXPECT_TRUE(pref->IsExtensionControlled()); 36 37 ProxyConfigDictionary dict(pref_service->GetDictionary(prefs::kProxy)); 38 39 ProxyPrefs::ProxyMode mode; 40 ASSERT_TRUE(dict.GetMode(&mode)); 41 EXPECT_EQ(expected_mode, mode); 42 43 std::string value; 44 if (!bypass.empty()) { 45 ASSERT_TRUE(dict.GetBypassList(&value)); 46 EXPECT_EQ(bypass, value); 47 } else { 48 EXPECT_FALSE(dict.GetBypassList(&value)); 49 } 50 51 if (!expected_pac_url.empty()) { 52 ASSERT_TRUE(dict.GetPacUrl(&value)); 53 EXPECT_EQ(expected_pac_url, value); 54 } else { 55 EXPECT_FALSE(dict.GetPacUrl(&value)); 56 } 57 58 if (!expected_server.empty()) { 59 ASSERT_TRUE(dict.GetProxyServer(&value)); 60 EXPECT_EQ(expected_server, value); 61 } else { 62 EXPECT_FALSE(dict.GetProxyServer(&value)); 63 } 64 } 65 66 void ExpectNoSettings(PrefService* pref_service) { 67 const PrefService::Preference* pref = 68 pref_service->FindPreference(prefs::kProxy); 69 ASSERT_TRUE(pref != NULL); 70 EXPECT_FALSE(pref->IsExtensionControlled()); 71 } 72 73 bool SetIsIncognitoEnabled(bool enabled) { 74 ResultCatcher catcher; 75 extensions::util::SetIsIncognitoEnabled( 76 GetSingleLoadedExtension()->id(), browser()->profile(), enabled); 77 if (!catcher.GetNextResult()) { 78 message_ = catcher.message(); 79 return false; 80 } 81 return true; 82 } 83}; 84 85// Tests direct connection settings. 86IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyDirectSettings) { 87 ASSERT_TRUE(RunExtensionTestIncognito("proxy/direct")) << message_; 88 const Extension* extension = GetSingleLoadedExtension(); 89 ASSERT_TRUE(extension); 90 91 PrefService* pref_service = browser()->profile()->GetPrefs(); 92 ValidateSettings(ProxyPrefs::MODE_DIRECT, kNoServer, kNoBypass, kNoPac, 93 pref_service); 94 95 // As the extension is executed with incognito permission, the settings 96 // should propagate to incognito mode. 97 pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); 98 ValidateSettings(ProxyPrefs::MODE_DIRECT, kNoServer, kNoBypass, kNoPac, 99 pref_service); 100} 101 102// Tests auto-detect settings. 103IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyAutoSettings) { 104 ASSERT_TRUE(RunExtensionTestIncognito("proxy/auto")) << message_; 105 const Extension* extension = GetSingleLoadedExtension(); 106 ASSERT_TRUE(extension); 107 108 PrefService* pref_service = browser()->profile()->GetPrefs(); 109 ValidateSettings(ProxyPrefs::MODE_AUTO_DETECT, kNoServer, kNoBypass, kNoPac, 110 pref_service); 111} 112 113// Tests PAC proxy settings. 114IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyPacScript) { 115 ASSERT_TRUE(RunExtensionTest("proxy/pac")) << message_; 116 const Extension* extension = GetSingleLoadedExtension(); 117 ASSERT_TRUE(extension); 118 119 PrefService* pref_service = browser()->profile()->GetPrefs(); 120 ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass, 121 "http://wpad/windows.pac", pref_service); 122 123 // As the extension is not executed with incognito permission, the settings 124 // should not propagate to incognito mode. 125 pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); 126 ExpectNoSettings(pref_service); 127 128 // Now we enable the extension in incognito mode and verify that settings 129 // are applied. 130 ASSERT_TRUE(SetIsIncognitoEnabled(true)); 131 ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass, 132 "http://wpad/windows.pac", pref_service); 133 134 // Disabling incognito permission should revoke the settings for incognito 135 // mode. 136 ASSERT_TRUE(SetIsIncognitoEnabled(false)); 137 ExpectNoSettings(pref_service); 138} 139 140// Tests PAC proxy settings. 141IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyPacDataUrl) { 142 ASSERT_TRUE(RunExtensionTest("proxy/pacdataurl")) << message_; 143 const Extension* extension = GetSingleLoadedExtension(); 144 ASSERT_TRUE(extension); 145 const char url[] = 146 "data:;base64,ZnVuY3Rpb24gRmluZFByb3h5R" 147 "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl" 148 "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0="; 149 PrefService* pref_service = browser()->profile()->GetPrefs(); 150 ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass, 151 url, pref_service); 152} 153 154// Tests PAC proxy settings. 155IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyPacData) { 156 ASSERT_TRUE(RunExtensionTest("proxy/pacdata")) << message_; 157 const Extension* extension = GetSingleLoadedExtension(); 158 ASSERT_TRUE(extension); 159 const char url[] = 160 "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R" 161 "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl" 162 "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0="; 163 PrefService* pref_service = browser()->profile()->GetPrefs(); 164 ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass, 165 url, pref_service); 166} 167 168// Tests setting a single proxy to cover all schemes. 169IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedSingle) { 170 ASSERT_TRUE(RunExtensionTest("proxy/single")) << message_; 171 const Extension* extension = GetSingleLoadedExtension(); 172 ASSERT_TRUE(extension); 173 174 PrefService* pref_service = browser()->profile()->GetPrefs(); 175 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 176 "127.0.0.1:100", 177 kNoBypass, 178 kNoPac, 179 pref_service); 180} 181 182// Tests setting to use the system's proxy settings. 183IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxySystem) { 184 ASSERT_TRUE(RunExtensionTest("proxy/system")) << message_; 185 const Extension* extension = GetSingleLoadedExtension(); 186 ASSERT_TRUE(extension); 187 188 PrefService* pref_service = browser()->profile()->GetPrefs(); 189 ValidateSettings(ProxyPrefs::MODE_SYSTEM, kNoServer, kNoBypass, kNoPac, 190 pref_service); 191} 192 193// Tests setting separate proxies for each scheme. 194IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedIndividual) { 195 ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual")) << message_; 196 const Extension* extension = GetSingleLoadedExtension(); 197 ASSERT_TRUE(extension); 198 199 PrefService* pref_service = browser()->profile()->GetPrefs(); 200 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 201 "http=quic://1.1.1.1:443;" 202 "https=2.2.2.2:80;" // http:// is pruned. 203 "ftp=3.3.3.3:9000;" // http:// is pruned. 204 "socks=socks4://4.4.4.4:9090", 205 kNoBypass, 206 kNoPac, 207 pref_service); 208 209 // Now check the incognito preferences. 210 pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); 211 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 212 "http=quic://1.1.1.1:443;" 213 "https=2.2.2.2:80;" 214 "ftp=3.3.3.3:9000;" 215 "socks=socks4://4.4.4.4:9090", 216 kNoBypass, 217 kNoPac, 218 pref_service); 219} 220 221// Tests setting values only for incognito mode 222IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, 223 ProxyFixedIndividualIncognitoOnly) { 224 ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual_incognito_only")) << 225 message_; 226 const Extension* extension = GetSingleLoadedExtension(); 227 ASSERT_TRUE(extension); 228 229 PrefService* pref_service = browser()->profile()->GetPrefs(); 230 ExpectNoSettings(pref_service); 231 232 // Now check the incognito preferences. 233 pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); 234 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 235 "http=1.1.1.1:80;" 236 "https=socks5://2.2.2.2:1080;" 237 "ftp=3.3.3.3:9000;" 238 "socks=socks4://4.4.4.4:9090", 239 kNoBypass, 240 kNoPac, 241 pref_service); 242} 243 244// Tests setting values also for incognito mode 245// Test disabled due to http://crbug.com/88972. 246IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, 247 DISABLED_ProxyFixedIndividualIncognitoAlso) { 248 ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual_incognito_also")) << 249 message_; 250 const Extension* extension = GetSingleLoadedExtension(); 251 ASSERT_TRUE(extension); 252 253 PrefService* pref_service = browser()->profile()->GetPrefs(); 254 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 255 "http=1.1.1.1:80;" 256 "https=socks5://2.2.2.2:1080;" 257 "ftp=3.3.3.3:9000;" 258 "socks=socks4://4.4.4.4:9090", 259 kNoBypass, 260 kNoPac, 261 pref_service); 262 263 // Now check the incognito preferences. 264 pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); 265 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 266 "http=5.5.5.5:80;" 267 "https=socks5://6.6.6.6:1080;" 268 "ftp=7.7.7.7:9000;" 269 "socks=socks4://8.8.8.8:9090", 270 kNoBypass, 271 kNoPac, 272 pref_service); 273} 274 275// Tests setting and unsetting values 276IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedIndividualRemove) { 277 ASSERT_TRUE(RunExtensionTest("proxy/individual_remove")) << message_; 278 const Extension* extension = GetSingleLoadedExtension(); 279 ASSERT_TRUE(extension); 280 281 PrefService* pref_service = browser()->profile()->GetPrefs(); 282 ExpectNoSettings(pref_service); 283} 284 285IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, 286 ProxyBypass) { 287 ASSERT_TRUE(RunExtensionTestIncognito("proxy/bypass")) << message_; 288 const Extension* extension = GetSingleLoadedExtension(); 289 ASSERT_TRUE(extension); 290 291 PrefService* pref_service = browser()->profile()->GetPrefs(); 292 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 293 "http=1.1.1.1:80", 294 "localhost,::1,foo.bar,<local>", 295 kNoPac, 296 pref_service); 297 298 // Now check the incognito preferences. 299 pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); 300 ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS, 301 "http=1.1.1.1:80", 302 "localhost,::1,foo.bar,<local>", 303 kNoPac, 304 pref_service); 305} 306 307// This test sets proxy to an inavalid host "does.not.exist" and then fetches 308// a page from localhost, expecting an error since host is invalid. 309// On ChromeOS, localhost is by default bypassed, so the page from localhost 310// will be fetched successfully, resulting in no error. Hence this test 311// shouldn't run on ChromeOS. 312#if defined(OS_CHROMEOS) 313#define MAYBE_ProxyEventsInvalidProxy DISABLED_ProxyEventsInvalidProxy 314#else 315#define MAYBE_ProxyEventsInvalidProxy ProxyEventsInvalidProxy 316#endif // defined(OS_CHROMEOS) 317 318// Tests error events: invalid proxy 319IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, MAYBE_ProxyEventsInvalidProxy) { 320 ASSERT_TRUE(StartEmbeddedTestServer()); 321 ASSERT_TRUE( 322 RunExtensionSubtest("proxy/events", "invalid_proxy.html")) << message_; 323} 324 325// Tests error events: PAC script parse error. 326IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyEventsParseError) { 327 ASSERT_TRUE( 328 RunExtensionSubtest("proxy/events", "parse_error.html")) << message_; 329} 330 331} // namespace extensions 332