blob: 88e5370ff67a42d7e92cf48a642e4ab098f45b74 [file] [log] [blame]
clamy49678312015-10-22 21:59:001// Copyright 2015 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
Mohamed Abdelhalim1e8c5822019-08-02 11:45:435#include "content/browser/frame_host/navigation_request.h"
Sebastien Marchandf8cbfab2019-01-25 16:02:306#include "base/bind.h"
Charles Harrison860f7ef2017-06-28 15:31:417#include "base/macros.h"
Lucas Garron0cedd962017-10-17 07:23:338#include "base/optional.h"
Becky Zhou9898cb6e2019-06-05 00:35:309#include "build/build_config.h"
clamy49678312015-10-22 21:59:0010#include "content/public/browser/navigation_throttle.h"
jam6d47c3452016-09-09 18:51:0111#include "content/public/browser/ssl_status.h"
Hans Wennborg5ffd1392019-10-16 11:00:0212#include "content/public/common/content_client.h"
Charles Harrison860f7ef2017-06-28 15:31:4113#include "content/public/common/url_constants.h"
Lucas Garron79e1a972017-10-04 22:25:0614#include "content/public/test/test_navigation_throttle.h"
Camille Lamy62b826012019-02-26 09:15:4715#include "content/test/navigation_simulator_impl.h"
Charles Harrison860f7ef2017-06-28 15:31:4116#include "content/test/test_content_browser_client.h"
clamy49678312015-10-22 21:59:0017#include "content/test/test_render_frame_host.h"
scottmg276753cf2016-10-27 18:25:2218#include "content/test/test_web_contents.h"
Lucas Garronc1edb5ab2017-11-08 03:31:1319#include "net/ssl/ssl_connection_status_flags.h"
Richard Lie6899952018-11-30 08:42:0020#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
clamy49678312015-10-22 21:59:0021
22namespace content {
23
clamy1d4e78fd2017-07-11 12:59:1924// Test version of a NavigationThrottle that will execute a callback when
25// called.
Lucas Garron79e1a972017-10-04 22:25:0626class DeletingNavigationThrottle : public NavigationThrottle {
clamy1d4e78fd2017-07-11 12:59:1927 public:
Lucas Garron79e1a972017-10-04 22:25:0628 DeletingNavigationThrottle(NavigationHandle* handle,
29 const base::RepeatingClosure& deletion_callback)
30 : NavigationThrottle(handle), deletion_callback_(deletion_callback) {}
31 ~DeletingNavigationThrottle() override {}
clamy1d4e78fd2017-07-11 12:59:1932
33 NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0634 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1935 return NavigationThrottle::PROCEED;
36 }
37
38 NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0639 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1940 return NavigationThrottle::PROCEED;
41 }
42
Lucas Garron0cedd962017-10-17 07:23:3343 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
44 deletion_callback_.Run();
45 return NavigationThrottle::PROCEED;
46 }
47
clamy1d4e78fd2017-07-11 12:59:1948 NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
Lucas Garron79e1a972017-10-04 22:25:0649 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1950 return NavigationThrottle::PROCEED;
51 }
52
53 const char* GetNameForLogging() override {
Lucas Garron79e1a972017-10-04 22:25:0654 return "DeletingNavigationThrottle";
clamy1d4e78fd2017-07-11 12:59:1955 }
56
57 private:
Lucas Garron79e1a972017-10-04 22:25:0658 base::RepeatingClosure deletion_callback_;
clamy1d4e78fd2017-07-11 12:59:1959};
60
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4361class NavigationRequestTest : public RenderViewHostImplTestHarness {
clamy49678312015-10-22 21:59:0062 public:
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4363 NavigationRequestTest()
clamy49678312015-10-22 21:59:0064 : was_callback_called_(false),
65 callback_result_(NavigationThrottle::DEFER) {}
66
67 void SetUp() override {
68 RenderViewHostImplTestHarness::SetUp();
clamy1d4e78fd2017-07-11 12:59:1969 CreateNavigationHandle();
scottmg276753cf2016-10-27 18:25:2270 contents()->GetMainFrame()->InitializeRenderFrameIfNeeded();
clamy49678312015-10-22 21:59:0071 }
72
73 void TearDown() override {
Mohamed Abdelhalimb7cabb12019-03-26 13:31:2574 // Release the |request_| before destroying the WebContents, to match
clamy49678312015-10-22 21:59:0075 // the WebContentsObserverSanityChecker expectations.
Mohamed Abdelhalimb7cabb12019-03-26 13:31:2576 request_.reset();
clamy49678312015-10-22 21:59:0077 RenderViewHostImplTestHarness::TearDown();
78 }
79
Charles Harrison4f2bf1a2017-07-18 20:21:2180 void CancelDeferredNavigation(
81 NavigationThrottle::ThrottleCheckResult result) {
Mohamed Abdelhalim9ef43fc2019-04-05 13:09:4382 request_->CancelDeferredNavigationInternal(result);
Charles Harrison4f2bf1a2017-07-18 20:21:2183 }
84
clamy49678312015-10-22 21:59:0085 // Helper function to call WillStartRequest on |handle|. If this function
86 // returns DEFER, |callback_result_| will be set to the actual result of
87 // the throttle checks when they are finished.
88 void SimulateWillStartRequest() {
89 was_callback_called_ = false;
90 callback_result_ = NavigationThrottle::DEFER;
91
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:4492 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4393 // the NavigationRequestTest.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:4494 request_->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:1895 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
96 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:4497
98 request_->WillStartRequest();
clamy49678312015-10-22 21:59:0099 }
100
101 // Helper function to call WillRedirectRequest on |handle|. If this function
102 // returns DEFER, |callback_result_| will be set to the actual result of the
103 // throttle checks when they are finished.
clamye88533842015-11-18 12:48:57104 // TODO(clamy): this should also simulate that WillStartRequest was called if
105 // it has not been called before.
clamy49678312015-10-22 21:59:00106 void SimulateWillRedirectRequest() {
107 was_callback_called_ = false;
108 callback_result_ = NavigationThrottle::DEFER;
109
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44110 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43111 // the NavigationRequestTest.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44112 request_->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18113 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
114 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44115
116 request_->WillRedirectRequest(GURL(), nullptr);
clamy49678312015-10-22 21:59:00117 }
118
Lucas Garron0cedd962017-10-17 07:23:33119 // Helper function to call WillFailRequest on |handle|. If this function
120 // returns DEFER, |callback_result_| will be set to the actual result of the
121 // throttle checks when they are finished.
Lucas Garronc1edb5ab2017-11-08 03:31:13122 void SimulateWillFailRequest(
123 net::Error net_error_code,
124 const base::Optional<net::SSLInfo> ssl_info = base::nullopt) {
Lucas Garron0cedd962017-10-17 07:23:33125 was_callback_called_ = false;
126 callback_result_ = NavigationThrottle::DEFER;
Mohamed Abdelhalimb4db22a2019-06-18 10:46:52127 request_->set_net_error(net_error_code);
Lucas Garron0cedd962017-10-17 07:23:33128
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44129 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43130 // the NavigationRequestTest.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44131 request_->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18132 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
133 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44134
135 request_->WillFailRequest();
Lucas Garron0cedd962017-10-17 07:23:33136 }
137
clamy49678312015-10-22 21:59:00138 // Whether the callback was called.
139 bool was_callback_called() const { return was_callback_called_; }
140
141 // Returns the callback_result.
142 NavigationThrottle::ThrottleCheckResult callback_result() const {
143 return callback_result_;
144 }
145
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19146 NavigationRequest::NavigationState state() { return request_->state(); }
Mohamed Abdelhalimccd149af2019-10-31 14:48:53147
Lucas Garron0cedd962017-10-17 07:23:33148 bool call_counts_match(TestNavigationThrottle* throttle,
149 int start,
150 int redirect,
151 int failure,
152 int process) {
153 return start == throttle->GetCallCount(
154 TestNavigationThrottle::WILL_START_REQUEST) &&
155 redirect == throttle->GetCallCount(
156 TestNavigationThrottle::WILL_REDIRECT_REQUEST) &&
157 failure == throttle->GetCallCount(
158 TestNavigationThrottle::WILL_FAIL_REQUEST) &&
159 process == throttle->GetCallCount(
160 TestNavigationThrottle::WILL_PROCESS_RESPONSE);
161 }
162
163 // Creates, register and returns a TestNavigationThrottle that will
164 // synchronously return |result| on checks by default.
clamy49678312015-10-22 21:59:00165 TestNavigationThrottle* CreateTestNavigationThrottle(
166 NavigationThrottle::ThrottleCheckResult result) {
167 TestNavigationThrottle* test_throttle =
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31168 new TestNavigationThrottle(request_.get());
Lucas Garron79e1a972017-10-04 22:25:06169 test_throttle->SetResponseForAllMethods(TestNavigationThrottle::SYNCHRONOUS,
170 result);
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43171 request_->RegisterThrottleForTesting(
dcheng9bfa5162016-04-09 01:00:57172 std::unique_ptr<TestNavigationThrottle>(test_throttle));
clamy49678312015-10-22 21:59:00173 return test_throttle;
174 }
175
Lucas Garron0cedd962017-10-17 07:23:33176 // Creates, register and returns a TestNavigationThrottle that will
177 // synchronously return |result| on check for the given |method|, and
178 // NavigationThrottle::PROCEED otherwise.
179 TestNavigationThrottle* CreateTestNavigationThrottle(
180 TestNavigationThrottle::ThrottleMethod method,
181 NavigationThrottle::ThrottleCheckResult result) {
182 TestNavigationThrottle* test_throttle =
183 CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
184 test_throttle->SetResponse(method, TestNavigationThrottle::SYNCHRONOUS,
185 result);
186 return test_throttle;
187 }
188
Mohamed Abdelhalim9ef43fc2019-04-05 13:09:43189 // TODO(zetamoo): Use NavigationSimulator instead of creating
190 // NavigationRequest and NavigationHandleImpl.
clamy1d4e78fd2017-07-11 12:59:19191 void CreateNavigationHandle() {
Lucas Furukawa Gadanieeddf2de2019-08-01 23:37:57192 auto common_params = CreateCommonNavigationParams();
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51193 common_params->initiator_origin =
Lukasz Anforowicz435bcb582019-07-12 20:50:06194 url::Origin::Create(GURL("https://initiator.example.com"));
Camille Lamy7c02ec702019-01-17 17:50:23195 request_ = NavigationRequest::CreateBrowserInitiated(
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51196 main_test_rfh()->frame_tree_node(), std::move(common_params),
Lucas Furukawa Gadania9c45682019-07-31 22:05:14197 CreateCommitNavigationParams(), false /* browser-initiated */,
John Delaney50425f82020-04-07 16:26:21198 std::string() /* extra_headers */, nullptr /* frame_entry */,
199 nullptr /* entry */, nullptr /* post_body */,
200 nullptr /* navigation_ui_data */, base::nullopt /* impression */);
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31201 request_->StartNavigation(true);
clamy1d4e78fd2017-07-11 12:59:19202 }
203
clamy49678312015-10-22 21:59:00204 private:
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31205 // The callback provided to NavigationRequest::WillStartRequest,
206 // NavigationRequest::WillRedirectRequest, and
207 // NavigationRequest::WillFailRequest during the tests.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44208 bool UpdateThrottleCheckResult(
clamy49678312015-10-22 21:59:00209 NavigationThrottle::ThrottleCheckResult result) {
210 callback_result_ = result;
211 was_callback_called_ = true;
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44212 return true;
clamy49678312015-10-22 21:59:00213 }
214
Camille Lamy7c02ec702019-01-17 17:50:23215 std::unique_ptr<NavigationRequest> request_;
clamy49678312015-10-22 21:59:00216 bool was_callback_called_;
217 NavigationThrottle::ThrottleCheckResult callback_result_;
218};
219
carlosk489d9e22016-07-25 14:25:43220// Checks that the request_context_type is properly set.
221// Note: can be extended to cover more internal members.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43222TEST_F(NavigationRequestTest, SimpleDataChecksRedirectAndProcess) {
Camille Lamy62b826012019-02-26 09:15:47223 const GURL kUrl1 = GURL("http://chromium.org");
224 const GURL kUrl2 = GURL("http://google.com");
225 auto navigation =
226 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
227 navigation->Start();
228 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05229 NavigationRequest::From(navigation->GetNavigationHandle())
230 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11231 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47232 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43233
Camille Lamy62b826012019-02-26 09:15:47234 navigation->set_http_connection_info(
235 net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1);
236 navigation->Redirect(kUrl2);
237 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05238 NavigationRequest::From(navigation->GetNavigationHandle())
239 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11240 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
Camille Lamy62b826012019-02-26 09:15:47241 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43242
Camille Lamy62b826012019-02-26 09:15:47243 navigation->set_http_connection_info(
244 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
245 navigation->ReadyToCommit();
246 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05247 NavigationRequest::From(navigation->GetNavigationHandle())
248 ->request_context_type());
bnc90be5dd782016-11-09 16:28:44249 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47250 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11251}
252
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43253TEST_F(NavigationRequestTest, SimpleDataCheckNoRedirect) {
Camille Lamy62b826012019-02-26 09:15:47254 const GURL kUrl = GURL("http://chromium.org");
255 auto navigation =
256 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
257 navigation->Start();
jkarlinbb150112016-11-02 17:55:11258 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47259 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11260
Camille Lamy62b826012019-02-26 09:15:47261 navigation->set_http_connection_info(
262 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
263 navigation->ReadyToCommit();
bnc90be5dd782016-11-09 16:28:44264 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47265 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43266}
267
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43268TEST_F(NavigationRequestTest, SimpleDataChecksFailure) {
Camille Lamy62b826012019-02-26 09:15:47269 const GURL kUrl = GURL("http://chromium.org");
270 auto navigation =
271 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
272 navigation->Start();
273 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05274 NavigationRequest::From(navigation->GetNavigationHandle())
275 ->request_context_type());
Lucas Garron0cedd962017-10-17 07:23:33276 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47277 navigation->GetNavigationHandle()->GetConnectionInfo());
Lucas Garron0cedd962017-10-17 07:23:33278
Camille Lamy62b826012019-02-26 09:15:47279 navigation->Fail(net::ERR_CERT_DATE_INVALID);
280 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05281 NavigationRequest::From(navigation->GetNavigationHandle())
282 ->request_context_type());
Camille Lamy62b826012019-02-26 09:15:47283 EXPECT_EQ(net::ERR_CERT_DATE_INVALID,
284 navigation->GetNavigationHandle()->GetNetErrorCode());
Lucas Garron0cedd962017-10-17 07:23:33285}
286
clamye88533842015-11-18 12:48:57287// Checks that a navigation deferred during WillStartRequest can be properly
288// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53289TEST_F(NavigationRequestTest, CancelDeferredWillStart) {
clamye88533842015-11-18 12:48:57290 TestNavigationThrottle* test_throttle =
291 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19292 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33293 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57294
295 // Simulate WillStartRequest. The request should be deferred. The callback
296 // should not have been called.
297 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19298 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
clamye88533842015-11-18 12:48:57299 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33300 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57301
302 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21303 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19304 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57305 EXPECT_TRUE(was_callback_called());
306 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33307 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57308}
309
310// Checks that a navigation deferred during WillRedirectRequest can be properly
311// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53312TEST_F(NavigationRequestTest, CancelDeferredWillRedirect) {
clamye88533842015-11-18 12:48:57313 TestNavigationThrottle* test_throttle =
314 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19315 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33316 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57317
318 // Simulate WillRedirectRequest. The request should be deferred. The callback
319 // should not have been called.
320 SimulateWillRedirectRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19321 EXPECT_EQ(NavigationRequest::WILL_REDIRECT_REQUEST, state());
clamye88533842015-11-18 12:48:57322 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33323 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
clamye88533842015-11-18 12:48:57324
325 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21326 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19327 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57328 EXPECT_TRUE(was_callback_called());
329 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33330 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
331}
332
333// Checks that a navigation deferred during WillFailRequest can be properly
334// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53335TEST_F(NavigationRequestTest, CancelDeferredWillFail) {
Lucas Garron0cedd962017-10-17 07:23:33336 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
337 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19338 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33339 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
340
341 // Simulate WillStartRequest.
342 SimulateWillStartRequest();
343 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
344
345 // Simulate WillFailRequest. The request should be deferred. The callback
346 // should not have been called.
347 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19348 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33349 EXPECT_FALSE(was_callback_called());
350 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
351
352 // Cancel the request. The callback should have been called.
353 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19354 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33355 EXPECT_TRUE(was_callback_called());
356 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
357 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
clamye88533842015-11-18 12:48:57358}
359
360// Checks that a navigation deferred can be canceled and not ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53361TEST_F(NavigationRequestTest, CancelDeferredWillRedirectNoIgnore) {
clamye88533842015-11-18 12:48:57362 TestNavigationThrottle* test_throttle =
363 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19364 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33365 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57366
Lucas Garron0cedd962017-10-17 07:23:33367 // Simulate WillStartRequest. The request should be deferred. The callback
clamye88533842015-11-18 12:48:57368 // should not have been called.
369 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19370 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33371 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57372
373 // Cancel the request. The callback should have been called with CANCEL, and
374 // not CANCEL_AND_IGNORE.
Charles Harrison4f2bf1a2017-07-18 20:21:21375 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19376 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57377 EXPECT_TRUE(was_callback_called());
378 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33379 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57380}
381
Lucas Garron0cedd962017-10-17 07:23:33382// Checks that a navigation deferred by WillFailRequest can be canceled and not
383// ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53384TEST_F(NavigationRequestTest, CancelDeferredWillFailNoIgnore) {
Lucas Garron0cedd962017-10-17 07:23:33385 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
386 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19387 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33388 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
389
390 // Simulate WillStartRequest.
391 SimulateWillStartRequest();
392 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
393
394 // Simulate WillFailRequest. The request should be deferred. The callback
395 // should not have been called.
396 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19397 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33398 EXPECT_FALSE(was_callback_called());
399 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
400
401 // Cancel the request. The callback should have been called with CANCEL, and
402 // not CANCEL_AND_IGNORE.
403 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19404 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33405 EXPECT_TRUE(was_callback_called());
406 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
407 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
408}
409
Lucas Garronc1edb5ab2017-11-08 03:31:13410// Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
John Abd-El-Malekf36e05f2017-11-30 16:17:52411// stored on the handle.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43412TEST_F(NavigationRequestTest, WillFailRequestSetsSSLInfo) {
Lucas Garronc1edb5ab2017-11-08 03:31:13413 uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
414 int connection_status = 0;
415 net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
416
417 // Set some test values.
418 net::SSLInfo ssl_info;
419 ssl_info.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
420 ssl_info.connection_status = connection_status;
421
Camille Lamy62b826012019-02-26 09:15:47422 const GURL kUrl = GURL("https://chromium.org");
423 auto navigation =
424 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
Emily Starkfd6978ad12019-04-30 21:20:07425 navigation->SetSSLInfo(ssl_info);
Camille Lamy62b826012019-02-26 09:15:47426 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Lucas Garronc1edb5ab2017-11-08 03:31:13427
428 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID,
Camille Lamy62b826012019-02-26 09:15:47429 navigation->GetNavigationHandle()->GetSSLInfo()->cert_status);
430 EXPECT_EQ(connection_status,
431 navigation->GetNavigationHandle()->GetSSLInfo()->connection_status);
Lucas Garronc1edb5ab2017-11-08 03:31:13432}
433
Camille Lamy62b826012019-02-26 09:15:47434namespace {
435
Alex Moshchuk1a66b1d2018-05-15 21:18:26436// Helper throttle which checks that it can access NavigationHandle's
437// RenderFrameHost in WillFailRequest() and then defers the failure.
438class GetRenderFrameHostOnFailureNavigationThrottle
439 : public NavigationThrottle {
440 public:
441 GetRenderFrameHostOnFailureNavigationThrottle(NavigationHandle* handle)
442 : NavigationThrottle(handle) {}
443 ~GetRenderFrameHostOnFailureNavigationThrottle() override {}
444
445 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
446 EXPECT_TRUE(navigation_handle()->GetRenderFrameHost());
447 return NavigationThrottle::DEFER;
448 }
449
450 const char* GetNameForLogging() override {
451 return "GetRenderFrameHostOnFailureNavigationThrottle";
452 }
453
454 private:
455 DISALLOW_COPY_AND_ASSIGN(GetRenderFrameHostOnFailureNavigationThrottle);
456};
457
Camille Lamy62b826012019-02-26 09:15:47458class ThrottleTestContentBrowserClient : public ContentBrowserClient {
459 std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation(
460 NavigationHandle* navigation_handle) override {
461 std::vector<std::unique_ptr<NavigationThrottle>> throttle;
462 throttle.push_back(
463 std::make_unique<GetRenderFrameHostOnFailureNavigationThrottle>(
464 navigation_handle));
465 return throttle;
466 }
467};
468
469} // namespace
470
Alex Moshchuk1a66b1d2018-05-15 21:18:26471// Verify that the NavigationHandle::GetRenderFrameHost() can be retrieved by a
472// throttle in WillFailRequest(), as well as after deferring the failure. This
473// is allowed, since at that point the final RenderFrameHost will have already
474// been chosen. See https://crbug.com/817881.
Mohamed Abdelhalimba020672019-10-31 16:18:53475TEST_F(NavigationRequestTest, WillFailRequestCanAccessRenderFrameHost) {
Camille Lamy62b826012019-02-26 09:15:47476 std::unique_ptr<ContentBrowserClient> client(
477 new ThrottleTestContentBrowserClient);
478 ContentBrowserClient* old_browser_client =
479 SetBrowserClientForTesting(client.get());
480
481 const GURL kUrl = GURL("http://chromium.org");
482 auto navigation =
483 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
484 navigation->SetAutoAdvance(false);
485 navigation->Start();
486 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalim3b235272019-11-05 15:06:07487 EXPECT_EQ(
488 NavigationRequest::WILL_FAIL_REQUEST,
489 NavigationRequest::From(navigation->GetNavigationHandle())->state());
Camille Lamy62b826012019-02-26 09:15:47490 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
Mohamed Abdelhalim40c35d22019-09-19 15:59:05491 NavigationRequest::From(navigation->GetNavigationHandle())
492 ->CallResumeForTesting();
Camille Lamy62b826012019-02-26 09:15:47493 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
494
495 SetBrowserClientForTesting(old_browser_client);
Alex Moshchuk1a66b1d2018-05-15 21:18:26496}
497
clamy49678312015-10-22 21:59:00498} // namespace content