• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ReferrerPolicyTest()46    ReferrerPolicyTest() {}
~ReferrerPolicyTest()47    virtual ~ReferrerPolicyTest() {}
48 
SetUp()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.
GetExpectedTitle(const GURL & url,ExpectedReferrer expected_referrer)73   base::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.
AddAllPossibleTitles(const GURL & url,content::TitleWatcher * title_watcher)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.
RunReferrerTest(const std::string referrer_policy,bool start_on_https,bool target_blank,bool redirect,bool opens_new_tab,blink::WebMouseEvent::Button button,ExpectedReferrer expected_referrer)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                        blink::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 == blink::WebMouseEvent::ButtonNone ? "false" : "true") +
138         "&target=" + (target_blank ? "_blank" : ""));
139 
140     ui_test_utils::WindowedTabAddedNotificationObserver tab_added_observer(
141         content::NotificationService::AllSources());
142 
143     base::string16 expected_title =
144         GetExpectedTitle(start_url, expected_referrer);
145     content::WebContents* tab =
146         browser()->tab_strip_model()->GetActiveWebContents();
147     content::TitleWatcher title_watcher(tab, expected_title);
148 
149     // Watch for all possible outcomes to avoid timeouts if something breaks.
150     AddAllPossibleTitles(start_url, &title_watcher);
151 
152     ui_test_utils::NavigateToURL(browser(), start_url);
153 
154     if (button != blink::WebMouseEvent::ButtonNone) {
155       blink::WebMouseEvent mouse_event;
156       mouse_event.type = blink::WebInputEvent::MouseDown;
157       mouse_event.button = button;
158       mouse_event.x = 15;
159       mouse_event.y = 15;
160       mouse_event.clickCount = 1;
161       tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
162       mouse_event.type = blink::WebInputEvent::MouseUp;
163       tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
164     }
165 
166     if (opens_new_tab) {
167       tab_added_observer.Wait();
168       tab = tab_added_observer.GetTab();
169       EXPECT_TRUE(tab);
170       content::WaitForLoadStop(tab);
171       EXPECT_EQ(expected_title, tab->GetTitle());
172     } else {
173       EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
174     }
175 
176     return start_url;
177   }
178 
179   scoped_ptr<net::SpawnedTestServer> test_server_;
180   scoped_ptr<net::SpawnedTestServer> ssl_test_server_;
181 };
182 
183 // The basic behavior of referrer policies is covered by layout tests in
184 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
185 // code paths chrome uses to navigate. To keep the number of combinations down,
186 // we only test the "origin" policy here.
187 //
188 // Some tests are marked as FAILS, see http://crbug.com/124750
189 
190 // Content initiated navigation, from HTTP to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,Origin)191 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Origin) {
192   RunReferrerTest("origin", false, false, false, false,
193                   blink::WebMouseEvent::ButtonNone,
194                   EXPECT_ORIGIN_AS_REFERRER);
195 }
196 
197 // Content initiated navigation, from HTTPS to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsDefault)198 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsDefault) {
199   RunReferrerTest("origin", true, false, false, false,
200                   blink::WebMouseEvent::ButtonNone,
201                   EXPECT_ORIGIN_AS_REFERRER);
202 }
203 
204 // User initiated navigation, from HTTP to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,LeftClickOrigin)205 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickOrigin) {
206   RunReferrerTest("origin", false, false, false, false,
207                   blink::WebMouseEvent::ButtonLeft,
208                   EXPECT_ORIGIN_AS_REFERRER);
209 }
210 
211 // User initiated navigation, from HTTPS to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsLeftClickOrigin)212 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickOrigin) {
213   RunReferrerTest("origin", true, false, false, false,
214                   blink::WebMouseEvent::ButtonLeft,
215                   EXPECT_ORIGIN_AS_REFERRER);
216 }
217 
218 // User initiated navigation, middle click, from HTTP to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MiddleClickOrigin)219 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickOrigin) {
220   RunReferrerTest("origin", false, false, false, true,
221                   blink::WebMouseEvent::ButtonMiddle,
222                   EXPECT_ORIGIN_AS_REFERRER);
223 }
224 
225 // User initiated navigation, middle click, from HTTPS to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsMiddleClickOrigin)226 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickOrigin) {
227   RunReferrerTest("origin", true, false, false, true,
228                   blink::WebMouseEvent::ButtonMiddle,
229                   EXPECT_ORIGIN_AS_REFERRER);
230 }
231 
232 // User initiated navigation, target blank, from HTTP to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,TargetBlankOrigin)233 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankOrigin) {
234   RunReferrerTest("origin", false, true, false, true,
235                   blink::WebMouseEvent::ButtonLeft,
236                   EXPECT_ORIGIN_AS_REFERRER);
237 }
238 
239 // User initiated navigation, target blank, from HTTPS to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsTargetBlankOrigin)240 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankOrigin) {
241   RunReferrerTest("origin", true, true, false, true,
242                   blink::WebMouseEvent::ButtonLeft,
243                   EXPECT_ORIGIN_AS_REFERRER);
244 }
245 
246 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MiddleClickTargetBlankOrigin)247 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankOrigin) {
248   RunReferrerTest("origin", false, true, false, true,
249                   blink::WebMouseEvent::ButtonMiddle,
250                   EXPECT_ORIGIN_AS_REFERRER);
251 }
252 
253 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsMiddleClickTargetBlankOrigin)254 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickTargetBlankOrigin) {
255   RunReferrerTest("origin", true, true, false, true,
256                   blink::WebMouseEvent::ButtonMiddle,
257                   EXPECT_ORIGIN_AS_REFERRER);
258 }
259 
260 // Context menu, from HTTP to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MAYBE_ContextMenuOrigin)261 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuOrigin) {
262   ContextMenuNotificationObserver context_menu_observer(
263       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
264   RunReferrerTest("origin", false, false, false, true,
265                   blink::WebMouseEvent::ButtonRight,
266                   EXPECT_ORIGIN_AS_REFERRER);
267 }
268 
269 // Context menu, from HTTPS to HTTP.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MAYBE_HttpsContextMenuOrigin)270 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuOrigin) {
271   ContextMenuNotificationObserver context_menu_observer(
272       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
273   RunReferrerTest("origin", true, false, false, true,
274                   blink::WebMouseEvent::ButtonRight,
275                   EXPECT_ORIGIN_AS_REFERRER);
276 }
277 
278 // Content initiated navigation, from HTTP to HTTP via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,Redirect)279 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Redirect) {
280   RunReferrerTest("origin", false, false, true, false,
281                   blink::WebMouseEvent::ButtonNone,
282                   EXPECT_ORIGIN_AS_REFERRER);
283 }
284 
285 // Content initiated navigation, from HTTPS to HTTP via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsRedirect)286 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsRedirect) {
287   RunReferrerTest("origin", true, false, true, false,
288                   blink::WebMouseEvent::ButtonNone,
289                   EXPECT_ORIGIN_AS_REFERRER);
290 }
291 
292 // User initiated navigation, from HTTP to HTTP via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,LeftClickRedirect)293 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickRedirect) {
294   RunReferrerTest("origin", false, false, true, false,
295                   blink::WebMouseEvent::ButtonLeft,
296                   EXPECT_ORIGIN_AS_REFERRER);
297 }
298 
299 // User initiated navigation, from HTTPS to HTTP via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsLeftClickRedirect)300 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickRedirect) {
301   RunReferrerTest("origin", true, false, true, false,
302                   blink::WebMouseEvent::ButtonLeft,
303                   EXPECT_ORIGIN_AS_REFERRER);
304 }
305 
306 // User initiated navigation, middle click, from HTTP to HTTP via server
307 // redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MiddleClickRedirect)308 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickRedirect) {
309   RunReferrerTest("origin", false, false, true, true,
310                   blink::WebMouseEvent::ButtonMiddle,
311                   EXPECT_ORIGIN_AS_REFERRER);
312 }
313 
314 // User initiated navigation, middle click, from HTTPS to HTTP via server
315 // redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsMiddleClickRedirect)316 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickRedirect) {
317   RunReferrerTest("origin", true, false, true, true,
318                   blink::WebMouseEvent::ButtonMiddle,
319                   EXPECT_ORIGIN_AS_REFERRER);
320 }
321 
322 // User initiated navigation, target blank, from HTTP to HTTP via server
323 // redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,TargetBlankRedirect)324 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankRedirect) {
325   RunReferrerTest("origin", false, true, true, true,
326                   blink::WebMouseEvent::ButtonLeft,
327                   EXPECT_ORIGIN_AS_REFERRER);
328 }
329 
330 // User initiated navigation, target blank, from HTTPS to HTTP via server
331 // redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsTargetBlankRedirect)332 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankRedirect) {
333   RunReferrerTest("origin", true, true, true, true,
334                   blink::WebMouseEvent::ButtonLeft,
335                   EXPECT_ORIGIN_AS_REFERRER);
336 }
337 
338 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
339 // server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MiddleClickTargetBlankRedirect)340 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankRedirect) {
341   RunReferrerTest("origin", false, true, true, true,
342                   blink::WebMouseEvent::ButtonMiddle,
343                   EXPECT_ORIGIN_AS_REFERRER);
344 }
345 
346 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
347 // via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,HttpsMiddleClickTargetBlankRedirect)348 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
349                        HttpsMiddleClickTargetBlankRedirect) {
350   RunReferrerTest("origin", true, true, true, true,
351                   blink::WebMouseEvent::ButtonMiddle,
352                   EXPECT_ORIGIN_AS_REFERRER);
353 }
354 
355 // Context menu, from HTTP to HTTP via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MAYBE_ContextMenuRedirect)356 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuRedirect) {
357   ContextMenuNotificationObserver context_menu_observer(
358       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
359   RunReferrerTest("origin", false, false, true, true,
360                   blink::WebMouseEvent::ButtonRight,
361                   EXPECT_ORIGIN_AS_REFERRER);
362 }
363 
364 // Context menu, from HTTPS to HTTP via server redirect.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,MAYBE_HttpsContextMenuRedirect)365 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuRedirect) {
366   ContextMenuNotificationObserver context_menu_observer(
367       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
368   RunReferrerTest("origin", true, false, true, true,
369                   blink::WebMouseEvent::ButtonRight,
370                   EXPECT_ORIGIN_AS_REFERRER);
371 }
372 
373 // Tests history navigation actions: Navigate from A to B with a referrer
374 // policy, then navigate to C, back to B, and reload.
IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,History)375 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, History) {
376   // Navigate from A to B.
377   GURL start_url = RunReferrerTest("origin", true, false, true, false,
378                                    blink::WebMouseEvent::ButtonLeft,
379                                    EXPECT_ORIGIN_AS_REFERRER);
380 
381   // Navigate to C.
382   ui_test_utils::NavigateToURL(browser(), test_server_->GetURL(std::string()));
383 
384   base::string16 expected_title =
385       GetExpectedTitle(start_url, EXPECT_ORIGIN_AS_REFERRER);
386   content::WebContents* tab =
387       browser()->tab_strip_model()->GetActiveWebContents();
388   scoped_ptr<content::TitleWatcher> title_watcher(
389       new content::TitleWatcher(tab, expected_title));
390 
391   // Watch for all possible outcomes to avoid timeouts if something breaks.
392   AddAllPossibleTitles(start_url, title_watcher.get());
393 
394   // Go back to B.
395   chrome::GoBack(browser(), CURRENT_TAB);
396   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
397 
398   title_watcher.reset(new content::TitleWatcher(tab, expected_title));
399   AddAllPossibleTitles(start_url, title_watcher.get());
400 
401   // Reload to B.
402   chrome::Reload(browser(), CURRENT_TAB);
403   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
404 
405   title_watcher.reset(new content::TitleWatcher(tab, expected_title));
406   AddAllPossibleTitles(start_url, title_watcher.get());
407 
408   // Shift-reload to B.
409   chrome::ReloadIgnoringCache(browser(), CURRENT_TAB);
410   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
411 }
412