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