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 "chrome/browser/net/chrome_network_delegate.h" 6 7 #include "base/memory/ref_counted.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/prefs/pref_member.h" 11 #include "chrome/browser/content_settings/cookie_settings.h" 12 #include "chrome/common/pref_names.h" 13 #include "chrome/common/url_constants.h" 14 #include "chrome/test/base/testing_pref_service_syncable.h" 15 #include "chrome/test/base/testing_profile.h" 16 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "net/base/completion_callback.h" 18 #include "net/base/request_priority.h" 19 #include "net/url_request/url_request.h" 20 #include "net/url_request/url_request_test_util.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 23 #if defined(ENABLE_EXTENSIONS) 24 #include "chrome/browser/extensions/event_router_forwarder.h" 25 #endif 26 27 #if defined(ENABLE_EXTENSIONS) 28 class ChromeNetworkDelegateTest : public testing::Test { 29 protected: 30 ChromeNetworkDelegateTest() 31 : forwarder_(new extensions::EventRouterForwarder()) { 32 } 33 34 virtual void SetUp() OVERRIDE { 35 never_throttle_requests_original_value_ = 36 ChromeNetworkDelegate::g_never_throttle_requests_; 37 ChromeNetworkDelegate::g_never_throttle_requests_ = false; 38 } 39 40 virtual void TearDown() OVERRIDE { 41 ChromeNetworkDelegate::g_never_throttle_requests_ = 42 never_throttle_requests_original_value_; 43 } 44 45 scoped_ptr<ChromeNetworkDelegate> CreateNetworkDelegate() { 46 return make_scoped_ptr( 47 new ChromeNetworkDelegate(forwarder_.get(), &pref_member_)); 48 } 49 50 // Implementation moved here for access to private bits. 51 void NeverThrottleLogicImpl() { 52 scoped_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); 53 54 net::TestURLRequestContext context; 55 scoped_ptr<net::URLRequest> extension_request(context.CreateRequest( 56 GURL("http://example.com/"), net::DEFAULT_PRIORITY, NULL, NULL)); 57 extension_request->set_first_party_for_cookies( 58 GURL("chrome-extension://abcdef/bingo.html")); 59 scoped_ptr<net::URLRequest> web_page_request(context.CreateRequest( 60 GURL("http://example.com/"), net::DEFAULT_PRIORITY, NULL, NULL)); 61 web_page_request->set_first_party_for_cookies( 62 GURL("http://example.com/helloworld.html")); 63 64 ASSERT_TRUE(delegate->OnCanThrottleRequest(*extension_request)); 65 ASSERT_FALSE(delegate->OnCanThrottleRequest(*web_page_request)); 66 67 delegate->NeverThrottleRequests(); 68 ASSERT_TRUE(ChromeNetworkDelegate::g_never_throttle_requests_); 69 ASSERT_FALSE(delegate->OnCanThrottleRequest(*extension_request)); 70 ASSERT_FALSE(delegate->OnCanThrottleRequest(*web_page_request)); 71 72 // Verify that the flag applies to later instances of the 73 // ChromeNetworkDelegate. 74 // 75 // We test the side effects of the flag rather than just the flag 76 // itself (which we did above) to help ensure that a changed 77 // implementation would show the same behavior, i.e. all instances 78 // of ChromeNetworkDelegate after the flag is set obey the flag. 79 scoped_ptr<ChromeNetworkDelegate> second_delegate(CreateNetworkDelegate()); 80 ASSERT_FALSE(delegate->OnCanThrottleRequest(*extension_request)); 81 ASSERT_FALSE(delegate->OnCanThrottleRequest(*web_page_request)); 82 } 83 84 private: 85 bool never_throttle_requests_original_value_; 86 base::MessageLoopForIO message_loop_; 87 88 scoped_refptr<extensions::EventRouterForwarder> forwarder_; 89 BooleanPrefMember pref_member_; 90 }; 91 92 TEST_F(ChromeNetworkDelegateTest, NeverThrottleLogic) { 93 NeverThrottleLogicImpl(); 94 } 95 #endif // defined(ENABLE_EXTENSIONS) 96 97 class ChromeNetworkDelegateSafeSearchTest : public testing::Test { 98 public: 99 ChromeNetworkDelegateSafeSearchTest() 100 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) { 101 #if defined(ENABLE_EXTENSIONS) 102 forwarder_ = new extensions::EventRouterForwarder(); 103 #endif 104 } 105 106 virtual void SetUp() OVERRIDE { 107 ChromeNetworkDelegate::InitializePrefsOnUIThread( 108 &enable_referrers_, NULL, &force_google_safe_search_, 109 profile_.GetTestingPrefService()); 110 } 111 112 protected: 113 scoped_ptr<net::NetworkDelegate> CreateNetworkDelegate() { 114 scoped_ptr<ChromeNetworkDelegate> network_delegate( 115 new ChromeNetworkDelegate(forwarder(), &enable_referrers_)); 116 network_delegate->set_force_google_safe_search(&force_google_safe_search_); 117 return network_delegate.PassAs<net::NetworkDelegate>(); 118 } 119 120 void SetSafeSearch(bool value) { 121 force_google_safe_search_.SetValue(value); 122 } 123 124 void SetDelegate(net::NetworkDelegate* delegate) { 125 network_delegate_ = delegate; 126 context_.set_network_delegate(network_delegate_); 127 } 128 129 // Does a request using the |url_string| URL and verifies that the expected 130 // string is equal to the query part (between ? and #) of the final url of 131 // that request. 132 void CheckAddedParameters(const std::string& url_string, 133 const std::string& expected_query_parameters) { 134 // Show the URL in the trace so we know where we failed. 135 SCOPED_TRACE(url_string); 136 137 scoped_ptr<net::URLRequest> request(context_.CreateRequest( 138 GURL(url_string), net::DEFAULT_PRIORITY, &delegate_, NULL)); 139 140 request->Start(); 141 base::MessageLoop::current()->RunUntilIdle(); 142 143 EXPECT_EQ(expected_query_parameters, request->url().query()); 144 } 145 146 private: 147 extensions::EventRouterForwarder* forwarder() { 148 #if defined(ENABLE_EXTENSIONS) 149 return forwarder_.get(); 150 #else 151 return NULL; 152 #endif 153 } 154 155 content::TestBrowserThreadBundle thread_bundle_; 156 #if defined(ENABLE_EXTENSIONS) 157 scoped_refptr<extensions::EventRouterForwarder> forwarder_; 158 #endif 159 TestingProfile profile_; 160 BooleanPrefMember enable_referrers_; 161 BooleanPrefMember force_google_safe_search_; 162 scoped_ptr<net::URLRequest> request_; 163 net::TestURLRequestContext context_; 164 net::NetworkDelegate* network_delegate_; 165 net::TestDelegate delegate_; 166 }; 167 168 TEST_F(ChromeNetworkDelegateSafeSearchTest, SafeSearchOn) { 169 // Tests with SafeSearch on, request parameters should be rewritten. 170 const std::string kSafeParameter = chrome::kSafeSearchSafeParameter; 171 const std::string kSsuiParameter = chrome::kSafeSearchSsuiParameter; 172 const std::string kBothParameters = kSafeParameter + "&" + kSsuiParameter; 173 SetSafeSearch(true); 174 scoped_ptr<net::NetworkDelegate> delegate(CreateNetworkDelegate()); 175 SetDelegate(delegate.get()); 176 177 // Test the home page. 178 CheckAddedParameters("http://google.com/", kBothParameters); 179 180 // Test the search home page. 181 CheckAddedParameters("http://google.com/webhp", 182 kBothParameters); 183 184 // Test different valid search pages with parameters. 185 CheckAddedParameters("http://google.com/search?q=google", 186 "q=google&" + kBothParameters); 187 188 CheckAddedParameters("http://google.com/?q=google", 189 "q=google&" + kBothParameters); 190 191 CheckAddedParameters("http://google.com/webhp?q=google", 192 "q=google&" + kBothParameters); 193 194 // Test the valid pages with safe set to off. 195 CheckAddedParameters("http://google.com/search?q=google&safe=off", 196 "q=google&" + kBothParameters); 197 198 CheckAddedParameters("http://google.com/?q=google&safe=off", 199 "q=google&" + kBothParameters); 200 201 CheckAddedParameters("http://google.com/webhp?q=google&safe=off", 202 "q=google&" + kBothParameters); 203 204 CheckAddedParameters("http://google.com/webhp?q=google&%73afe=off", 205 "q=google&%73afe=off&" + kBothParameters); 206 207 // Test the home page, different TLDs. 208 CheckAddedParameters("http://google.de/", kBothParameters); 209 CheckAddedParameters("http://google.ro/", kBothParameters); 210 CheckAddedParameters("http://google.nl/", kBothParameters); 211 212 // Test the search home page, different TLD. 213 CheckAddedParameters("http://google.de/webhp", kBothParameters); 214 215 // Test the search page with parameters, different TLD. 216 CheckAddedParameters("http://google.de/search?q=google", 217 "q=google&" + kBothParameters); 218 219 // Test the home page with parameters, different TLD. 220 CheckAddedParameters("http://google.de/?q=google", 221 "q=google&" + kBothParameters); 222 223 // Test the search page with the parameters set. 224 CheckAddedParameters("http://google.de/?q=google&" + kBothParameters, 225 "q=google&" + kBothParameters); 226 227 // Test some possibly tricky combinations. 228 CheckAddedParameters("http://google.com/?q=goog&" + kSafeParameter + 229 "&ssui=one", 230 "q=goog&" + kBothParameters); 231 232 CheckAddedParameters("http://google.de/?q=goog&unsafe=active&" + 233 kSsuiParameter, 234 "q=goog&unsafe=active&" + kBothParameters); 235 236 CheckAddedParameters("http://google.de/?q=goog&safe=off&ssui=off", 237 "q=goog&" + kBothParameters); 238 239 // Test various combinations where we should not add anything. 240 CheckAddedParameters("http://google.com/?q=goog&" + kSsuiParameter + "&" + 241 kSafeParameter, 242 "q=goog&" + kBothParameters); 243 244 CheckAddedParameters("http://google.com/?" + kSsuiParameter + "&q=goog&" + 245 kSafeParameter, 246 "q=goog&" + kBothParameters); 247 248 CheckAddedParameters("http://google.com/?" + kSsuiParameter + "&" + 249 kSafeParameter + "&q=goog", 250 "q=goog&" + kBothParameters); 251 252 // Test that another website is not affected, without parameters. 253 CheckAddedParameters("http://google.com/finance", std::string()); 254 255 // Test that another website is not affected, with parameters. 256 CheckAddedParameters("http://google.com/finance?q=goog", "q=goog"); 257 258 // Test that another website is not affected with redirects, with parameters. 259 CheckAddedParameters("http://finance.google.com/?q=goog", "q=goog"); 260 261 // Test with percent-encoded data (%26 is &) 262 CheckAddedParameters("http://google.com/?q=%26%26%26&" + kSsuiParameter + 263 "&" + kSafeParameter + "¶m=%26%26%26", 264 "q=%26%26%26¶m=%26%26%26&" + kBothParameters); 265 } 266 267 TEST_F(ChromeNetworkDelegateSafeSearchTest, SafeSearchOff) { 268 // Tests with SafeSearch settings off, delegate should not alter requests. 269 SetSafeSearch(false); 270 scoped_ptr<net::NetworkDelegate> delegate(CreateNetworkDelegate()); 271 SetDelegate(delegate.get()); 272 273 // Test the home page. 274 CheckAddedParameters("http://google.com/", std::string()); 275 276 // Test the search home page. 277 CheckAddedParameters("http://google.com/webhp", std::string()); 278 279 // Test the home page with parameters. 280 CheckAddedParameters("http://google.com/search?q=google", 281 "q=google"); 282 283 // Test the search page with parameters. 284 CheckAddedParameters("http://google.com/?q=google", 285 "q=google"); 286 287 // Test the search webhp page with parameters. 288 CheckAddedParameters("http://google.com/webhp?q=google", 289 "q=google"); 290 291 // Test the home page with parameters and safe set to off. 292 CheckAddedParameters("http://google.com/search?q=google&safe=off", 293 "q=google&safe=off"); 294 295 // Test the home page with parameters and safe set to active. 296 CheckAddedParameters("http://google.com/search?q=google&safe=active", 297 "q=google&safe=active"); 298 } 299 300 // Privacy Mode disables Channel Id if cookies are blocked (cr223191) 301 class ChromeNetworkDelegatePrivacyModeTest : public testing::Test { 302 public: 303 ChromeNetworkDelegatePrivacyModeTest() 304 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 305 #if defined(ENABLE_EXTENSIONS) 306 forwarder_(new extensions::EventRouterForwarder()), 307 #endif 308 cookie_settings_(CookieSettings::Factory::GetForProfile(&profile_) 309 .get()), 310 kBlockedSite("http://ads.thirdparty.com"), 311 kAllowedSite("http://good.allays.com"), 312 kFirstPartySite("http://cool.things.com"), 313 kBlockedFirstPartySite("http://no.thirdparties.com") {} 314 315 virtual void SetUp() OVERRIDE { 316 ChromeNetworkDelegate::InitializePrefsOnUIThread( 317 &enable_referrers_, NULL, NULL, 318 profile_.GetTestingPrefService()); 319 } 320 321 protected: 322 scoped_ptr<ChromeNetworkDelegate> CreateNetworkDelegate() { 323 scoped_ptr<ChromeNetworkDelegate> network_delegate( 324 new ChromeNetworkDelegate(forwarder(), &enable_referrers_)); 325 network_delegate->set_cookie_settings(cookie_settings_); 326 return network_delegate.Pass(); 327 } 328 329 void SetDelegate(net::NetworkDelegate* delegate) { 330 network_delegate_ = delegate; 331 context_.set_network_delegate(network_delegate_); 332 } 333 334 protected: 335 extensions::EventRouterForwarder* forwarder() { 336 #if defined(ENABLE_EXTENSIONS) 337 return forwarder_.get(); 338 #else 339 return NULL; 340 #endif 341 } 342 343 content::TestBrowserThreadBundle thread_bundle_; 344 #if defined(ENABLE_EXTENSIONS) 345 scoped_refptr<extensions::EventRouterForwarder> forwarder_; 346 #endif 347 TestingProfile profile_; 348 CookieSettings* cookie_settings_; 349 BooleanPrefMember enable_referrers_; 350 scoped_ptr<net::URLRequest> request_; 351 net::TestURLRequestContext context_; 352 net::NetworkDelegate* network_delegate_; 353 354 const GURL kBlockedSite; 355 const GURL kAllowedSite; 356 const GURL kEmptyFirstPartySite; 357 const GURL kFirstPartySite; 358 const GURL kBlockedFirstPartySite; 359 }; 360 361 TEST_F(ChromeNetworkDelegatePrivacyModeTest, DisablePrivacyIfCookiesAllowed) { 362 scoped_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); 363 SetDelegate(delegate.get()); 364 365 EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, 366 kEmptyFirstPartySite)); 367 } 368 369 370 TEST_F(ChromeNetworkDelegatePrivacyModeTest, EnablePrivacyIfCookiesBlocked) { 371 scoped_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); 372 SetDelegate(delegate.get()); 373 374 EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kBlockedSite, 375 kEmptyFirstPartySite)); 376 377 cookie_settings_->SetCookieSetting( 378 ContentSettingsPattern::FromURL(kBlockedSite), 379 ContentSettingsPattern::Wildcard(), 380 CONTENT_SETTING_BLOCK); 381 EXPECT_TRUE(network_delegate_->CanEnablePrivacyMode(kBlockedSite, 382 kEmptyFirstPartySite)); 383 } 384 385 TEST_F(ChromeNetworkDelegatePrivacyModeTest, EnablePrivacyIfThirdPartyBlocked) { 386 scoped_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); 387 SetDelegate(delegate.get()); 388 389 EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, 390 kFirstPartySite)); 391 392 profile_.GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true); 393 EXPECT_TRUE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, 394 kFirstPartySite)); 395 profile_.GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, false); 396 EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, 397 kFirstPartySite)); 398 } 399 400 TEST_F(ChromeNetworkDelegatePrivacyModeTest, 401 DisablePrivacyIfOnlyFirstPartyBlocked) { 402 scoped_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); 403 SetDelegate(delegate.get()); 404 405 EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, 406 kBlockedFirstPartySite)); 407 408 cookie_settings_->SetCookieSetting( 409 ContentSettingsPattern::FromURL(kBlockedFirstPartySite), 410 ContentSettingsPattern::Wildcard(), 411 CONTENT_SETTING_BLOCK); 412 // Privacy mode is disabled as kAllowedSite is still getting cookies 413 EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, 414 kBlockedFirstPartySite)); 415 } 416 417