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/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 + "&param=%26%26%26",
    264                        "q=%26%26%26&param=%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