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/renderer_context_menu/render_view_context_menu.h"
12 #include "chrome/browser/renderer_context_menu/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"
30 const base::FilePath::CharType kDocRoot
[] =
31 FILE_PATH_LITERAL("chrome/test/data/referrer_policy");
35 class ReferrerPolicyTest
: public InProcessBrowserTest
{
37 ReferrerPolicyTest() {}
38 virtual ~ReferrerPolicyTest() {}
40 virtual void SetUp() OVERRIDE
{
41 test_server_
.reset(new net::SpawnedTestServer(
42 net::SpawnedTestServer::TYPE_HTTP
,
43 net::SpawnedTestServer::kLocalhost
,
44 base::FilePath(kDocRoot
)));
45 ASSERT_TRUE(test_server_
->Start());
46 ssl_test_server_
.reset(new net::SpawnedTestServer(
47 net::SpawnedTestServer::TYPE_HTTPS
,
48 net::SpawnedTestServer::kLocalhost
,
49 base::FilePath(kDocRoot
)));
50 ASSERT_TRUE(ssl_test_server_
->Start());
52 InProcessBrowserTest::SetUp();
56 enum ExpectedReferrer
{
57 EXPECT_EMPTY_REFERRER
,
59 EXPECT_ORIGIN_AS_REFERRER
62 // Returns the expected title for the tab with the given (full) referrer and
63 // the expected modification of it.
64 base::string16
GetExpectedTitle(const GURL
& url
,
65 ExpectedReferrer expected_referrer
) {
67 switch (expected_referrer
) {
68 case EXPECT_EMPTY_REFERRER
:
69 referrer
= "Referrer is empty";
71 case EXPECT_FULL_REFERRER
:
72 referrer
= "Referrer is " + url
.spec();
74 case EXPECT_ORIGIN_AS_REFERRER
:
75 referrer
= "Referrer is " + url
.GetWithEmptyPath().spec();
78 return base::ASCIIToUTF16(referrer
);
81 // Adds all possible titles to the TitleWatcher, so we don't time out
82 // waiting for the title if the test fails.
83 void AddAllPossibleTitles(const GURL
& url
,
84 content::TitleWatcher
* title_watcher
) {
85 title_watcher
->AlsoWaitForTitle(
86 GetExpectedTitle(url
, EXPECT_EMPTY_REFERRER
));
87 title_watcher
->AlsoWaitForTitle(
88 GetExpectedTitle(url
, EXPECT_FULL_REFERRER
));
89 title_watcher
->AlsoWaitForTitle(
90 GetExpectedTitle(url
, EXPECT_ORIGIN_AS_REFERRER
));
93 // Returns a string representation of a given |referrer_policy|.
94 std::string
ReferrerPolicyToString(blink::WebReferrerPolicy referrer_policy
) {
95 switch (referrer_policy
) {
96 case blink::WebReferrerPolicyDefault
:
98 case blink::WebReferrerPolicyOrigin
:
100 case blink::WebReferrerPolicyAlways
:
102 case blink::WebReferrerPolicyNever
:
110 enum StartOnProtocol
{ START_ON_HTTP
, START_ON_HTTPS
, };
112 enum LinkType
{ REGULAR_LINK
, LINk_WITH_TARGET_BLANK
, };
114 enum RedirectType
{ NO_REDIRECT
, SERVER_REDIRECT
, SERVER_REDIRECT_ON_HTTP
, };
116 std::string
RedirectTypeToString(RedirectType redirect
) {
120 case SERVER_REDIRECT
:
122 case SERVER_REDIRECT_ON_HTTP
:
129 // Navigates from a page with a given |referrer_policy| and checks that the
130 // reported referrer matches the expectation.
132 // referrer_policy: The referrer policy to test.
133 // start_protocol: The protocol the test should start on.
134 // link_type: The link type that is used to trigger the navigation.
135 // redirect: Whether the link target should redirect and how.
136 // disposition: The disposition for the navigation.
137 // button: If not WebMouseEvent::ButtonNone, click on the
138 // link with the specified mouse button.
139 // expected_referrer: The kind of referrer to expect.
142 // The URL of the first page navigated to.
143 GURL
RunReferrerTest(const blink::WebReferrerPolicy referrer_policy
,
144 StartOnProtocol start_protocol
,
146 RedirectType redirect
,
147 WindowOpenDisposition disposition
,
148 blink::WebMouseEvent::Button button
,
149 ExpectedReferrer expected_referrer
) {
151 net::SpawnedTestServer
* start_server
= start_protocol
== START_ON_HTTPS
152 ? ssl_test_server_
.get()
153 : test_server_
.get();
154 start_url
= start_server
->GetURL(
155 std::string("files/referrer-policy-start.html?") + "policy=" +
156 ReferrerPolicyToString(referrer_policy
) + "&port=" +
157 base::IntToString(test_server_
->host_port_pair().port()) +
159 base::IntToString(ssl_test_server_
->host_port_pair().port()) +
160 "&redirect=" + RedirectTypeToString(redirect
) + "&link=" +
161 (button
== blink::WebMouseEvent::ButtonNone
? "false" : "true") +
162 "&target=" + (link_type
== LINk_WITH_TARGET_BLANK
? "_blank" : ""));
164 ui_test_utils::WindowedTabAddedNotificationObserver
tab_added_observer(
165 content::NotificationService::AllSources());
167 base::string16 expected_title
=
168 GetExpectedTitle(start_url
, expected_referrer
);
169 content::WebContents
* tab
=
170 browser()->tab_strip_model()->GetActiveWebContents();
171 content::TitleWatcher
title_watcher(tab
, expected_title
);
173 // Watch for all possible outcomes to avoid timeouts if something breaks.
174 AddAllPossibleTitles(start_url
, &title_watcher
);
176 ui_test_utils::NavigateToURL(browser(), start_url
);
178 if (button
!= blink::WebMouseEvent::ButtonNone
) {
179 blink::WebMouseEvent mouse_event
;
180 mouse_event
.type
= blink::WebInputEvent::MouseDown
;
181 mouse_event
.button
= button
;
184 mouse_event
.clickCount
= 1;
185 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
186 mouse_event
.type
= blink::WebInputEvent::MouseUp
;
187 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
190 if (disposition
== CURRENT_TAB
) {
191 EXPECT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
193 tab_added_observer
.Wait();
194 tab
= tab_added_observer
.GetTab();
196 content::TitleWatcher
title_watcher2(tab
, expected_title
);
198 // Watch for all possible outcomes to avoid timeouts if something breaks.
199 AddAllPossibleTitles(start_url
, &title_watcher2
);
201 EXPECT_EQ(expected_title
, title_watcher2
.WaitAndGetTitle());
204 EXPECT_EQ(referrer_policy
,
205 tab
->GetController().GetActiveEntry()->GetReferrer().policy
);
210 scoped_ptr
<net::SpawnedTestServer
> test_server_
;
211 scoped_ptr
<net::SpawnedTestServer
> ssl_test_server_
;
214 // The basic behavior of referrer policies is covered by layout tests in
215 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
216 // code paths chrome uses to navigate. To keep the number of combinations down,
217 // we only test the "origin" policy here.
219 // Some tests are marked as FAILS, see http://crbug.com/124750
221 // Content initiated navigation, from HTTP to HTTP.
222 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, Origin
) {
223 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
228 blink::WebMouseEvent::ButtonNone
,
229 EXPECT_ORIGIN_AS_REFERRER
);
232 // Content initiated navigation, from HTTPS to HTTP.
233 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsDefault
) {
234 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
239 blink::WebMouseEvent::ButtonNone
,
240 EXPECT_ORIGIN_AS_REFERRER
);
243 // User initiated navigation, from HTTP to HTTP.
244 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, LeftClickOrigin
) {
245 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
250 blink::WebMouseEvent::ButtonLeft
,
251 EXPECT_ORIGIN_AS_REFERRER
);
254 // User initiated navigation, from HTTPS to HTTP.
255 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsLeftClickOrigin
) {
256 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
261 blink::WebMouseEvent::ButtonLeft
,
262 EXPECT_ORIGIN_AS_REFERRER
);
265 // User initiated navigation, middle click, from HTTP to HTTP.
266 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickOrigin
) {
267 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
272 blink::WebMouseEvent::ButtonMiddle
,
273 EXPECT_ORIGIN_AS_REFERRER
);
276 // User initiated navigation, middle click, from HTTPS to HTTP.
277 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsMiddleClickOrigin
) {
278 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
283 blink::WebMouseEvent::ButtonMiddle
,
284 EXPECT_ORIGIN_AS_REFERRER
);
287 // User initiated navigation, target blank, from HTTP to HTTP.
288 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, TargetBlankOrigin
) {
289 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
291 LINk_WITH_TARGET_BLANK
,
294 blink::WebMouseEvent::ButtonLeft
,
295 EXPECT_ORIGIN_AS_REFERRER
);
298 // User initiated navigation, target blank, from HTTPS to HTTP.
299 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsTargetBlankOrigin
) {
300 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
302 LINk_WITH_TARGET_BLANK
,
305 blink::WebMouseEvent::ButtonLeft
,
306 EXPECT_ORIGIN_AS_REFERRER
);
309 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
310 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickTargetBlankOrigin
) {
311 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
313 LINk_WITH_TARGET_BLANK
,
316 blink::WebMouseEvent::ButtonMiddle
,
317 EXPECT_ORIGIN_AS_REFERRER
);
320 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
321 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsMiddleClickTargetBlankOrigin
) {
322 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
324 LINk_WITH_TARGET_BLANK
,
327 blink::WebMouseEvent::ButtonMiddle
,
328 EXPECT_ORIGIN_AS_REFERRER
);
331 // Context menu, from HTTP to HTTP.
332 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, ContextMenuOrigin
) {
333 ContextMenuNotificationObserver
context_menu_observer(
334 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
335 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
340 blink::WebMouseEvent::ButtonRight
,
341 EXPECT_ORIGIN_AS_REFERRER
);
344 // Context menu, from HTTPS to HTTP.
345 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsContextMenuOrigin
) {
346 ContextMenuNotificationObserver
context_menu_observer(
347 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
348 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
353 blink::WebMouseEvent::ButtonRight
,
354 EXPECT_ORIGIN_AS_REFERRER
);
357 // Content initiated navigation, from HTTP to HTTP via server redirect.
358 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, Redirect
) {
359 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
364 blink::WebMouseEvent::ButtonNone
,
365 EXPECT_ORIGIN_AS_REFERRER
);
368 // Content initiated navigation, from HTTPS to HTTP via server redirect.
369 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsRedirect
) {
370 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
375 blink::WebMouseEvent::ButtonNone
,
376 EXPECT_ORIGIN_AS_REFERRER
);
379 // User initiated navigation, from HTTP to HTTP via server redirect.
380 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, LeftClickRedirect
) {
381 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
386 blink::WebMouseEvent::ButtonLeft
,
387 EXPECT_ORIGIN_AS_REFERRER
);
390 // User initiated navigation, from HTTPS to HTTP via server redirect.
391 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsLeftClickRedirect
) {
392 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
397 blink::WebMouseEvent::ButtonLeft
,
398 EXPECT_ORIGIN_AS_REFERRER
);
401 // User initiated navigation, middle click, from HTTP to HTTP via server
403 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickRedirect
) {
404 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
409 blink::WebMouseEvent::ButtonMiddle
,
410 EXPECT_ORIGIN_AS_REFERRER
);
413 // User initiated navigation, middle click, from HTTPS to HTTP via server
415 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsMiddleClickRedirect
) {
416 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
421 blink::WebMouseEvent::ButtonMiddle
,
422 EXPECT_ORIGIN_AS_REFERRER
);
425 // User initiated navigation, target blank, from HTTP to HTTP via server
427 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, TargetBlankRedirect
) {
428 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
430 LINk_WITH_TARGET_BLANK
,
433 blink::WebMouseEvent::ButtonLeft
,
434 EXPECT_ORIGIN_AS_REFERRER
);
437 // User initiated navigation, target blank, from HTTPS to HTTP via server
439 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsTargetBlankRedirect
) {
440 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
442 LINk_WITH_TARGET_BLANK
,
445 blink::WebMouseEvent::ButtonLeft
,
446 EXPECT_ORIGIN_AS_REFERRER
);
449 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
451 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickTargetBlankRedirect
) {
452 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
454 LINk_WITH_TARGET_BLANK
,
457 blink::WebMouseEvent::ButtonMiddle
,
458 EXPECT_ORIGIN_AS_REFERRER
);
461 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
462 // via server redirect.
463 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
,
464 HttpsMiddleClickTargetBlankRedirect
) {
465 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
467 LINk_WITH_TARGET_BLANK
,
470 blink::WebMouseEvent::ButtonMiddle
,
471 EXPECT_ORIGIN_AS_REFERRER
);
474 // Context menu, from HTTP to HTTP via server redirect.
475 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, ContextMenuRedirect
) {
476 ContextMenuNotificationObserver
context_menu_observer(
477 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
478 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
483 blink::WebMouseEvent::ButtonRight
,
484 EXPECT_ORIGIN_AS_REFERRER
);
487 // Context menu, from HTTPS to HTTP via server redirect.
488 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsContextMenuRedirect
) {
489 ContextMenuNotificationObserver
context_menu_observer(
490 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
491 RunReferrerTest(blink::WebReferrerPolicyOrigin
,
496 blink::WebMouseEvent::ButtonRight
,
497 EXPECT_ORIGIN_AS_REFERRER
);
500 // Tests history navigation actions: Navigate from A to B with a referrer
501 // policy, then navigate to C, back to B, and reload.
502 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, History
) {
503 // Navigate from A to B.
504 GURL start_url
= RunReferrerTest(blink::WebReferrerPolicyOrigin
,
509 blink::WebMouseEvent::ButtonLeft
,
510 EXPECT_ORIGIN_AS_REFERRER
);
513 ui_test_utils::NavigateToURL(browser(), test_server_
->GetURL(std::string()));
515 base::string16 expected_title
=
516 GetExpectedTitle(start_url
, EXPECT_ORIGIN_AS_REFERRER
);
517 content::WebContents
* tab
=
518 browser()->tab_strip_model()->GetActiveWebContents();
519 scoped_ptr
<content::TitleWatcher
> title_watcher(
520 new content::TitleWatcher(tab
, expected_title
));
522 // Watch for all possible outcomes to avoid timeouts if something breaks.
523 AddAllPossibleTitles(start_url
, title_watcher
.get());
526 chrome::GoBack(browser(), CURRENT_TAB
);
527 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
529 title_watcher
.reset(new content::TitleWatcher(tab
, expected_title
));
530 AddAllPossibleTitles(start_url
, title_watcher
.get());
533 chrome::Reload(browser(), CURRENT_TAB
);
534 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
536 title_watcher
.reset(new content::TitleWatcher(tab
, expected_title
));
537 AddAllPossibleTitles(start_url
, title_watcher
.get());
539 // Shift-reload to B.
540 chrome::ReloadIgnoringCache(browser(), CURRENT_TAB
);
541 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
544 // Tests that reloading a site for "request tablet version" correctly clears
546 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, RequestTabletSite
) {
547 GURL start_url
= RunReferrerTest(blink::WebReferrerPolicyOrigin
,
550 SERVER_REDIRECT_ON_HTTP
,
552 blink::WebMouseEvent::ButtonLeft
,
553 EXPECT_ORIGIN_AS_REFERRER
);
555 base::string16 expected_title
=
556 GetExpectedTitle(start_url
, EXPECT_EMPTY_REFERRER
);
557 content::WebContents
* tab
=
558 browser()->tab_strip_model()->GetActiveWebContents();
559 content::TitleWatcher
title_watcher(tab
, expected_title
);
561 // Watch for all possible outcomes to avoid timeouts if something breaks.
562 AddAllPossibleTitles(start_url
, &title_watcher
);
564 // Request tablet version.
565 chrome::ToggleRequestTabletSite(browser());
566 EXPECT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
569 // Test that an iframes gets the parent frames referrer and referrer policy if
570 // the load was triggered by the parent, or from the iframe itself, if the
571 // navigations was started by the iframe.
572 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, IFrame
) {
573 browser()->profile()->GetPrefs()->SetBoolean(
574 prefs::kWebKitAllowRunningInsecureContent
, true);
575 content::WebContents
* tab
=
576 browser()->tab_strip_model()->GetActiveWebContents();
577 base::string16
expected_title(base::ASCIIToUTF16("loaded"));
578 scoped_ptr
<content::TitleWatcher
> title_watcher(
579 new content::TitleWatcher(tab
, expected_title
));
581 // Load a page that loads an iframe.
582 ui_test_utils::NavigateToURL(
584 ssl_test_server_
->GetURL(
585 std::string("files/referrer-policy-iframe.html?") +
586 base::IntToString(test_server_
->host_port_pair().port())));
587 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
589 // Verify that the referrer policy was honored and the main page's origin was
591 content::RenderFrameHost
* frame
= content::FrameMatchingPredicate(
592 tab
, base::Bind(&content::FrameIsChildOfMainFrame
));
594 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
596 "window.domAutomationController.send(document.title)",
598 EXPECT_EQ("Referrer is " + ssl_test_server_
->GetURL(std::string()).spec(),
601 // Reload the iframe.
602 expected_title
= base::ASCIIToUTF16("reset");
603 title_watcher
.reset(new content::TitleWatcher(tab
, expected_title
));
604 EXPECT_TRUE(content::ExecuteScript(tab
, "document.title = 'reset'"));
605 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
607 expected_title
= base::ASCIIToUTF16("loaded");
608 title_watcher
.reset(new content::TitleWatcher(tab
, expected_title
));
609 EXPECT_TRUE(content::ExecuteScript(frame
, "location.reload()"));
610 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
612 // Verify that the full url of the iframe was used as referrer.
613 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
615 "window.domAutomationController.send(document.title)",
617 EXPECT_EQ("Referrer is " +
618 test_server_
->GetURL("files/referrer-policy-log.html").spec(),