Home | History | Annotate | Download | only in net
      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 + "&param=%26%26%26",
    247                        "q=%26%26%26&param=%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