Home | History | Annotate | Download | only in browser
      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/bind.h"
      6 #include "base/strings/string_number_conversions.h"
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/app/chrome_command_ids.h"
      9 #include "chrome/browser/chrome_notification_types.h"
     10 #include "chrome/browser/tab_contents/render_view_context_menu.h"
     11 #include "chrome/browser/tab_contents/render_view_context_menu_browsertest_util.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/browser_commands.h"
     14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     15 #include "chrome/test/base/in_process_browser_test.h"
     16 #include "chrome/test/base/ui_test_utils.h"
     17 #include "content/public/browser/notification_service.h"
     18 #include "content/public/browser/render_view_host.h"
     19 #include "content/public/browser/web_contents.h"
     20 #include "content/public/test/browser_test_utils.h"
     21 #include "net/test/spawned_test_server/spawned_test_server.h"
     22 #include "third_party/WebKit/public/web/WebInputEvent.h"
     23 
     24 // GTK requires a X11-level mouse event to open a context menu correctly.
     25 #if defined(TOOLKIT_GTK)
     26 #define MAYBE_ContextMenuOrigin DISABLED_ContextMenuOrigin
     27 #define MAYBE_HttpsContextMenuOrigin DISABLED_HttpsContextMenuOrigin
     28 #define MAYBE_ContextMenuRedirect DISABLED_ContextMenuRedirect
     29 #define MAYBE_HttpsContextMenuRedirect DISABLED_HttpsContextMenuRedirect
     30 #else
     31 #define MAYBE_ContextMenuOrigin ContextMenuOrigin
     32 #define MAYBE_HttpsContextMenuOrigin HttpsContextMenuOrigin
     33 #define MAYBE_ContextMenuRedirect ContextMenuRedirect
     34 #define MAYBE_HttpsContextMenuRedirect HttpsContextMenuRedirect
     35 #endif
     36 
     37 namespace {
     38 
     39 const base::FilePath::CharType kDocRoot[] =
     40     FILE_PATH_LITERAL("chrome/test/data/referrer_policy");
     41 
     42 }  // namespace
     43 
     44 class ReferrerPolicyTest : public InProcessBrowserTest {
     45  public:
     46    ReferrerPolicyTest() {}
     47    virtual ~ReferrerPolicyTest() {}
     48 
     49    virtual void SetUp() OVERRIDE {
     50      test_server_.reset(new net::SpawnedTestServer(
     51                             net::SpawnedTestServer::TYPE_HTTP,
     52                             net::SpawnedTestServer::kLocalhost,
     53                             base::FilePath(kDocRoot)));
     54      ASSERT_TRUE(test_server_->Start());
     55      ssl_test_server_.reset(new net::SpawnedTestServer(
     56                                 net::SpawnedTestServer::TYPE_HTTPS,
     57                                 net::SpawnedTestServer::kLocalhost,
     58                                 base::FilePath(kDocRoot)));
     59      ASSERT_TRUE(ssl_test_server_->Start());
     60 
     61      InProcessBrowserTest::SetUp();
     62    }
     63 
     64  protected:
     65   enum ExpectedReferrer {
     66     EXPECT_EMPTY_REFERRER,
     67     EXPECT_FULL_REFERRER,
     68     EXPECT_ORIGIN_AS_REFERRER
     69   };
     70 
     71   // Returns the expected title for the tab with the given (full) referrer and
     72   // the expected modification of it.
     73   string16 GetExpectedTitle(const GURL& url,
     74                             ExpectedReferrer expected_referrer) {
     75     std::string referrer;
     76     switch (expected_referrer) {
     77       case EXPECT_EMPTY_REFERRER:
     78         referrer = "Referrer is empty";
     79         break;
     80       case EXPECT_FULL_REFERRER:
     81         referrer = "Referrer is " + url.spec();
     82         break;
     83       case EXPECT_ORIGIN_AS_REFERRER:
     84         referrer = "Referrer is " + url.GetWithEmptyPath().spec();
     85         break;
     86     }
     87     return ASCIIToUTF16(referrer);
     88   }
     89 
     90   // Adds all possible titles to the TitleWatcher, so we don't time out
     91   // waiting for the title if the test fails.
     92   void AddAllPossibleTitles(const GURL& url,
     93                             content::TitleWatcher* title_watcher) {
     94     title_watcher->AlsoWaitForTitle(
     95         GetExpectedTitle(url, EXPECT_EMPTY_REFERRER));
     96     title_watcher->AlsoWaitForTitle(
     97         GetExpectedTitle(url, EXPECT_FULL_REFERRER));
     98     title_watcher->AlsoWaitForTitle(
     99         GetExpectedTitle(url, EXPECT_ORIGIN_AS_REFERRER));
    100   }
    101 
    102   // Navigates from a page with a given |referrer_policy| and checks that the
    103   // reported referrer matches the expectation.
    104   // Parameters:
    105   //  referrer_policy:   The referrer policy to test ("default", "always",
    106   //                     "origin", "never")
    107   //  start_on_https:    True if the test should start on an HTTPS page.
    108   //  target_blank:      True if the link that is generated should have the
    109   //                     attribute target=_blank
    110   //  redirect:          True if the link target should first do a server
    111   //                     redirect before evaluating the passed referrer.
    112   //  opens_new_tab:     True if this test opens a new tab.
    113   //  button:            If not WebMouseEvent::ButtonNone, click on the
    114   //                     link with the specified mouse button.
    115   //  expected_referrer: The kind of referrer to expect.
    116   //
    117   // Returns:
    118   //  The URL of the first page navigated to.
    119   GURL RunReferrerTest(const std::string referrer_policy,
    120                        bool start_on_https,
    121                        bool target_blank,
    122                        bool redirect,
    123                        bool opens_new_tab,
    124                        WebKit::WebMouseEvent::Button button,
    125                        ExpectedReferrer expected_referrer) {
    126     GURL start_url;
    127     net::SpawnedTestServer* start_server =
    128         start_on_https ? ssl_test_server_.get() : test_server_.get();
    129     start_url = start_server->GetURL(
    130         std::string("files/referrer-policy-start.html?") +
    131         "policy=" + referrer_policy +
    132         "&port=" + base::IntToString(test_server_->host_port_pair().port()) +
    133         "&ssl_port=" +
    134             base::IntToString(ssl_test_server_->host_port_pair().port()) +
    135         "&redirect=" + (redirect ? "true" : "false") +
    136         "&link=" +
    137             (button == WebKit::WebMouseEvent::ButtonNone ? "false" : "true") +
    138         "&target=" + (target_blank ? "_blank" : ""));
    139 
    140     ui_test_utils::WindowedTabAddedNotificationObserver tab_added_observer(
    141         content::NotificationService::AllSources());
    142 
    143     string16 expected_title = GetExpectedTitle(start_url, expected_referrer);
    144     content::WebContents* tab =
    145         browser()->tab_strip_model()->GetActiveWebContents();
    146     content::TitleWatcher title_watcher(tab, expected_title);
    147 
    148     // Watch for all possible outcomes to avoid timeouts if something breaks.
    149     AddAllPossibleTitles(start_url, &title_watcher);
    150 
    151     ui_test_utils::NavigateToURL(browser(), start_url);
    152 
    153     if (button != WebKit::WebMouseEvent::ButtonNone) {
    154       WebKit::WebMouseEvent mouse_event;
    155       mouse_event.type = WebKit::WebInputEvent::MouseDown;
    156       mouse_event.button = button;
    157       mouse_event.x = 15;
    158       mouse_event.y = 15;
    159       mouse_event.clickCount = 1;
    160       tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    161       mouse_event.type = WebKit::WebInputEvent::MouseUp;
    162       tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    163     }
    164 
    165     if (opens_new_tab) {
    166       tab_added_observer.Wait();
    167       tab = tab_added_observer.GetTab();
    168       EXPECT_TRUE(tab);
    169       content::WaitForLoadStop(tab);
    170       EXPECT_EQ(expected_title, tab->GetTitle());
    171     } else {
    172       EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    173     }
    174 
    175     return start_url;
    176   }
    177 
    178   scoped_ptr<net::SpawnedTestServer> test_server_;
    179   scoped_ptr<net::SpawnedTestServer> ssl_test_server_;
    180 };
    181 
    182 // The basic behavior of referrer policies is covered by layout tests in
    183 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
    184 // code paths chrome uses to navigate. To keep the number of combinations down,
    185 // we only test the "origin" policy here.
    186 //
    187 // Some tests are marked as FAILS, see http://crbug.com/124750
    188 
    189 // Content initiated navigation, from HTTP to HTTP.
    190 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Origin) {
    191   RunReferrerTest("origin", false, false, false, false,
    192                   WebKit::WebMouseEvent::ButtonNone,
    193                   EXPECT_ORIGIN_AS_REFERRER);
    194 }
    195 
    196 // Content initiated navigation, from HTTPS to HTTP.
    197 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsDefault) {
    198   RunReferrerTest("origin", true, false, false, false,
    199                   WebKit::WebMouseEvent::ButtonNone,
    200                   EXPECT_ORIGIN_AS_REFERRER);
    201 }
    202 
    203 // User initiated navigation, from HTTP to HTTP.
    204 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickOrigin) {
    205   RunReferrerTest("origin", false, false, false, false,
    206                   WebKit::WebMouseEvent::ButtonLeft,
    207                   EXPECT_ORIGIN_AS_REFERRER);
    208 }
    209 
    210 // User initiated navigation, from HTTPS to HTTP.
    211 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickOrigin) {
    212   RunReferrerTest("origin", true, false, false, false,
    213                   WebKit::WebMouseEvent::ButtonLeft,
    214                   EXPECT_ORIGIN_AS_REFERRER);
    215 }
    216 
    217 // User initiated navigation, middle click, from HTTP to HTTP.
    218 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickOrigin) {
    219   RunReferrerTest("origin", false, false, false, true,
    220                   WebKit::WebMouseEvent::ButtonMiddle,
    221                   EXPECT_ORIGIN_AS_REFERRER);
    222 }
    223 
    224 // User initiated navigation, middle click, from HTTPS to HTTP.
    225 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickOrigin) {
    226   RunReferrerTest("origin", true, false, false, true,
    227                   WebKit::WebMouseEvent::ButtonMiddle,
    228                   EXPECT_ORIGIN_AS_REFERRER);
    229 }
    230 
    231 // User initiated navigation, target blank, from HTTP to HTTP.
    232 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankOrigin) {
    233   RunReferrerTest("origin", false, true, false, true,
    234                   WebKit::WebMouseEvent::ButtonLeft,
    235                   EXPECT_ORIGIN_AS_REFERRER);
    236 }
    237 
    238 // User initiated navigation, target blank, from HTTPS to HTTP.
    239 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankOrigin) {
    240   RunReferrerTest("origin", true, true, false, true,
    241                   WebKit::WebMouseEvent::ButtonLeft,
    242                   EXPECT_ORIGIN_AS_REFERRER);
    243 }
    244 
    245 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
    246 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankOrigin) {
    247   RunReferrerTest("origin", false, true, false, true,
    248                   WebKit::WebMouseEvent::ButtonMiddle,
    249                   EXPECT_ORIGIN_AS_REFERRER);
    250 }
    251 
    252 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
    253 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickTargetBlankOrigin) {
    254   RunReferrerTest("origin", true, true, false, true,
    255                   WebKit::WebMouseEvent::ButtonMiddle,
    256                   EXPECT_ORIGIN_AS_REFERRER);
    257 }
    258 
    259 // Context menu, from HTTP to HTTP.
    260 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuOrigin) {
    261   ContextMenuNotificationObserver context_menu_observer(
    262       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
    263   RunReferrerTest("origin", false, false, false, true,
    264                   WebKit::WebMouseEvent::ButtonRight,
    265                   EXPECT_ORIGIN_AS_REFERRER);
    266 }
    267 
    268 // Context menu, from HTTPS to HTTP.
    269 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuOrigin) {
    270   ContextMenuNotificationObserver context_menu_observer(
    271       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
    272   RunReferrerTest("origin", true, false, false, true,
    273                   WebKit::WebMouseEvent::ButtonRight,
    274                   EXPECT_ORIGIN_AS_REFERRER);
    275 }
    276 
    277 // Content initiated navigation, from HTTP to HTTP via server redirect.
    278 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Redirect) {
    279   RunReferrerTest("origin", false, false, true, false,
    280                   WebKit::WebMouseEvent::ButtonNone,
    281                   EXPECT_ORIGIN_AS_REFERRER);
    282 }
    283 
    284 // Content initiated navigation, from HTTPS to HTTP via server redirect.
    285 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsRedirect) {
    286   RunReferrerTest("origin", true, false, true, false,
    287                   WebKit::WebMouseEvent::ButtonNone,
    288                   EXPECT_ORIGIN_AS_REFERRER);
    289 }
    290 
    291 // User initiated navigation, from HTTP to HTTP via server redirect.
    292 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickRedirect) {
    293   RunReferrerTest("origin", false, false, true, false,
    294                   WebKit::WebMouseEvent::ButtonLeft,
    295                   EXPECT_ORIGIN_AS_REFERRER);
    296 }
    297 
    298 // User initiated navigation, from HTTPS to HTTP via server redirect.
    299 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickRedirect) {
    300   RunReferrerTest("origin", true, false, true, false,
    301                   WebKit::WebMouseEvent::ButtonLeft,
    302                   EXPECT_ORIGIN_AS_REFERRER);
    303 }
    304 
    305 // User initiated navigation, middle click, from HTTP to HTTP via server
    306 // redirect.
    307 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickRedirect) {
    308   RunReferrerTest("origin", false, false, true, true,
    309                   WebKit::WebMouseEvent::ButtonMiddle,
    310                   EXPECT_ORIGIN_AS_REFERRER);
    311 }
    312 
    313 // User initiated navigation, middle click, from HTTPS to HTTP via server
    314 // redirect.
    315 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickRedirect) {
    316   RunReferrerTest("origin", true, false, true, true,
    317                   WebKit::WebMouseEvent::ButtonMiddle,
    318                   EXPECT_ORIGIN_AS_REFERRER);
    319 }
    320 
    321 // User initiated navigation, target blank, from HTTP to HTTP via server
    322 // redirect.
    323 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankRedirect) {
    324   RunReferrerTest("origin", false, true, true, true,
    325                   WebKit::WebMouseEvent::ButtonLeft,
    326                   EXPECT_ORIGIN_AS_REFERRER);
    327 }
    328 
    329 // User initiated navigation, target blank, from HTTPS to HTTP via server
    330 // redirect.
    331 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankRedirect) {
    332   RunReferrerTest("origin", true, true, true, true,
    333                   WebKit::WebMouseEvent::ButtonLeft,
    334                   EXPECT_ORIGIN_AS_REFERRER);
    335 }
    336 
    337 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
    338 // server redirect.
    339 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankRedirect) {
    340   RunReferrerTest("origin", false, true, true, true,
    341                   WebKit::WebMouseEvent::ButtonMiddle,
    342                   EXPECT_ORIGIN_AS_REFERRER);
    343 }
    344 
    345 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
    346 // via server redirect.
    347 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
    348                        HttpsMiddleClickTargetBlankRedirect) {
    349   RunReferrerTest("origin", true, true, true, true,
    350                   WebKit::WebMouseEvent::ButtonMiddle,
    351                   EXPECT_ORIGIN_AS_REFERRER);
    352 }
    353 
    354 // Context menu, from HTTP to HTTP via server redirect.
    355 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuRedirect) {
    356   ContextMenuNotificationObserver context_menu_observer(
    357       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
    358   RunReferrerTest("origin", false, false, true, true,
    359                   WebKit::WebMouseEvent::ButtonRight,
    360                   EXPECT_ORIGIN_AS_REFERRER);
    361 }
    362 
    363 // Context menu, from HTTPS to HTTP via server redirect.
    364 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuRedirect) {
    365   ContextMenuNotificationObserver context_menu_observer(
    366       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
    367   RunReferrerTest("origin", true, false, true, true,
    368                   WebKit::WebMouseEvent::ButtonRight,
    369                   EXPECT_ORIGIN_AS_REFERRER);
    370 }
    371 
    372 // Tests history navigation actions: Navigate from A to B with a referrer
    373 // policy, then navigate to C, back to B, and reload.
    374 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, History) {
    375   // Navigate from A to B.
    376   GURL start_url = RunReferrerTest("origin", true, false, true, false,
    377                                    WebKit::WebMouseEvent::ButtonLeft,
    378                                    EXPECT_ORIGIN_AS_REFERRER);
    379 
    380   // Navigate to C.
    381   ui_test_utils::NavigateToURL(browser(), test_server_->GetURL(std::string()));
    382 
    383   string16 expected_title =
    384       GetExpectedTitle(start_url, EXPECT_ORIGIN_AS_REFERRER);
    385   content::WebContents* tab =
    386       browser()->tab_strip_model()->GetActiveWebContents();
    387   scoped_ptr<content::TitleWatcher> title_watcher(
    388       new content::TitleWatcher(tab, expected_title));
    389 
    390   // Watch for all possible outcomes to avoid timeouts if something breaks.
    391   AddAllPossibleTitles(start_url, title_watcher.get());
    392 
    393   // Go back to B.
    394   chrome::GoBack(browser(), CURRENT_TAB);
    395   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
    396 
    397   title_watcher.reset(new content::TitleWatcher(tab, expected_title));
    398   AddAllPossibleTitles(start_url, title_watcher.get());
    399 
    400   // Reload to B.
    401   chrome::Reload(browser(), CURRENT_TAB);
    402   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
    403 
    404   title_watcher.reset(new content::TitleWatcher(tab, expected_title));
    405   AddAllPossibleTitles(start_url, title_watcher.get());
    406 
    407   // Shift-reload to B.
    408   chrome::ReloadIgnoringCache(browser(), CURRENT_TAB);
    409   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
    410 }
    411