OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/frame_host/navigation_handle_impl.h" | 5 #include "content/browser/frame_host/navigation_handle_impl.h" |
6 #include "content/browser/web_contents/web_contents_impl.h" | 6 #include "content/browser/web_contents/web_contents_impl.h" |
7 #include "content/public/browser/web_contents.h" | 7 #include "content/public/browser/web_contents.h" |
8 #include "content/public/browser/web_contents_observer.h" | 8 #include "content/public/browser/web_contents_observer.h" |
9 #include "content/public/test/browser_test_utils.h" | 9 #include "content/public/test/browser_test_utils.h" |
10 #include "content/public/test/content_browser_test.h" | 10 #include "content/public/test/content_browser_test.h" |
11 #include "content/public/test/content_browser_test_utils.h" | 11 #include "content/public/test/content_browser_test_utils.h" |
12 #include "content/public/test/test_navigation_observer.h" | 12 #include "content/public/test/test_navigation_observer.h" |
13 #include "content/public/test/test_utils.h" | 13 #include "content/public/test/test_utils.h" |
14 #include "content/shell/browser/shell.h" | 14 #include "content/shell/browser/shell.h" |
15 #include "content/test/content_browser_test_utils_internal.h" | 15 #include "content/test/content_browser_test_utils_internal.h" |
16 #include "net/dns/mock_host_resolver.h" | 16 #include "net/dns/mock_host_resolver.h" |
17 #include "ui/base/page_transition_types.h" | 17 #include "ui/base/page_transition_types.h" |
18 #include "url/url_constants.h" | 18 #include "url/url_constants.h" |
19 | 19 |
20 namespace content { | 20 namespace content { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
| 24 // Gathers data from the NavigationHandle assigned to navigations that start |
| 25 // with the expected URL. |
24 class NavigationHandleObserver : public WebContentsObserver { | 26 class NavigationHandleObserver : public WebContentsObserver { |
25 public: | 27 public: |
26 NavigationHandleObserver(WebContents* web_contents, const GURL& expected_url) | 28 NavigationHandleObserver(WebContents* web_contents, |
| 29 const GURL& expected_start_url) |
27 : WebContentsObserver(web_contents), | 30 : WebContentsObserver(web_contents), |
28 handle_(nullptr), | 31 handle_(nullptr), |
29 has_committed_(false), | 32 has_committed_(false), |
30 is_error_(false), | 33 is_error_(false), |
31 is_main_frame_(false), | 34 is_main_frame_(false), |
32 is_parent_main_frame_(false), | 35 is_parent_main_frame_(false), |
33 is_renderer_initiated_(true), | 36 is_renderer_initiated_(true), |
34 is_synchronous_(false), | 37 is_synchronous_(false), |
35 is_srcdoc_(false), | 38 is_srcdoc_(false), |
36 was_redirected_(false), | 39 was_redirected_(false), |
37 frame_tree_node_id_(-1), | 40 frame_tree_node_id_(-1), |
38 page_transition_(ui::PAGE_TRANSITION_LINK), | 41 page_transition_(ui::PAGE_TRANSITION_LINK), |
39 expected_url_(expected_url) {} | 42 expected_start_url_(expected_start_url) {} |
40 | 43 |
41 void DidStartNavigation(NavigationHandle* navigation_handle) override { | 44 void DidStartNavigation(NavigationHandle* navigation_handle) override { |
42 if (handle_ || navigation_handle->GetURL() != expected_url_) | 45 if (handle_ || navigation_handle->GetURL() != expected_start_url_) |
43 return; | 46 return; |
44 | 47 |
45 handle_ = navigation_handle; | 48 handle_ = navigation_handle; |
46 has_committed_ = false; | 49 has_committed_ = false; |
47 is_error_ = false; | 50 is_error_ = false; |
48 page_transition_ = ui::PAGE_TRANSITION_LINK; | 51 page_transition_ = ui::PAGE_TRANSITION_LINK; |
49 last_committed_url_ = GURL(); | 52 last_committed_url_ = GURL(); |
50 | 53 |
51 is_main_frame_ = navigation_handle->IsInMainFrame(); | 54 is_main_frame_ = navigation_handle->IsInMainFrame(); |
52 is_parent_main_frame_ = navigation_handle->IsParentMainFrame(); | 55 is_parent_main_frame_ = navigation_handle->IsParentMainFrame(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 bool has_committed_; | 111 bool has_committed_; |
109 bool is_error_; | 112 bool is_error_; |
110 bool is_main_frame_; | 113 bool is_main_frame_; |
111 bool is_parent_main_frame_; | 114 bool is_parent_main_frame_; |
112 bool is_renderer_initiated_; | 115 bool is_renderer_initiated_; |
113 bool is_synchronous_; | 116 bool is_synchronous_; |
114 bool is_srcdoc_; | 117 bool is_srcdoc_; |
115 bool was_redirected_; | 118 bool was_redirected_; |
116 int frame_tree_node_id_; | 119 int frame_tree_node_id_; |
117 ui::PageTransition page_transition_; | 120 ui::PageTransition page_transition_; |
118 GURL expected_url_; | 121 GURL expected_start_url_; |
119 GURL last_committed_url_; | 122 GURL last_committed_url_; |
120 }; | 123 }; |
121 | 124 |
122 // A test NavigationThrottle that will return pre-determined checks and run | 125 // A test NavigationThrottle that will return pre-determined checks and run |
123 // callbacks when the various NavigationThrottle methods are called. | 126 // callbacks when the various NavigationThrottle methods are called. It is |
| 127 // not instantiated directly but through a TestNavigationThrottleInstaller. |
124 class TestNavigationThrottle : public NavigationThrottle { | 128 class TestNavigationThrottle : public NavigationThrottle { |
125 public: | 129 public: |
126 TestNavigationThrottle( | 130 TestNavigationThrottle( |
127 NavigationHandle* handle, | 131 NavigationHandle* handle, |
128 NavigationThrottle::ThrottleCheckResult will_start_result, | 132 NavigationThrottle::ThrottleCheckResult will_start_result, |
129 NavigationThrottle::ThrottleCheckResult will_redirect_result, | 133 NavigationThrottle::ThrottleCheckResult will_redirect_result, |
130 NavigationThrottle::ThrottleCheckResult will_process_result, | 134 NavigationThrottle::ThrottleCheckResult will_process_result, |
131 base::Closure did_call_will_start, | 135 base::Closure did_call_will_start, |
132 base::Closure did_call_will_redirect, | 136 base::Closure did_call_will_redirect, |
133 base::Closure did_call_will_process) | 137 base::Closure did_call_will_process) |
(...skipping 28 matching lines...) Expand all Loading... |
162 } | 166 } |
163 | 167 |
164 NavigationThrottle::ThrottleCheckResult will_start_result_; | 168 NavigationThrottle::ThrottleCheckResult will_start_result_; |
165 NavigationThrottle::ThrottleCheckResult will_redirect_result_; | 169 NavigationThrottle::ThrottleCheckResult will_redirect_result_; |
166 NavigationThrottle::ThrottleCheckResult will_process_result_; | 170 NavigationThrottle::ThrottleCheckResult will_process_result_; |
167 base::Closure did_call_will_start_; | 171 base::Closure did_call_will_start_; |
168 base::Closure did_call_will_redirect_; | 172 base::Closure did_call_will_redirect_; |
169 base::Closure did_call_will_process_; | 173 base::Closure did_call_will_process_; |
170 }; | 174 }; |
171 | 175 |
172 // Install a TestNavigationThrottle on all requests and allows waiting for | 176 // Install a TestNavigationThrottle on all following requests and allows waiting |
173 // various NavigationThrottle related events. | 177 // for various NavigationThrottle related events. Waiting works only for the |
| 178 // immediately next navigation. New instances are needed to wait for further |
| 179 // navigations. |
174 class TestNavigationThrottleInstaller : public WebContentsObserver { | 180 class TestNavigationThrottleInstaller : public WebContentsObserver { |
175 public: | 181 public: |
176 TestNavigationThrottleInstaller( | 182 TestNavigationThrottleInstaller( |
177 WebContents* web_contents, | 183 WebContents* web_contents, |
178 NavigationThrottle::ThrottleCheckResult will_start_result, | 184 NavigationThrottle::ThrottleCheckResult will_start_result, |
179 NavigationThrottle::ThrottleCheckResult will_redirect_result, | 185 NavigationThrottle::ThrottleCheckResult will_redirect_result, |
180 NavigationThrottle::ThrottleCheckResult will_process_result) | 186 NavigationThrottle::ThrottleCheckResult will_process_result) |
181 : WebContentsObserver(web_contents), | 187 : WebContentsObserver(web_contents), |
182 will_start_result_(will_start_result), | 188 will_start_result_(will_start_result), |
183 will_redirect_result_(will_redirect_result), | 189 will_redirect_result_(will_redirect_result), |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 NavigationThrottle::ThrottleCheckResult will_process_result_; | 269 NavigationThrottle::ThrottleCheckResult will_process_result_; |
264 int will_start_called_; | 270 int will_start_called_; |
265 int will_redirect_called_; | 271 int will_redirect_called_; |
266 int will_process_called_; | 272 int will_process_called_; |
267 TestNavigationThrottle* navigation_throttle_; | 273 TestNavigationThrottle* navigation_throttle_; |
268 scoped_refptr<MessageLoopRunner> will_start_loop_runner_; | 274 scoped_refptr<MessageLoopRunner> will_start_loop_runner_; |
269 scoped_refptr<MessageLoopRunner> will_redirect_loop_runner_; | 275 scoped_refptr<MessageLoopRunner> will_redirect_loop_runner_; |
270 scoped_refptr<MessageLoopRunner> will_process_loop_runner_; | 276 scoped_refptr<MessageLoopRunner> will_process_loop_runner_; |
271 }; | 277 }; |
272 | 278 |
| 279 // Records all navigation start URLs from the WebContents. |
| 280 class NavigationStartUrlRecorder : public WebContentsObserver { |
| 281 public: |
| 282 NavigationStartUrlRecorder(WebContents* web_contents) |
| 283 : WebContentsObserver(web_contents) {} |
| 284 |
| 285 void DidStartNavigation(NavigationHandle* navigation_handle) override { |
| 286 urls_.push_back(navigation_handle->GetURL()); |
| 287 } |
| 288 |
| 289 const std::vector<GURL>& urls() const { return urls_; } |
| 290 |
| 291 private: |
| 292 std::vector<GURL> urls_; |
| 293 }; |
| 294 |
273 } // namespace | 295 } // namespace |
274 | 296 |
275 class NavigationHandleImplBrowserTest : public ContentBrowserTest { | 297 class NavigationHandleImplBrowserTest : public ContentBrowserTest { |
276 protected: | 298 protected: |
277 void SetUpOnMainThread() override { | 299 void SetUpOnMainThread() override { |
278 host_resolver()->AddRule("*", "127.0.0.1"); | 300 host_resolver()->AddRule("*", "127.0.0.1"); |
279 ASSERT_TRUE(embedded_test_server()->Start()); | 301 ASSERT_TRUE(embedded_test_server()->Start()); |
280 SetupCrossSiteRedirector(embedded_test_server()); | 302 SetupCrossSiteRedirector(embedded_test_server()); |
281 } | 303 } |
282 }; | 304 }; |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 // Wait for the end of the navigation. | 647 // Wait for the end of the navigation. |
626 navigation_observer.Wait(); | 648 navigation_observer.Wait(); |
627 | 649 |
628 EXPECT_TRUE(observer.has_committed()); | 650 EXPECT_TRUE(observer.has_committed()); |
629 EXPECT_TRUE(observer.was_redirected()); | 651 EXPECT_TRUE(observer.was_redirected()); |
630 EXPECT_FALSE(observer.is_error()); | 652 EXPECT_FALSE(observer.is_error()); |
631 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), | 653 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), |
632 GURL(embedded_test_server()->GetURL("bar.com", "/title2.html"))); | 654 GURL(embedded_test_server()->GetURL("bar.com", "/title2.html"))); |
633 } | 655 } |
634 | 656 |
| 657 // Specialized test that verifies the NavigationHandle gets the HTTPS upgraded |
| 658 // URL from the very beginning of the navigation. |
| 659 class NavigationHandleImplHttpsUpgradeBrowserTest |
| 660 : public NavigationHandleImplBrowserTest { |
| 661 public: |
| 662 void CheckHttpsUpgradedIframeNavigation(const GURL& start_url, |
| 663 const GURL& iframe_secure_url) { |
| 664 ASSERT_TRUE(start_url.SchemeIs(url::kHttpScheme)); |
| 665 ASSERT_TRUE(iframe_secure_url.SchemeIs(url::kHttpsScheme)); |
| 666 |
| 667 NavigationStartUrlRecorder url_recorder(shell()->web_contents()); |
| 668 TestNavigationThrottleInstaller installer( |
| 669 shell()->web_contents(), NavigationThrottle::PROCEED, |
| 670 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); |
| 671 TestNavigationManager navigation_manager(shell()->web_contents(), |
| 672 iframe_secure_url); |
| 673 |
| 674 // Load the page and wait for the frame load with the expected URL. |
| 675 // Note: if the test times out while waiting then a navigation to |
| 676 // iframe_secure_url never happened and the expected upgrade may not be |
| 677 // working. |
| 678 shell()->LoadURL(start_url); |
| 679 navigation_manager.WaitForWillStartRequest(); |
| 680 |
| 681 // The main frame should have finished navigating while the iframe should |
| 682 // have just started. |
| 683 EXPECT_EQ(2, installer.will_start_called()); |
| 684 EXPECT_EQ(0, installer.will_redirect_called()); |
| 685 EXPECT_EQ(1, installer.will_process_called()); |
| 686 |
| 687 // Check the correct start URLs have been registered. |
| 688 EXPECT_EQ(iframe_secure_url, url_recorder.urls().back()); |
| 689 EXPECT_EQ(start_url, url_recorder.urls().front()); |
| 690 EXPECT_EQ(2ul, url_recorder.urls().size()); |
| 691 } |
| 692 }; |
| 693 |
| 694 // Tests that the start URL is HTTPS upgraded for a same site navigation. |
| 695 IN_PROC_BROWSER_TEST_F(NavigationHandleImplHttpsUpgradeBrowserTest, |
| 696 StartUrlIsHttpsUpgradedSameSite) { |
| 697 GURL start_url( |
| 698 embedded_test_server()->GetURL("/https_upgrade_same_site.html")); |
| 699 |
| 700 // Builds the expected upgraded same site URL. |
| 701 GURL::Replacements replace_scheme; |
| 702 replace_scheme.SetSchemeStr("https"); |
| 703 GURL cross_site_iframe_secure_url = embedded_test_server() |
| 704 ->GetURL("/title1.html") |
| 705 .ReplaceComponents(replace_scheme); |
| 706 |
| 707 CheckHttpsUpgradedIframeNavigation(start_url, cross_site_iframe_secure_url); |
| 708 } |
| 709 |
| 710 // Tests that the start URL is HTTPS upgraded for a cross site navigation. |
| 711 IN_PROC_BROWSER_TEST_F(NavigationHandleImplHttpsUpgradeBrowserTest, |
| 712 StartUrlIsHttpsUpgradedCrossSite) { |
| 713 GURL start_url( |
| 714 embedded_test_server()->GetURL("/https_upgrade_cross_site.html")); |
| 715 GURL cross_site_iframe_secure_url("https://other.com/title1.html"); |
| 716 |
| 717 CheckHttpsUpgradedIframeNavigation(start_url, cross_site_iframe_secure_url); |
| 718 } |
| 719 |
635 } // namespace content | 720 } // namespace content |
OLD | NEW |