| 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 "base/memory/weak_ptr.h" | 5 #include "base/memory/weak_ptr.h" |
| 6 #include "content/browser/frame_host/navigation_handle_impl.h" | 6 #include "content/browser/frame_host/navigation_handle_impl.h" |
| 7 #include "content/browser/web_contents/web_contents_impl.h" | 7 #include "content/browser/web_contents/web_contents_impl.h" |
| 8 #include "content/public/browser/web_contents.h" | 8 #include "content/public/browser/web_contents.h" |
| 9 #include "content/public/browser/web_contents_observer.h" | 9 #include "content/public/browser/web_contents_observer.h" |
| 10 #include "content/public/common/browser_side_navigation_policy.h" | 10 #include "content/public/common/browser_side_navigation_policy.h" |
| 11 #include "content/public/common/content_switches.h" | 11 #include "content/public/common/content_switches.h" |
| 12 #include "content/public/common/request_context_type.h" | 12 #include "content/public/common/request_context_type.h" |
| 13 #include "content/public/common/url_constants.h" |
| 13 #include "content/public/test/browser_test_utils.h" | 14 #include "content/public/test/browser_test_utils.h" |
| 14 #include "content/public/test/content_browser_test.h" | 15 #include "content/public/test/content_browser_test.h" |
| 15 #include "content/public/test/content_browser_test_utils.h" | 16 #include "content/public/test/content_browser_test_utils.h" |
| 17 #include "content/public/test/navigation_handle_observer.h" |
| 16 #include "content/public/test/test_navigation_observer.h" | 18 #include "content/public/test/test_navigation_observer.h" |
| 17 #include "content/public/test/test_utils.h" | 19 #include "content/public/test/test_utils.h" |
| 18 #include "content/shell/browser/shell.h" | 20 #include "content/shell/browser/shell.h" |
| 19 #include "content/test/content_browser_test_utils_internal.h" | 21 #include "content/test/content_browser_test_utils_internal.h" |
| 20 #include "net/dns/mock_host_resolver.h" | 22 #include "net/dns/mock_host_resolver.h" |
| 21 #include "net/test/url_request/url_request_failed_job.h" | 23 #include "net/test/url_request/url_request_failed_job.h" |
| 22 #include "ui/base/page_transition_types.h" | 24 #include "ui/base/page_transition_types.h" |
| 23 #include "url/url_constants.h" | 25 #include "url/url_constants.h" |
| 24 | 26 |
| 25 namespace content { | 27 namespace content { |
| 26 | 28 |
| 27 namespace { | 29 namespace { |
| 28 | 30 |
| 29 // Gathers data from the NavigationHandle assigned to navigations that start | |
| 30 // with the expected URL. | |
| 31 class NavigationHandleObserver : public WebContentsObserver { | |
| 32 public: | |
| 33 NavigationHandleObserver(WebContents* web_contents, | |
| 34 const GURL& expected_start_url) | |
| 35 : WebContentsObserver(web_contents), | |
| 36 page_transition_(ui::PAGE_TRANSITION_LINK), | |
| 37 expected_start_url_(expected_start_url) {} | |
| 38 | |
| 39 void DidStartNavigation(NavigationHandle* navigation_handle) override { | |
| 40 if (handle_ || navigation_handle->GetURL() != expected_start_url_) | |
| 41 return; | |
| 42 | |
| 43 handle_ = navigation_handle; | |
| 44 has_committed_ = false; | |
| 45 is_error_ = false; | |
| 46 page_transition_ = ui::PAGE_TRANSITION_LINK; | |
| 47 last_committed_url_ = GURL(); | |
| 48 | |
| 49 is_main_frame_ = navigation_handle->IsInMainFrame(); | |
| 50 is_parent_main_frame_ = navigation_handle->IsParentMainFrame(); | |
| 51 is_renderer_initiated_ = navigation_handle->IsRendererInitiated(); | |
| 52 is_same_document_ = navigation_handle->IsSameDocument(); | |
| 53 was_redirected_ = navigation_handle->WasServerRedirect(); | |
| 54 frame_tree_node_id_ = navigation_handle->GetFrameTreeNodeId(); | |
| 55 } | |
| 56 | |
| 57 void DidFinishNavigation(NavigationHandle* navigation_handle) override { | |
| 58 if (navigation_handle != handle_) | |
| 59 return; | |
| 60 | |
| 61 DCHECK_EQ(is_main_frame_, navigation_handle->IsInMainFrame()); | |
| 62 DCHECK_EQ(is_parent_main_frame_, navigation_handle->IsParentMainFrame()); | |
| 63 DCHECK_EQ(is_same_document_, navigation_handle->IsSameDocument()); | |
| 64 DCHECK_EQ(is_renderer_initiated_, navigation_handle->IsRendererInitiated()); | |
| 65 DCHECK_EQ(frame_tree_node_id_, navigation_handle->GetFrameTreeNodeId()); | |
| 66 | |
| 67 was_redirected_ = navigation_handle->WasServerRedirect(); | |
| 68 net_error_code_ = navigation_handle->GetNetErrorCode(); | |
| 69 | |
| 70 if (navigation_handle->HasCommitted()) { | |
| 71 has_committed_ = true; | |
| 72 if (!navigation_handle->IsErrorPage()) { | |
| 73 page_transition_ = navigation_handle->GetPageTransition(); | |
| 74 last_committed_url_ = navigation_handle->GetURL(); | |
| 75 } else { | |
| 76 is_error_ = true; | |
| 77 } | |
| 78 } else { | |
| 79 has_committed_ = false; | |
| 80 is_error_ = true; | |
| 81 } | |
| 82 | |
| 83 handle_ = nullptr; | |
| 84 } | |
| 85 | |
| 86 bool has_committed() { return has_committed_; } | |
| 87 bool is_error() { return is_error_; } | |
| 88 bool is_main_frame() { return is_main_frame_; } | |
| 89 bool is_parent_main_frame() { return is_parent_main_frame_; } | |
| 90 bool is_renderer_initiated() { return is_renderer_initiated_; } | |
| 91 bool is_same_document() { return is_same_document_; } | |
| 92 bool was_redirected() { return was_redirected_; } | |
| 93 int frame_tree_node_id() { return frame_tree_node_id_; } | |
| 94 | |
| 95 const GURL& last_committed_url() { return last_committed_url_; } | |
| 96 | |
| 97 ui::PageTransition page_transition() { return page_transition_; } | |
| 98 | |
| 99 net::Error net_error_code() { return net_error_code_; } | |
| 100 | |
| 101 private: | |
| 102 // A reference to the NavigationHandle so this class will track only | |
| 103 // one navigation at a time. It is set at DidStartNavigation and cleared | |
| 104 // at DidFinishNavigation before the NavigationHandle is destroyed. | |
| 105 NavigationHandle* handle_ = nullptr; | |
| 106 bool has_committed_ = false; | |
| 107 bool is_error_ = false; | |
| 108 bool is_main_frame_ = false; | |
| 109 bool is_parent_main_frame_ = false; | |
| 110 bool is_renderer_initiated_ = true; | |
| 111 bool is_same_document_ = false; | |
| 112 bool was_redirected_ = false; | |
| 113 int frame_tree_node_id_ = -1; | |
| 114 ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK; | |
| 115 GURL expected_start_url_; | |
| 116 GURL last_committed_url_; | |
| 117 net::Error net_error_code_ = net::OK; | |
| 118 }; | |
| 119 | |
| 120 // A test NavigationThrottle that will return pre-determined checks and run | 31 // A test NavigationThrottle that will return pre-determined checks and run |
| 121 // callbacks when the various NavigationThrottle methods are called. It is | 32 // callbacks when the various NavigationThrottle methods are called. It is |
| 122 // not instantiated directly but through a TestNavigationThrottleInstaller. | 33 // not instantiated directly but through a TestNavigationThrottleInstaller. |
| 123 class TestNavigationThrottle : public NavigationThrottle { | 34 class TestNavigationThrottle : public NavigationThrottle { |
| 124 public: | 35 public: |
| 125 TestNavigationThrottle( | 36 TestNavigationThrottle( |
| 126 NavigationHandle* handle, | 37 NavigationHandle* handle, |
| 127 NavigationThrottle::ThrottleCheckResult will_start_result, | 38 NavigationThrottle::ThrottleCheckResult will_start_result, |
| 128 NavigationThrottle::ThrottleCheckResult will_redirect_result, | 39 NavigationThrottle::ThrottleCheckResult will_redirect_result, |
| 129 NavigationThrottle::ThrottleCheckResult will_process_result, | 40 NavigationThrottle::ThrottleCheckResult will_process_result, |
| (...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 | 1042 |
| 1132 GURL url2(embedded_test_server()->GetURL("/title1.html")); | 1043 GURL url2(embedded_test_server()->GetURL("/title1.html")); |
| 1133 TestNavigationObserver same_tab_observer( | 1044 TestNavigationObserver same_tab_observer( |
| 1134 shell()->web_contents(), 1); | 1045 shell()->web_contents(), 1); |
| 1135 shell()->LoadURL(url2); | 1046 shell()->LoadURL(url2); |
| 1136 same_tab_observer.Wait(); | 1047 same_tab_observer.Wait(); |
| 1137 | 1048 |
| 1138 EXPECT_EQ(net::ERR_ABORTED, observer.net_error_code()); | 1049 EXPECT_EQ(net::ERR_ABORTED, observer.net_error_code()); |
| 1139 } | 1050 } |
| 1140 | 1051 |
| 1052 // Tests that when a renderer-initiated request redirects to a URL that the |
| 1053 // renderer can't access, the right error code is set on the NavigationHandle. |
| 1054 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ErrorCodeOnRedirect) { |
| 1055 GURL url(embedded_test_server()->GetURL("/title1.html")); |
| 1056 EXPECT_TRUE(NavigateToURL(shell(), url)); |
| 1057 |
| 1058 GURL redirect_url = embedded_test_server()->GetURL( |
| 1059 std::string("/server-redirect?") + kChromeUINetworkErrorsListingURL); |
| 1060 NavigationHandleObserver observer(shell()->web_contents(), redirect_url); |
| 1061 TestNavigationObserver same_tab_observer(shell()->web_contents(), 1); |
| 1062 EXPECT_TRUE( |
| 1063 ExecuteScript(shell(), base::StringPrintf("location.href = '%s';", |
| 1064 redirect_url.spec().c_str()))); |
| 1065 same_tab_observer.Wait(); |
| 1066 EXPECT_EQ(net::ERR_ABORTED, observer.net_error_code()); |
| 1067 } |
| 1068 |
| 1069 // Tests that when a navigation is aborted (i.e. because of beforeunload), the |
| 1070 // right error code is set on the NavigationHandle. |
| 1071 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, |
| 1072 ErrorCodeOnAbortedNavigation) { |
| 1073 // Without PlzNavigate, NavigationHandles aren't created until after the |
| 1074 // beforeunload handler runs. |
| 1075 if (!IsBrowserSideNavigationEnabled()) |
| 1076 return; |
| 1077 GURL url( |
| 1078 embedded_test_server()->GetURL("/render_frame_host/beforeunload.html")); |
| 1079 EXPECT_TRUE(NavigateToURL(shell(), url)); |
| 1080 |
| 1081 GURL new_url("/title1.html"); |
| 1082 NavigationHandleObserver observer(shell()->web_contents(), new_url); |
| 1083 TestNavigationManager navigation_waiter(shell()->web_contents(), new_url); |
| 1084 PrepContentsForBeforeUnloadTest(shell()->web_contents()); |
| 1085 SetShouldProceedOnBeforeUnload(shell(), false); |
| 1086 |
| 1087 shell()->LoadURL(new_url); |
| 1088 WaitForAppModalDialog(shell()); |
| 1089 static_cast<WebContentsImpl*>(shell()->web_contents()) |
| 1090 ->CancelModalDialogsForRenderManager(); |
| 1091 navigation_waiter.WaitForNavigationFinished(); |
| 1092 EXPECT_EQ(net::ERR_ABORTED, observer.net_error_code()); |
| 1093 } |
| 1094 |
| 1141 // This class allows running tests with PlzNavigate enabled, regardless of | 1095 // This class allows running tests with PlzNavigate enabled, regardless of |
| 1142 // default test configuration. | 1096 // default test configuration. |
| 1143 class PlzNavigateNavigationHandleImplBrowserTest : public ContentBrowserTest { | 1097 class PlzNavigateNavigationHandleImplBrowserTest : public ContentBrowserTest { |
| 1144 public: | 1098 public: |
| 1145 PlzNavigateNavigationHandleImplBrowserTest() {} | 1099 PlzNavigateNavigationHandleImplBrowserTest() {} |
| 1146 | 1100 |
| 1147 void SetUpCommandLine(base::CommandLine* command_line) override { | 1101 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 1148 command_line->AppendSwitch(switches::kEnableBrowserSideNavigation); | 1102 command_line->AppendSwitch(switches::kEnableBrowserSideNavigation); |
| 1149 } | 1103 } |
| 1150 | 1104 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 NavigationHandleObserver observer(shell()->web_contents(), error_url); | 1170 NavigationHandleObserver observer(shell()->web_contents(), error_url); |
| 1217 EXPECT_FALSE(NavigateToURL(shell(), error_url)); | 1171 EXPECT_FALSE(NavigateToURL(shell(), error_url)); |
| 1218 EXPECT_TRUE(observer.has_committed()); | 1172 EXPECT_TRUE(observer.has_committed()); |
| 1219 EXPECT_TRUE(observer.is_error()); | 1173 EXPECT_TRUE(observer.is_error()); |
| 1220 EXPECT_NE(site_instance, | 1174 EXPECT_NE(site_instance, |
| 1221 shell()->web_contents()->GetMainFrame()->GetSiteInstance()); | 1175 shell()->web_contents()->GetMainFrame()->GetSiteInstance()); |
| 1222 } | 1176 } |
| 1223 } | 1177 } |
| 1224 | 1178 |
| 1225 } // namespace content | 1179 } // namespace content |
| OLD | NEW |