| 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 |