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.
6 #include "base/prefs/pref_service.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/tab_contents/render_view_context_menu.h"
12 #include "chrome/browser/tab_contents/render_view_context_menu_browsertest_util.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_commands.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/navigation_entry.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "net/test/spawned_test_server/spawned_test_server.h"
26 #include "third_party/WebKit/public/web/WebInputEvent.h"
28 // GTK requires a X11-level mouse event to open a context menu correctly.
29 #if defined(TOOLKIT_GTK)
30 #define MAYBE_ContextMenuOrigin DISABLED_ContextMenuOrigin
31 #define MAYBE_HttpsContextMenuOrigin DISABLED_HttpsContextMenuOrigin
32 #define MAYBE_ContextMenuRedirect DISABLED_ContextMenuRedirect
33 #define MAYBE_HttpsContextMenuRedirect DISABLED_HttpsContextMenuRedirect
35 #define MAYBE_ContextMenuOrigin ContextMenuOrigin
36 #define MAYBE_HttpsContextMenuOrigin HttpsContextMenuOrigin
37 #define MAYBE_ContextMenuRedirect ContextMenuRedirect
38 #define MAYBE_HttpsContextMenuRedirect HttpsContextMenuRedirect
43 const base::FilePath::CharType kDocRoot[] =
44 FILE_PATH_LITERAL("chrome/test/data/referrer_policy");
48 class ReferrerPolicyTest : public InProcessBrowserTest {
50 ReferrerPolicyTest() {}
51 virtual ~ReferrerPolicyTest() {}
53 virtual void SetUp() OVERRIDE {
54 test_server_.reset(new net::SpawnedTestServer(
55 net::SpawnedTestServer::TYPE_HTTP,
56 net::SpawnedTestServer::kLocalhost,
57 base::FilePath(kDocRoot)));
58 ASSERT_TRUE(test_server_->Start());
59 ssl_test_server_.reset(new net::SpawnedTestServer(
60 net::SpawnedTestServer::TYPE_HTTPS,
61 net::SpawnedTestServer::kLocalhost,
62 base::FilePath(kDocRoot)));
63 ASSERT_TRUE(ssl_test_server_->Start());
65 InProcessBrowserTest::SetUp();
69 enum ExpectedReferrer {
70 EXPECT_EMPTY_REFERRER,
72 EXPECT_ORIGIN_AS_REFERRER
75 // Returns the expected title for the tab with the given (full) referrer and
76 // the expected modification of it.
77 base::string16 GetExpectedTitle(const GURL& url,
78 ExpectedReferrer expected_referrer) {
80 switch (expected_referrer) {
81 case EXPECT_EMPTY_REFERRER:
82 referrer = "Referrer is empty";
84 case EXPECT_FULL_REFERRER:
85 referrer = "Referrer is " + url.spec();
87 case EXPECT_ORIGIN_AS_REFERRER:
88 referrer = "Referrer is " + url.GetWithEmptyPath().spec();
91 return base::ASCIIToUTF16(referrer);
94 // Adds all possible titles to the TitleWatcher, so we don't time out
95 // waiting for the title if the test fails.
96 void AddAllPossibleTitles(const GURL& url,
97 content::TitleWatcher* title_watcher) {
98 title_watcher->AlsoWaitForTitle(
99 GetExpectedTitle(url, EXPECT_EMPTY_REFERRER));
100 title_watcher->AlsoWaitForTitle(
101 GetExpectedTitle(url, EXPECT_FULL_REFERRER));
102 title_watcher->AlsoWaitForTitle(
103 GetExpectedTitle(url, EXPECT_ORIGIN_AS_REFERRER));
106 // Returns a string representation of a given |referrer_policy|.
107 std::string ReferrerPolicyToString(blink::WebReferrerPolicy referrer_policy) {
108 switch (referrer_policy) {
109 case blink::WebReferrerPolicyDefault:
111 case blink::WebReferrerPolicyOrigin:
113 case blink::WebReferrerPolicyAlways:
115 case blink::WebReferrerPolicyNever:
123 enum StartOnProtocol { START_ON_HTTP, START_ON_HTTPS, };
125 enum LinkType { REGULAR_LINK, LINk_WITH_TARGET_BLANK, };
127 enum RedirectType { NO_REDIRECT, SERVER_REDIRECT, SERVER_REDIRECT_ON_HTTP, };
129 std::string RedirectTypeToString(RedirectType redirect) {
133 case SERVER_REDIRECT:
135 case SERVER_REDIRECT_ON_HTTP:
142 // Navigates from a page with a given |referrer_policy| and checks that the
143 // reported referrer matches the expectation.
145 // referrer_policy: The referrer policy to test.
146 // start_protocol: The protocol the test should start on.
147 // link_type: The link type that is used to trigger the navigation.
148 // redirect: Whether the link target should redirect and how.
149 // disposition: The disposition for the navigation.
150 // button: If not WebMouseEvent::ButtonNone, click on the
151 // link with the specified mouse button.
152 // expected_referrer: The kind of referrer to expect.
155 // The URL of the first page navigated to.
156 GURL RunReferrerTest(const blink::WebReferrerPolicy referrer_policy,
157 StartOnProtocol start_protocol,
159 RedirectType redirect,
160 WindowOpenDisposition disposition,
161 blink::WebMouseEvent::Button button,
162 ExpectedReferrer expected_referrer) {
164 net::SpawnedTestServer* start_server = start_protocol == START_ON_HTTPS
165 ? ssl_test_server_.get()
166 : test_server_.get();
167 start_url = start_server->GetURL(
168 std::string("files/referrer-policy-start.html?") + "policy=" +
169 ReferrerPolicyToString(referrer_policy) + "&port=" +
170 base::IntToString(test_server_->host_port_pair().port()) +
172 base::IntToString(ssl_test_server_->host_port_pair().port()) +
173 "&redirect=" + RedirectTypeToString(redirect) + "&link=" +
174 (button == blink::WebMouseEvent::ButtonNone ? "false" : "true") +
175 "&target=" + (link_type == LINk_WITH_TARGET_BLANK ? "_blank" : ""));
177 ui_test_utils::WindowedTabAddedNotificationObserver tab_added_observer(
178 content::NotificationService::AllSources());
180 base::string16 expected_title =
181 GetExpectedTitle(start_url, expected_referrer);
182 content::WebContents* tab =
183 browser()->tab_strip_model()->GetActiveWebContents();
184 content::TitleWatcher title_watcher(tab, expected_title);
186 // Watch for all possible outcomes to avoid timeouts if something breaks.
187 AddAllPossibleTitles(start_url, &title_watcher);
189 ui_test_utils::NavigateToURL(browser(), start_url);
191 if (button != blink::WebMouseEvent::ButtonNone) {
192 blink::WebMouseEvent mouse_event;
193 mouse_event.type = blink::WebInputEvent::MouseDown;
194 mouse_event.button = button;
197 mouse_event.clickCount = 1;
198 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
199 mouse_event.type = blink::WebInputEvent::MouseUp;
200 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
203 if (disposition == CURRENT_TAB) {
204 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
206 tab_added_observer.Wait();
207 tab = tab_added_observer.GetTab();
209 content::WaitForLoadStop(tab);
210 EXPECT_EQ(expected_title, tab->GetTitle());
213 EXPECT_EQ(referrer_policy,
214 tab->GetController().GetActiveEntry()->GetReferrer().policy);
219 scoped_ptr<net::SpawnedTestServer> test_server_;
220 scoped_ptr<net::SpawnedTestServer> ssl_test_server_;
223 // The basic behavior of referrer policies is covered by layout tests in
224 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
225 // code paths chrome uses to navigate. To keep the number of combinations down,
226 // we only test the "origin" policy here.
228 // Some tests are marked as FAILS, see http://crbug.com/124750
230 // Content initiated navigation, from HTTP to HTTP.
231 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Origin) {
232 RunReferrerTest(blink::WebReferrerPolicyOrigin,
237 blink::WebMouseEvent::ButtonNone,
238 EXPECT_ORIGIN_AS_REFERRER);
241 // Content initiated navigation, from HTTPS to HTTP.
242 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsDefault) {
243 RunReferrerTest(blink::WebReferrerPolicyOrigin,
248 blink::WebMouseEvent::ButtonNone,
249 EXPECT_ORIGIN_AS_REFERRER);
252 // User initiated navigation, from HTTP to HTTP.
253 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickOrigin) {
254 RunReferrerTest(blink::WebReferrerPolicyOrigin,
259 blink::WebMouseEvent::ButtonLeft,
260 EXPECT_ORIGIN_AS_REFERRER);
263 // User initiated navigation, from HTTPS to HTTP.
264 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickOrigin) {
265 RunReferrerTest(blink::WebReferrerPolicyOrigin,
270 blink::WebMouseEvent::ButtonLeft,
271 EXPECT_ORIGIN_AS_REFERRER);
274 // User initiated navigation, middle click, from HTTP to HTTP.
275 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickOrigin) {
276 RunReferrerTest(blink::WebReferrerPolicyOrigin,
281 blink::WebMouseEvent::ButtonMiddle,
282 EXPECT_ORIGIN_AS_REFERRER);
285 // User initiated navigation, middle click, from HTTPS to HTTP.
286 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickOrigin) {
287 RunReferrerTest(blink::WebReferrerPolicyOrigin,
292 blink::WebMouseEvent::ButtonMiddle,
293 EXPECT_ORIGIN_AS_REFERRER);
296 // User initiated navigation, target blank, from HTTP to HTTP.
297 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankOrigin) {
298 RunReferrerTest(blink::WebReferrerPolicyOrigin,
300 LINk_WITH_TARGET_BLANK,
303 blink::WebMouseEvent::ButtonLeft,
304 EXPECT_ORIGIN_AS_REFERRER);
307 // User initiated navigation, target blank, from HTTPS to HTTP.
308 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankOrigin) {
309 RunReferrerTest(blink::WebReferrerPolicyOrigin,
311 LINk_WITH_TARGET_BLANK,
314 blink::WebMouseEvent::ButtonLeft,
315 EXPECT_ORIGIN_AS_REFERRER);
318 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
319 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankOrigin) {
320 RunReferrerTest(blink::WebReferrerPolicyOrigin,
322 LINk_WITH_TARGET_BLANK,
325 blink::WebMouseEvent::ButtonMiddle,
326 EXPECT_ORIGIN_AS_REFERRER);
329 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
330 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickTargetBlankOrigin) {
331 RunReferrerTest(blink::WebReferrerPolicyOrigin,
333 LINk_WITH_TARGET_BLANK,
336 blink::WebMouseEvent::ButtonMiddle,
337 EXPECT_ORIGIN_AS_REFERRER);
340 // Context menu, from HTTP to HTTP.
341 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuOrigin) {
342 ContextMenuNotificationObserver context_menu_observer(
343 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
344 RunReferrerTest(blink::WebReferrerPolicyOrigin,
349 blink::WebMouseEvent::ButtonRight,
350 EXPECT_ORIGIN_AS_REFERRER);
353 // Context menu, from HTTPS to HTTP.
354 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuOrigin) {
355 ContextMenuNotificationObserver context_menu_observer(
356 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
357 RunReferrerTest(blink::WebReferrerPolicyOrigin,
362 blink::WebMouseEvent::ButtonRight,
363 EXPECT_ORIGIN_AS_REFERRER);
366 // Content initiated navigation, from HTTP to HTTP via server redirect.
367 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Redirect) {
368 RunReferrerTest(blink::WebReferrerPolicyOrigin,
373 blink::WebMouseEvent::ButtonNone,
374 EXPECT_ORIGIN_AS_REFERRER);
377 // Content initiated navigation, from HTTPS to HTTP via server redirect.
378 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsRedirect) {
379 RunReferrerTest(blink::WebReferrerPolicyOrigin,
384 blink::WebMouseEvent::ButtonNone,
385 EXPECT_ORIGIN_AS_REFERRER);
388 // User initiated navigation, from HTTP to HTTP via server redirect.
389 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickRedirect) {
390 RunReferrerTest(blink::WebReferrerPolicyOrigin,
395 blink::WebMouseEvent::ButtonLeft,
396 EXPECT_ORIGIN_AS_REFERRER);
399 // User initiated navigation, from HTTPS to HTTP via server redirect.
400 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickRedirect) {
401 RunReferrerTest(blink::WebReferrerPolicyOrigin,
406 blink::WebMouseEvent::ButtonLeft,
407 EXPECT_ORIGIN_AS_REFERRER);
410 // User initiated navigation, middle click, from HTTP to HTTP via server
412 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickRedirect) {
413 RunReferrerTest(blink::WebReferrerPolicyOrigin,
418 blink::WebMouseEvent::ButtonMiddle,
419 EXPECT_ORIGIN_AS_REFERRER);
422 // User initiated navigation, middle click, from HTTPS to HTTP via server
424 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickRedirect) {
425 RunReferrerTest(blink::WebReferrerPolicyOrigin,
430 blink::WebMouseEvent::ButtonMiddle,
431 EXPECT_ORIGIN_AS_REFERRER);
434 // User initiated navigation, target blank, from HTTP to HTTP via server
436 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankRedirect) {
437 RunReferrerTest(blink::WebReferrerPolicyOrigin,
439 LINk_WITH_TARGET_BLANK,
442 blink::WebMouseEvent::ButtonLeft,
443 EXPECT_ORIGIN_AS_REFERRER);
446 // User initiated navigation, target blank, from HTTPS to HTTP via server
448 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankRedirect) {
449 RunReferrerTest(blink::WebReferrerPolicyOrigin,
451 LINk_WITH_TARGET_BLANK,
454 blink::WebMouseEvent::ButtonLeft,
455 EXPECT_ORIGIN_AS_REFERRER);
458 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
460 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankRedirect) {
461 RunReferrerTest(blink::WebReferrerPolicyOrigin,
463 LINk_WITH_TARGET_BLANK,
466 blink::WebMouseEvent::ButtonMiddle,
467 EXPECT_ORIGIN_AS_REFERRER);
470 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
471 // via server redirect.
472 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
473 HttpsMiddleClickTargetBlankRedirect) {
474 RunReferrerTest(blink::WebReferrerPolicyOrigin,
476 LINk_WITH_TARGET_BLANK,
479 blink::WebMouseEvent::ButtonMiddle,
480 EXPECT_ORIGIN_AS_REFERRER);
483 // Context menu, from HTTP to HTTP via server redirect.
484 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuRedirect) {
485 ContextMenuNotificationObserver context_menu_observer(
486 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
487 RunReferrerTest(blink::WebReferrerPolicyOrigin,
492 blink::WebMouseEvent::ButtonRight,
493 EXPECT_ORIGIN_AS_REFERRER);
496 // Context menu, from HTTPS to HTTP via server redirect.
497 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuRedirect) {
498 ContextMenuNotificationObserver context_menu_observer(
499 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
500 RunReferrerTest(blink::WebReferrerPolicyOrigin,
505 blink::WebMouseEvent::ButtonRight,
506 EXPECT_ORIGIN_AS_REFERRER);
509 // Tests history navigation actions: Navigate from A to B with a referrer
510 // policy, then navigate to C, back to B, and reload.
511 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, History) {
512 // Navigate from A to B.
513 GURL start_url = RunReferrerTest(blink::WebReferrerPolicyOrigin,
518 blink::WebMouseEvent::ButtonLeft,
519 EXPECT_ORIGIN_AS_REFERRER);
522 ui_test_utils::NavigateToURL(browser(), test_server_->GetURL(std::string()));
524 base::string16 expected_title =
525 GetExpectedTitle(start_url, EXPECT_ORIGIN_AS_REFERRER);
526 content::WebContents* tab =
527 browser()->tab_strip_model()->GetActiveWebContents();
528 scoped_ptr<content::TitleWatcher> title_watcher(
529 new content::TitleWatcher(tab, expected_title));
531 // Watch for all possible outcomes to avoid timeouts if something breaks.
532 AddAllPossibleTitles(start_url, title_watcher.get());
535 chrome::GoBack(browser(), CURRENT_TAB);
536 EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
538 title_watcher.reset(new content::TitleWatcher(tab, expected_title));
539 AddAllPossibleTitles(start_url, title_watcher.get());
542 chrome::Reload(browser(), CURRENT_TAB);
543 EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
545 title_watcher.reset(new content::TitleWatcher(tab, expected_title));
546 AddAllPossibleTitles(start_url, title_watcher.get());
548 // Shift-reload to B.
549 chrome::ReloadIgnoringCache(browser(), CURRENT_TAB);
550 EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
553 // Tests that reloading a site for "request tablet version" correctly clears
555 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, RequestTabletSite) {
556 GURL start_url = RunReferrerTest(blink::WebReferrerPolicyOrigin,
559 SERVER_REDIRECT_ON_HTTP,
561 blink::WebMouseEvent::ButtonLeft,
562 EXPECT_ORIGIN_AS_REFERRER);
564 base::string16 expected_title =
565 GetExpectedTitle(start_url, EXPECT_EMPTY_REFERRER);
566 content::WebContents* tab =
567 browser()->tab_strip_model()->GetActiveWebContents();
568 content::TitleWatcher title_watcher(tab, expected_title);
570 // Watch for all possible outcomes to avoid timeouts if something breaks.
571 AddAllPossibleTitles(start_url, &title_watcher);
573 // Request tablet version.
574 chrome::ToggleRequestTabletSite(browser());
575 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
578 // Test that an iframes gets the parent frames referrer and referrer policy if
579 // the load was triggered by the parent, or from the iframe itself, if the
580 // navigations was started by the iframe.
581 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, IFrame) {
582 browser()->profile()->GetPrefs()->SetBoolean(
583 prefs::kWebKitAllowRunningInsecureContent, true);
584 content::WebContents* tab =
585 browser()->tab_strip_model()->GetActiveWebContents();
586 base::string16 expected_title(base::ASCIIToUTF16("loaded"));
587 scoped_ptr<content::TitleWatcher> title_watcher(
588 new content::TitleWatcher(tab, expected_title));
590 // Load a page that loads an iframe.
591 ui_test_utils::NavigateToURL(
593 ssl_test_server_->GetURL(
594 std::string("files/referrer-policy-iframe.html?") +
595 base::IntToString(test_server_->host_port_pair().port())));
596 EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
598 // Verify that the referrer policy was honored and the main page's origin was
601 EXPECT_TRUE(content::ExecuteScriptInFrameAndExtractString(
604 "window.domAutomationController.send(document.title)",
606 EXPECT_EQ("Referrer is " + ssl_test_server_->GetURL(std::string()).spec(),
609 // Reload the iframe.
610 expected_title = base::ASCIIToUTF16("reset");
611 title_watcher.reset(new content::TitleWatcher(tab, expected_title));
612 EXPECT_TRUE(content::ExecuteScript(tab, "document.title = 'reset'"));
613 EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
615 expected_title = base::ASCIIToUTF16("loaded");
616 title_watcher.reset(new content::TitleWatcher(tab, expected_title));
618 content::ExecuteScriptInFrame(tab, "//iframe", "location.reload()"));
619 EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
621 // Verify that the full url of the iframe was used as referrer.
622 EXPECT_TRUE(content::ExecuteScriptInFrameAndExtractString(
625 "window.domAutomationController.send(document.title)",
627 EXPECT_EQ("Referrer is " +
628 test_server_->GetURL("files/referrer-policy-log.html").spec(),