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