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 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 | |
716 // Builds the expected upgraded URL. | |
717 GURL::Replacements replace_scheme; | |
718 replace_scheme.SetSchemeStr("https"); | |
719 replace_scheme.SetPortStr(""); | |
720 GURL cross_site_iframe_secure_url = embedded_test_server() | |
721 ->GetURL("other.com", "/title1.html") | |
722 .ReplaceComponents(replace_scheme); | |
723 ASSERT_FALSE(cross_site_iframe_secure_url.has_port()); | |
Mike West
2016/07/06 06:55:35
Nit: If this is necessary to make the test pass, p
carlosk
2016/07/06 08:46:21
I was wrong to place the blame in the upgrade code
| |
724 | |
725 CheckHttpsUpgradedIframeNavigation(start_url, cross_site_iframe_secure_url); | |
726 } | |
727 | |
635 } // namespace content | 728 } // namespace content |
OLD | NEW |