[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / referrer_policy_browsertest.cc
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 <memory>
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/synchronization/lock.h"
12 #include "base/thread_annotations.h"
13 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/net/system_network_context_manager.h"
17 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
18 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_commands.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_features.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/test/base/in_process_browser_test.h"
25 #include "chrome/test/base/ui_test_utils.h"
26 #include "components/prefs/pref_service.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/navigation_controller.h"
29 #include "content/public/browser/navigation_entry.h"
30 #include "content/public/browser/notification_service.h"
31 #include "content/public/browser/render_view_host.h"
32 #include "content/public/browser/render_widget_host.h"
33 #include "content/public/browser/storage_partition.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/common/content_features.h"
36 #include "content/public/test/browser_test.h"
37 #include "content/public/test/browser_test_utils.h"
38 #include "net/base/features.h"
39 #include "net/test/embedded_test_server/http_request.h"
40 #include "services/network/public/mojom/referrer_policy.mojom-shared.h"
41 #include "third_party/blink/public/common/input/web_input_event.h"
42 #include "third_party/blink/public/common/input/web_mouse_event.h"
43 #include "ui/base/page_transition_types.h"
44 #include "ui/base/window_open_disposition.h"
45
46 class ReferrerPolicyTest : public InProcessBrowserTest {
47  public:
48   ReferrerPolicyTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
49     // Subclasses might want to verify the requests that arrive at servers;
50     // register a default no-op handler that subclasses may override.
51     embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
52         &ReferrerPolicyTest::OnServerIncomingRequest, base::Unretained(this)));
53     https_server_.RegisterRequestMonitor(base::BindRepeating(
54         &ReferrerPolicyTest::OnServerIncomingRequest, base::Unretained(this)));
55
56     https_server_.AddDefaultHandlers(GetChromeTestDataDir());
57     EXPECT_TRUE(embedded_test_server()->Start());
58     EXPECT_TRUE(https_server_.Start());
59   }
60   ~ReferrerPolicyTest() override = default;
61
62   enum ExpectedReferrer {
63     EXPECT_EMPTY_REFERRER,
64     EXPECT_FULL_REFERRER,
65     EXPECT_ORIGIN_AS_REFERRER
66   };
67
68  protected:
69   // Callback to verify that HTTP requests have the correct headers;
70   // currently, (See the comment on RequestCheck, below.)
71   virtual void OnServerIncomingRequest(
72       const net::test_server::HttpRequest& request) {
73     base::AutoLock lock(check_on_requests_lock_);
74     if (!check_on_requests_)
75       return;
76
77     if (request.relative_url != check_on_requests_->destination_url_to_match)
78       return;
79
80     auto it = request.headers.find("Referer");
81
82     if (check_on_requests_->expected_spec.empty()) {
83       EXPECT_TRUE(it == request.headers.end()) << it->second;
84     } else {
85       EXPECT_TRUE(it != request.headers.end());
86       if (it != request.headers.end())
87         EXPECT_EQ(it->second, check_on_requests_->expected_spec);
88     }
89   }
90
91   // Returns the expected title for the tab with the given (full) referrer and
92   // the expected modification of it.
93   base::string16 GetExpectedTitle(const GURL& url,
94                                   ExpectedReferrer expected_referrer) {
95     std::string referrer;
96     switch (expected_referrer) {
97       case EXPECT_EMPTY_REFERRER:
98         referrer = "Referrer is empty";
99         break;
100       case EXPECT_FULL_REFERRER:
101         referrer = "Referrer is " + url.spec();
102         break;
103       case EXPECT_ORIGIN_AS_REFERRER:
104         referrer = "Referrer is " + url.GetWithEmptyPath().spec();
105         break;
106     }
107     return base::ASCIIToUTF16(referrer);
108   }
109
110   // Adds all possible titles to the TitleWatcher, so we don't time out
111   // waiting for the title if the test fails.
112   void AddAllPossibleTitles(const GURL& url,
113                             content::TitleWatcher* title_watcher) {
114     title_watcher->AlsoWaitForTitle(
115         GetExpectedTitle(url, EXPECT_EMPTY_REFERRER));
116     title_watcher->AlsoWaitForTitle(
117         GetExpectedTitle(url, EXPECT_FULL_REFERRER));
118     title_watcher->AlsoWaitForTitle(
119         GetExpectedTitle(url, EXPECT_ORIGIN_AS_REFERRER));
120   }
121
122   enum StartOnProtocol { START_ON_HTTP, START_ON_HTTPS, };
123
124   enum LinkType { REGULAR_LINK, LINK_WITH_TARGET_BLANK, };
125
126   enum RedirectType {
127     NO_REDIRECT,        // direct navigation via HTTP
128     HTTPS_NO_REDIRECT,  // direct navigation via HTTPS
129     SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
130     SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
131     SERVER_REDIRECT_FROM_HTTP_TO_HTTPS
132   };
133
134   enum RendererOrBrowserInitiated { RENDERER_INITIATED, BROWSER_INITIATED };
135
136   // Navigates from a page with a given |referrer_policy| and checks that the
137   // reported referrer matches the expectation.
138   // Parameters:
139   //  referrer_policy:   The referrer policy to test.
140   //  start_protocol:    The protocol the test should start on.
141   //  link_type:         The link type that is used to trigger the navigation.
142   //  redirect:          Whether the link target should redirect and how.
143   //  disposition:       The disposition for the navigation.
144   //  button:            If not WebMouseEvent::Button::NoButton, click on the
145   //                     link with the specified mouse button.
146   //  expected_referrer: The kind of referrer to expect.
147   //  expected_referrer_policy: The expected referrer policy of the activity.
148   //  renderer_or_browser_initiated: If BROWSER_INITIATED, uses Navigate() to
149   //  load in the current WebContents and disregards the value of |button|.
150   //
151   // Returns:
152   //  The URL of the first page navigated to.
153   GURL RunReferrerTest(const network::mojom::ReferrerPolicy referrer_policy,
154                        StartOnProtocol start_protocol,
155                        LinkType link_type,
156                        RedirectType redirect,
157                        WindowOpenDisposition disposition,
158                        blink::WebMouseEvent::Button button,
159                        ExpectedReferrer expected_referrer,
160                        network::mojom::ReferrerPolicy expected_referrer_policy,
161                        RendererOrBrowserInitiated
162                            renderer_or_browser_initiated = RENDERER_INITIATED) {
163     GURL redirect_url;
164     switch (redirect) {
165       case NO_REDIRECT:
166         redirect_url = embedded_test_server()->GetURL(
167             "/referrer_policy/referrer-policy-log.html");
168         break;
169       case HTTPS_NO_REDIRECT:
170         redirect_url =
171             https_server_.GetURL("/referrer_policy/referrer-policy-log.html");
172         break;
173       case SERVER_REDIRECT_FROM_HTTPS_TO_HTTP:
174         redirect_url = https_server_.GetURL(
175             std::string("/server-redirect?") +
176             embedded_test_server()
177                 ->GetURL("/referrer_policy/referrer-policy-log.html")
178                 .spec());
179         break;
180       case SERVER_REDIRECT_FROM_HTTP_TO_HTTP:
181         redirect_url = embedded_test_server()->GetURL(
182             std::string("/server-redirect?") +
183             embedded_test_server()
184                 ->GetURL("/referrer_policy/referrer-policy-log.html")
185                 .spec());
186         break;
187       case SERVER_REDIRECT_FROM_HTTP_TO_HTTPS:
188         redirect_url = embedded_test_server()->GetURL(
189             std::string("/server-redirect?") +
190             https_server_.GetURL("/referrer_policy/referrer-policy-log.html")
191                 .spec());
192         break;
193     }
194
195     std::string relative_url =
196         std::string("/referrer_policy/referrer-policy-start.html?") +
197         "policy=" + content::ReferrerPolicyToString(referrer_policy) +
198         "&redirect=" + redirect_url.spec() + "&link=" +
199         ((button == blink::WebMouseEvent::Button::kNoButton &&
200           renderer_or_browser_initiated == RENDERER_INITIATED)
201              ? "false"
202              : "true") +
203         "&target=" + (link_type == LINK_WITH_TARGET_BLANK ? "_blank" : "");
204
205     auto* start_test_server = start_protocol == START_ON_HTTPS
206                                   ? &https_server_
207                                   : embedded_test_server();
208     const GURL start_url = start_test_server->GetURL(relative_url);
209
210     ui_test_utils::AllBrowserTabAddedWaiter add_tab;
211
212     base::string16 expected_title =
213         GetExpectedTitle(start_url, expected_referrer);
214     content::WebContents* tab =
215         browser()->tab_strip_model()->GetActiveWebContents();
216     content::TitleWatcher title_watcher(tab, expected_title);
217
218     std::string expected_referrer_value;
219     if (expected_referrer != EXPECT_EMPTY_REFERRER) {
220       expected_referrer_value =
221           base::UTF16ToASCII(expected_title)
222               .substr(base::StringPiece("Referrer is ").size());
223     }
224     base::ReleasableAutoLock releaseable_lock(&check_on_requests_lock_);
225     check_on_requests_ = RequestCheck{
226         expected_referrer_value, "/referrer_policy/referrer-policy-log.html"};
227     releaseable_lock.Release();
228
229     // Watch for all possible outcomes to avoid timeouts if something breaks.
230     AddAllPossibleTitles(start_url, &title_watcher);
231
232     ui_test_utils::NavigateToURL(browser(), start_url);
233
234     if (renderer_or_browser_initiated == BROWSER_INITIATED) {
235       CHECK(disposition == WindowOpenDisposition::CURRENT_TAB);
236       NavigateParams params(browser(), redirect_url, ui::PAGE_TRANSITION_LINK);
237       params.referrer = content::Referrer(
238           tab->GetController().GetVisibleEntry()->GetURL(), referrer_policy);
239       params.source_contents = tab;
240       ui_test_utils::NavigateToURL(&params);
241     } else if (button != blink::WebMouseEvent::Button::kNoButton) {
242       blink::WebMouseEvent mouse_event(
243           blink::WebInputEvent::Type::kMouseDown,
244           blink::WebInputEvent::kNoModifiers,
245           blink::WebInputEvent::GetStaticTimeStampForTests());
246       mouse_event.button = button;
247       mouse_event.SetPositionInWidget(15, 15);
248       mouse_event.click_count = 1;
249       tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event);
250       mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
251       tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event);
252     }
253
254     if (disposition == WindowOpenDisposition::CURRENT_TAB) {
255       EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
256     } else {
257       tab = add_tab.Wait();
258       EXPECT_TRUE(tab);
259       content::TitleWatcher title_watcher2(tab, expected_title);
260
261       // Watch for all possible outcomes to avoid timeouts if something breaks.
262       AddAllPossibleTitles(start_url, &title_watcher2);
263
264       EXPECT_EQ(expected_title, title_watcher2.WaitAndGetTitle());
265     }
266
267     EXPECT_EQ(expected_referrer_policy,
268               tab->GetController().GetVisibleEntry()->GetReferrer().policy);
269
270     base::AutoLock lock(check_on_requests_lock_);
271     check_on_requests_.reset();
272
273     return start_url;
274   }
275
276   // Shorthand for cases where |referrer_policy| is the expected policy.
277   GURL RunReferrerTest(const network::mojom::ReferrerPolicy referrer_policy,
278                        StartOnProtocol start_protocol,
279                        LinkType link_type,
280                        RedirectType redirect,
281                        WindowOpenDisposition disposition,
282                        blink::WebMouseEvent::Button button,
283                        ExpectedReferrer expected_referrer) {
284     return RunReferrerTest(referrer_policy, start_protocol, link_type, redirect,
285                            disposition, button, expected_referrer,
286                            referrer_policy);
287   }
288
289   net::EmbeddedTestServer https_server_;
290
291   // If "check_on_requests_" is set, for each HTTP request that arrives at
292   // either of the embedded test servers ("embedded_test_server()" and
293   // "https_server_"), if the relative URL equals that stored in
294   // "destination_url_to_match", OnServerIncomingRequest will assert
295   // that the provided Referer header's value equals the value of
296   // "expected_spec".
297   struct RequestCheck {
298     std::string expected_spec;
299     std::string destination_url_to_match;
300   };
301
302   base::Lock check_on_requests_lock_;
303   base::Optional<RequestCheck> check_on_requests_
304       GUARDED_BY(check_on_requests_lock_);
305 };
306
307 // The basic behavior of referrer policies is covered by layout tests in
308 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
309 // code paths chrome uses to navigate. To keep the number of combinations down,
310 // we only test the "origin" policy here.
311
312 // Content initiated navigation, from HTTP to HTTP.
313 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Origin) {
314   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
315                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
316                   blink::WebMouseEvent::Button::kNoButton,
317                   EXPECT_ORIGIN_AS_REFERRER);
318 }
319
320 // Content initiated navigation, from HTTPS to HTTP.
321 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsDefault) {
322   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
323                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
324                   blink::WebMouseEvent::Button::kNoButton,
325                   EXPECT_ORIGIN_AS_REFERRER);
326 }
327
328 // User initiated navigation, from HTTP to HTTP.
329 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickOrigin) {
330   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
331                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
332                   blink::WebMouseEvent::Button::kLeft,
333                   EXPECT_ORIGIN_AS_REFERRER);
334 }
335
336 // User initiated navigation, from HTTPS to HTTP.
337 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickOrigin) {
338   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
339                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
340                   blink::WebMouseEvent::Button::kLeft,
341                   EXPECT_ORIGIN_AS_REFERRER);
342 }
343
344 // User initiated navigation, middle click, from HTTP to HTTP.
345 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickOrigin) {
346   RunReferrerTest(
347       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
348       NO_REDIRECT, WindowOpenDisposition::NEW_BACKGROUND_TAB,
349       blink::WebMouseEvent::Button::kMiddle, EXPECT_ORIGIN_AS_REFERRER);
350 }
351
352 // User initiated navigation, middle click, from HTTPS to HTTP.
353 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickOrigin) {
354   RunReferrerTest(
355       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
356       NO_REDIRECT, WindowOpenDisposition::NEW_BACKGROUND_TAB,
357       blink::WebMouseEvent::Button::kMiddle, EXPECT_ORIGIN_AS_REFERRER);
358 }
359
360 // User initiated navigation, target blank, from HTTP to HTTP.
361 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankOrigin) {
362   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
363                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
364                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
365                   blink::WebMouseEvent::Button::kLeft,
366                   EXPECT_ORIGIN_AS_REFERRER);
367 }
368
369 // User initiated navigation, target blank, from HTTPS to HTTP.
370 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankOrigin) {
371   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
372                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
373                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
374                   blink::WebMouseEvent::Button::kLeft,
375                   EXPECT_ORIGIN_AS_REFERRER);
376 }
377
378 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
379 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankOrigin) {
380   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
381                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
382                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
383                   blink::WebMouseEvent::Button::kMiddle,
384                   EXPECT_ORIGIN_AS_REFERRER);
385 }
386
387 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
388 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickTargetBlankOrigin) {
389   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
390                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
391                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
392                   blink::WebMouseEvent::Button::kMiddle,
393                   EXPECT_ORIGIN_AS_REFERRER);
394 }
395
396 // Context menu, from HTTP to HTTP.
397 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, ContextMenuOrigin) {
398   ContextMenuNotificationObserver context_menu_observer(
399       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
400   RunReferrerTest(
401       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
402       NO_REDIRECT, WindowOpenDisposition::NEW_FOREGROUND_TAB,
403       blink::WebMouseEvent::Button::kRight, EXPECT_ORIGIN_AS_REFERRER);
404 }
405
406 // Context menu, from HTTPS to HTTP.
407 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsContextMenuOrigin) {
408   ContextMenuNotificationObserver context_menu_observer(
409       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
410   RunReferrerTest(
411       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
412       NO_REDIRECT, WindowOpenDisposition::NEW_FOREGROUND_TAB,
413       blink::WebMouseEvent::Button::kRight, EXPECT_ORIGIN_AS_REFERRER);
414 }
415
416 // Content initiated navigation, from HTTP to HTTP via server redirect.
417 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Redirect) {
418   RunReferrerTest(
419       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
420       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
421       blink::WebMouseEvent::Button::kNoButton, EXPECT_ORIGIN_AS_REFERRER);
422 }
423
424 // Content initiated navigation, from HTTPS to HTTP via server redirect.
425 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsRedirect) {
426   RunReferrerTest(
427       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
428       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
429       blink::WebMouseEvent::Button::kNoButton, EXPECT_ORIGIN_AS_REFERRER);
430 }
431
432 // User initiated navigation, from HTTP to HTTP via server redirect.
433 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickRedirect) {
434   RunReferrerTest(
435       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
436       SERVER_REDIRECT_FROM_HTTP_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
437       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
438 }
439
440 // User initiated navigation, from HTTPS to HTTP via server redirect.
441 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickRedirect) {
442   RunReferrerTest(
443       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
444       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
445       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
446 }
447
448 // User initiated navigation, middle click, from HTTP to HTTP via server
449 // redirect.
450 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickRedirect) {
451   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
452                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
453                   WindowOpenDisposition::NEW_BACKGROUND_TAB,
454                   blink::WebMouseEvent::Button::kMiddle,
455                   EXPECT_ORIGIN_AS_REFERRER);
456 }
457
458 // User initiated navigation, middle click, from HTTPS to HTTP via server
459 // redirect.
460 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickRedirect) {
461   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
462                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
463                   WindowOpenDisposition::NEW_BACKGROUND_TAB,
464                   blink::WebMouseEvent::Button::kMiddle,
465                   EXPECT_ORIGIN_AS_REFERRER);
466 }
467
468 // User initiated navigation, target blank, from HTTP to HTTP via server
469 // redirect.
470 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankRedirect) {
471   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
472                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
473                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
474                   blink::WebMouseEvent::Button::kLeft,
475                   EXPECT_ORIGIN_AS_REFERRER);
476 }
477
478 // User initiated navigation, target blank, from HTTPS to HTTP via server
479 // redirect.
480 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankRedirect) {
481   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
482                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
483                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
484                   blink::WebMouseEvent::Button::kLeft,
485                   EXPECT_ORIGIN_AS_REFERRER);
486 }
487
488 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
489 // server redirect.
490 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankRedirect) {
491   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
492                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
493                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
494                   blink::WebMouseEvent::Button::kMiddle,
495                   EXPECT_ORIGIN_AS_REFERRER);
496 }
497
498 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
499 // via server redirect.
500 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
501                        HttpsMiddleClickTargetBlankRedirect) {
502   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
503                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
504                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
505                   blink::WebMouseEvent::Button::kMiddle,
506                   EXPECT_ORIGIN_AS_REFERRER);
507 }
508
509 // Context menu, from HTTP to HTTP via server redirect.
510 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, ContextMenuRedirect) {
511   ContextMenuNotificationObserver context_menu_observer(
512       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
513   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
514                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
515                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
516                   blink::WebMouseEvent::Button::kRight,
517                   EXPECT_ORIGIN_AS_REFERRER);
518 }
519
520 // Context menu, from HTTPS to HTTP via server redirect.
521 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsContextMenuRedirect) {
522   ContextMenuNotificationObserver context_menu_observer(
523       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
524   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
525                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
526                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
527                   blink::WebMouseEvent::Button::kRight,
528                   EXPECT_ORIGIN_AS_REFERRER);
529 }
530
531 // Tests history navigation actions: Navigate from A to B with a referrer
532 // policy, then navigate to C, back to B, and reload.
533 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, History) {
534   // Navigate from A to B.
535   GURL start_url = RunReferrerTest(
536       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
537       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
538       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
539
540   // Navigate to C.
541   ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL("/"));
542
543   base::string16 expected_title =
544       GetExpectedTitle(start_url, EXPECT_ORIGIN_AS_REFERRER);
545   content::WebContents* tab =
546       browser()->tab_strip_model()->GetActiveWebContents();
547   std::unique_ptr<content::TitleWatcher> title_watcher(
548       new content::TitleWatcher(tab, expected_title));
549
550   // Watch for all possible outcomes to avoid timeouts if something breaks.
551   AddAllPossibleTitles(start_url, title_watcher.get());
552
553   // Go back to B.
554   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
555   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
556
557   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
558   AddAllPossibleTitles(start_url, title_watcher.get());
559
560   // Reload to B.
561   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
562   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
563
564   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
565   AddAllPossibleTitles(start_url, title_watcher.get());
566
567   // Shift-reload to B.
568   chrome::ReloadBypassingCache(browser(), WindowOpenDisposition::CURRENT_TAB);
569   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
570 }
571
572 // Tests that reloading a site for "request tablet version" correctly clears
573 // the referrer.
574 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, RequestTabletSite) {
575   GURL start_url = RunReferrerTest(
576       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
577       SERVER_REDIRECT_FROM_HTTP_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
578       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
579
580   base::string16 expected_title =
581       GetExpectedTitle(start_url, EXPECT_EMPTY_REFERRER);
582   content::WebContents* tab =
583       browser()->tab_strip_model()->GetActiveWebContents();
584   content::TitleWatcher title_watcher(tab, expected_title);
585
586   // Watch for all possible outcomes to avoid timeouts if something breaks.
587   AddAllPossibleTitles(start_url, &title_watcher);
588
589   // Erase the current title in the NavigationEntry.
590   //
591   // TitleWatcher overrides WebContentObserver's TitleWasSet() but also
592   // DidStopLoading(). The page that is being reloaded sets its title after load
593   // is complete, so the title change is missed because the title is checked on
594   // load. Clearing the title ensures that TitleWatcher will wait for the actual
595   // title setting.
596   tab->GetController().GetVisibleEntry()->SetTitle(base::string16());
597
598   // Request tablet version.
599   chrome::ToggleRequestTabletSite(browser());
600   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
601 }
602
603 // Test that an iframes gets the parent frames referrer and referrer policy if
604 // the load was triggered by the parent, or from the iframe itself, if the
605 // navigations was started by the iframe.
606 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, IFrame) {
607   browser()->profile()->GetPrefs()->SetBoolean(
608       prefs::kWebKitAllowRunningInsecureContent, true);
609   content::WebContents* tab =
610       browser()->tab_strip_model()->GetActiveWebContents();
611   base::string16 expected_title(base::ASCIIToUTF16("loaded"));
612   std::unique_ptr<content::TitleWatcher> title_watcher(
613       new content::TitleWatcher(tab, expected_title));
614
615   // Load a page that loads an iframe.
616   ui_test_utils::NavigateToURL(
617       browser(),
618       https_server_.GetURL("/referrer_policy/referrer-policy-iframe.html"));
619   EXPECT_TRUE(content::ExecuteScript(
620       tab,
621       std::string("var frame = document.createElement('iframe');frame.src ='") +
622           embedded_test_server()
623               ->GetURL("/referrer_policy/referrer-policy-log.html")
624               .spec() +
625           "';frame.onload = function() { document.title = 'loaded'; };" +
626           "document.body.appendChild(frame)"));
627   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
628
629   // Verify that the referrer policy was honored and the main page's origin was
630   // send as referrer.
631   content::RenderFrameHost* frame = content::FrameMatchingPredicate(
632       tab, base::Bind(&content::FrameIsChildOfMainFrame));
633   std::string title;
634   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
635       frame,
636       "window.domAutomationController.send(document.title)",
637       &title));
638   EXPECT_EQ("Referrer is " + https_server_.GetURL("/").spec(), title);
639
640   // Reload the iframe.
641   expected_title = base::ASCIIToUTF16("reset");
642   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
643   EXPECT_TRUE(content::ExecuteScript(tab, "document.title = 'reset'"));
644   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
645
646   expected_title = base::ASCIIToUTF16("loaded");
647   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
648   EXPECT_TRUE(content::ExecuteScript(frame, "location.reload()"));
649   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
650
651   // Verify that the full url of the iframe was used as referrer.
652   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
653       frame,
654       "window.domAutomationController.send(document.title)",
655       &title));
656   EXPECT_EQ(
657       "Referrer is " + embedded_test_server()
658                            ->GetURL("/referrer_policy/referrer-policy-log.html")
659                            .spec(),
660       title);
661 }
662
663 // Origin When Cross-Origin
664
665 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
666                        HttpLeftClickHTTPSRedirectToHTTPOriginWhenCrossOrigin) {
667   RunReferrerTest(
668       network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, START_ON_HTTPS,
669       REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
670       WindowOpenDisposition::CURRENT_TAB, blink::WebMouseEvent::Button::kLeft,
671       EXPECT_ORIGIN_AS_REFERRER);
672 }
673
674 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
675                        HttpLeftClickRedirectToHTTPSOriginWhenCrossOrigin) {
676   RunReferrerTest(
677       network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, START_ON_HTTP,
678       REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
679       WindowOpenDisposition::CURRENT_TAB, blink::WebMouseEvent::Button::kLeft,
680       EXPECT_ORIGIN_AS_REFERRER);
681 }
682
683 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
684                        HttpLeftClickRedirectToHTTPOriginWhenCrossOrigin) {
685   RunReferrerTest(network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin,
686                   START_ON_HTTP, REGULAR_LINK,
687                   SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
688                   WindowOpenDisposition::CURRENT_TAB,
689                   blink::WebMouseEvent::Button::kLeft, EXPECT_FULL_REFERRER);
690 }
691
692 // Same origin
693
694 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
695                        HttpLeftClickHTTPRedirectToHTTPSameOrigin) {
696   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTP,
697                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
698                   WindowOpenDisposition::CURRENT_TAB,
699                   blink::WebMouseEvent::Button::kLeft, EXPECT_FULL_REFERRER);
700 }
701
702 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
703                        HttpLeftClickHTTPRedirectToHTTPSSameOrigin) {
704   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTPS,
705                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
706                   WindowOpenDisposition::CURRENT_TAB,
707                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
708 }
709
710 // Strict origin
711
712 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
713                        HttpLeftClickHTTPRedirectToHTTPStrictOrigin) {
714   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTP,
715                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
716                   WindowOpenDisposition::CURRENT_TAB,
717                   blink::WebMouseEvent::Button::kLeft,
718                   EXPECT_ORIGIN_AS_REFERRER);
719 }
720
721 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
722                        HttpLeftClickHTTPSRedirectToHTTPStrictOrigin) {
723   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTPS,
724                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
725                   WindowOpenDisposition::CURRENT_TAB,
726                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
727 }
728
729 // Parameters for testing functionality imposing ad-hoc restrictions
730 // on the behavior of referrers, for instance absolute caps like
731 // "never send referrers" (as of writing, features::kNoReferrers)
732 // or "on cross-origin requests, never send more than the initiator's
733 // origin" (features::kCapReferrerToOriginOnCrossOrigin).
734 //
735 // These tests assume a default policy of no-referrer-when-downgrade.
736 struct ReferrerOverrideParams {
737   base::Optional<base::Feature> feature_to_enable;
738   // If true, calls content::Referrer::SetForceLegacyDefaultReferrerPolicy()
739   // to pin the default policy to no-referrer-when-downgrade.
740   bool force_no_referrer_when_downgrade_default;
741   network::mojom::ReferrerPolicy baseline_policy;
742   network::mojom::ReferrerPolicy expected_policy;
743
744   ReferrerPolicyTest::ExpectedReferrer same_origin_nav,  // HTTP -> HTTP
745       cross_origin_nav,                                  // HTTP -> HTTP
746       cross_origin_downgrade_nav,  // HTTPS -> HTTP, cross-origin
747       same_origin_to_cross_origin_redirect,
748       cross_origin_to_same_origin_redirect, same_origin_subresource,
749       same_origin_to_cross_origin_subresource_redirect;
750 } kReferrerOverrideParams[] = {
751     {.feature_to_enable = features::kNoReferrers,
752      .force_no_referrer_when_downgrade_default = false,
753      .baseline_policy = network::mojom::ReferrerPolicy::kAlways,
754      // The renderer's "have we completely disabled referrers?"
755      // implementation resets requests' referrer policies to kNever when
756      // it excises their referrers.
757      .expected_policy = network::mojom::ReferrerPolicy::kNever,
758      .same_origin_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
759      .cross_origin_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
760      .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
761      .same_origin_to_cross_origin_redirect =
762          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
763      .cross_origin_to_same_origin_redirect =
764          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
765      .same_origin_subresource = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
766      .same_origin_to_cross_origin_subresource_redirect =
767          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER},
768     {
769         .feature_to_enable = net::features::kCapReferrerToOriginOnCrossOrigin,
770         .force_no_referrer_when_downgrade_default = false,
771         .baseline_policy = network::mojom::ReferrerPolicy::kAlways,
772         // Applying the cap doesn't change the "referrer policy"
773         // attribute of a request
774         .expected_policy = network::mojom::ReferrerPolicy::kAlways,
775         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
776         .cross_origin_nav = ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
777         .cross_origin_downgrade_nav =
778             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
779         .same_origin_to_cross_origin_redirect =
780             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
781         // Referrer policies get applied to whatever the current referrer is:
782         // in the case of a cross-origin -> same-origin redirect, we already
783         // will have truncated the referrer to the initiating origin
784         .cross_origin_to_same_origin_redirect =
785             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
786         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
787         .same_origin_to_cross_origin_subresource_redirect =
788             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
789     },
790     {
791         .feature_to_enable = features::kReducedReferrerGranularity,
792         .force_no_referrer_when_downgrade_default = false,
793         .baseline_policy = network::mojom::ReferrerPolicy::kDefault,
794         // kDefault gets resolved into a concrete policy when making requests
795         .expected_policy =
796             network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
797         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
798         .cross_origin_nav = ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
799         .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
800         .same_origin_to_cross_origin_redirect =
801             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
802         .cross_origin_to_same_origin_redirect =
803             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
804         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
805         .same_origin_to_cross_origin_subresource_redirect =
806             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
807     },
808     {
809         .feature_to_enable = features::kReducedReferrerGranularity,
810         .force_no_referrer_when_downgrade_default = true,
811         .baseline_policy = network::mojom::ReferrerPolicy::kDefault,
812         // kDefault gets resolved into a concrete policy when making requests
813         .expected_policy =
814             network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade,
815         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
816         .cross_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
817         .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
818         .same_origin_to_cross_origin_redirect =
819             ReferrerPolicyTest::EXPECT_FULL_REFERRER,
820         .cross_origin_to_same_origin_redirect =
821             ReferrerPolicyTest::EXPECT_FULL_REFERRER,
822         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
823         .same_origin_to_cross_origin_subresource_redirect =
824             ReferrerPolicyTest::EXPECT_FULL_REFERRER,
825     }};
826
827 class ReferrerOverrideTest
828     : public ReferrerPolicyTest,
829       public ::testing::WithParamInterface<ReferrerOverrideParams> {
830  public:
831   ReferrerOverrideTest() {
832     if (GetParam().feature_to_enable)
833       scoped_feature_list_.InitAndEnableFeature(*GetParam().feature_to_enable);
834     content::Referrer::SetForceLegacyDefaultReferrerPolicy(
835         GetParam().force_no_referrer_when_downgrade_default);
836   }
837
838  protected:
839   // Test that the correct referrer is sent along with
840   // a subresource request.
841   // Parameter semantics are the same as for
842   // ReferrerPolicyTest::RunReferrerTest.
843   void RunSubresourceTest(StartOnProtocol start_protocol,
844                           RedirectType redirect,
845                           network::mojom::ReferrerPolicy baseline_policy,
846                           ExpectedReferrer expectation) {
847     GURL image_url;
848     switch (redirect) {
849       case NO_REDIRECT:
850         image_url = embedded_test_server()->GetURL("/referrer_policy/logo.gif");
851         break;
852       case HTTPS_NO_REDIRECT:
853         image_url = https_server_.GetURL("/referrer_policy/logo.gif");
854         break;
855       case SERVER_REDIRECT_FROM_HTTPS_TO_HTTP:
856         image_url = https_server_.GetURL(
857             std::string("/server-redirect?") +
858             embedded_test_server()->GetURL("/referrer_policy/logo.gif").spec());
859         break;
860       case SERVER_REDIRECT_FROM_HTTP_TO_HTTP:
861         image_url = embedded_test_server()->GetURL(
862             std::string("/server-redirect?") +
863             embedded_test_server()->GetURL("/referrer_policy/logo.gif").spec());
864         break;
865       case SERVER_REDIRECT_FROM_HTTP_TO_HTTPS:
866         image_url = embedded_test_server()->GetURL(
867             std::string("/server-redirect?") +
868             https_server_.GetURL("/referrer_policy/logo.gif").spec());
869         break;
870     }
871
872     std::string relative_url =
873         std::string("/referrer_policy/referrer-policy-subresource.html?") +
874         "policy=" + content::ReferrerPolicyToString(baseline_policy) +
875         "&redirect=" + image_url.spec();
876
877     auto* start_server = start_protocol == START_ON_HTTPS
878                              ? &https_server_
879                              : embedded_test_server();
880     const GURL start_url = start_server->GetURL(relative_url);
881
882     content::WebContents* tab =
883         browser()->tab_strip_model()->GetActiveWebContents();
884
885     base::ReleasableAutoLock lock(&check_on_requests_lock_);
886     check_on_requests_ = RequestCheck{"", "/referrer_policy/logo.gif"};
887     switch (expectation) {
888       case ReferrerPolicyTest::EXPECT_EMPTY_REFERRER:
889         check_on_requests_->expected_spec = "";
890         break;
891       case ReferrerPolicyTest::EXPECT_FULL_REFERRER:
892         check_on_requests_->expected_spec = start_url.spec();
893         break;
894       case ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER:
895         check_on_requests_->expected_spec = start_url.GetWithEmptyPath().spec();
896         break;
897     }
898     lock.Release();
899
900     // set by referrer-policy-subresource.html JS after the embedded image loads
901     base::string16 expected_title(base::ASCIIToUTF16("loaded"));
902     std::unique_ptr<content::TitleWatcher> title_watcher(
903         new content::TitleWatcher(tab, expected_title));
904     ui_test_utils::NavigateToURL(browser(), start_url);
905
906     // Wait for the page to load; during the load, since check_on_requests_ is
907     // nonempty, OnServerIncomingRequest will validate the referrers.
908     EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
909   }
910
911  private:
912   base::test::ScopedFeatureList scoped_feature_list_;
913 };
914
915 INSTANTIATE_TEST_SUITE_P(
916     WithOverrideParams,
917     ReferrerOverrideTest,
918     ::testing::ValuesIn(kReferrerOverrideParams),
919     [](const ::testing::TestParamInfo<ReferrerOverrideParams>& info)
920         -> std::string {
921       if (info.param.feature_to_enable)
922         return base::StringPrintf(
923             "Param%s_ForceLegacyPolicy%s", info.param.feature_to_enable->name,
924             info.param.force_no_referrer_when_downgrade_default ? "True"
925                                                                 : "False");
926       return "NoFeature";
927     });
928
929 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, SameOriginNavigation) {
930   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
931                   NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
932                   blink::WebMouseEvent::Button::kNoButton,
933                   GetParam().same_origin_nav, GetParam().expected_policy);
934 }
935
936 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginNavigation) {
937   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
938                   HTTPS_NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
939                   blink::WebMouseEvent::Button::kNoButton,
940                   GetParam().cross_origin_nav, GetParam().expected_policy);
941 }
942
943 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest,
944                        CrossOriginNavigationBrowserInitiated) {
945   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
946                   HTTPS_NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
947                   blink::WebMouseEvent::Button::kLeft,
948                   GetParam().cross_origin_nav, GetParam().expected_policy,
949                   BROWSER_INITIATED);
950 }
951
952 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginDowngradeNavigation) {
953   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTPS, REGULAR_LINK,
954                   NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
955                   blink::WebMouseEvent::Button::kNoButton,
956                   GetParam().cross_origin_downgrade_nav,
957                   GetParam().expected_policy);
958 }
959
960 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginRedirect) {
961   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
962                   SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
963                   WindowOpenDisposition::CURRENT_TAB,
964                   blink::WebMouseEvent::Button::kNoButton,
965                   GetParam().same_origin_to_cross_origin_redirect,
966                   GetParam().expected_policy);
967 }
968
969 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginToSameOriginRedirect) {
970   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
971                   SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
972                   WindowOpenDisposition::CURRENT_TAB,
973                   blink::WebMouseEvent::Button::kNoButton,
974                   GetParam().cross_origin_to_same_origin_redirect,
975                   GetParam().expected_policy);
976 }
977
978 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, SameOriginSubresource) {
979   RunSubresourceTest(START_ON_HTTP, NO_REDIRECT, GetParam().baseline_policy,
980                      GetParam().same_origin_subresource);
981 }
982
983 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest,
984                        SameOriginToCrossOriginSubresourceRedirect) {
985   RunSubresourceTest(
986       START_ON_HTTP, SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
987       GetParam().baseline_policy,
988       GetParam().same_origin_to_cross_origin_subresource_redirect);
989 }
990
991 // Most of the functionality of the referrer-cap flag is covered by
992 // ReferrerOverrideTest; these couple additional tests test the flag's
993 // interaction with other referrer policies
994 class ReferrerPolicyCapReferrerToOriginOnCrossOriginTest
995     : public ReferrerPolicyTest {
996  public:
997   ReferrerPolicyCapReferrerToOriginOnCrossOriginTest() {
998     scoped_feature_list_.InitAndEnableFeature(
999         net::features::kCapReferrerToOriginOnCrossOrigin);
1000   }
1001
1002  private:
1003   base::test::ScopedFeatureList scoped_feature_list_;
1004 };
1005
1006 // Test that capping referrer granularity at origin on cross-origin requests
1007 // correctly defers to a more restrictive referrer policy on a
1008 // cross-origin navigation.
1009 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1010                        HonorsMoreRestrictivePolicyOnNavigation) {
1011   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTPS,
1012                   REGULAR_LINK, NO_REDIRECT /*direct navigation x-origin*/,
1013                   WindowOpenDisposition::CURRENT_TAB,
1014                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
1015 }
1016
1017 // Test that capping referrer granularity at origin on cross-origin requests
1018 // correctly defers to a more restrictive referrer policy on a
1019 // cross-origin redirect.
1020 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1021                        HonorsMoreRestrictivePolicyOnRedirect) {
1022   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTPS,
1023                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
1024                   WindowOpenDisposition::CURRENT_TAB,
1025                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
1026 }
1027
1028 // Test that, when the cross-origin referrer cap is on but we also have the
1029 // "no referrers at all" pref set, we send no referrer at all on cross-origin
1030 // requests.
1031 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1032                        RespectsNoReferrerPref) {
1033   browser()->profile()->GetPrefs()->SetBoolean(prefs::kEnableReferrers, false);
1034   content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
1035       ->FlushNetworkInterfaceForTesting();
1036   RunReferrerTest(network::mojom::ReferrerPolicy::kAlways, START_ON_HTTPS,
1037                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
1038                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER,
1039                   // when the pref is set, the renderer sets the referrer policy
1040                   // to the kNever on outgoing requests at the same time
1041                   // it removes referrers
1042                   network::mojom::ReferrerPolicy::kNever);
1043 }