blob: fd4a7b5cdf226edcc177650e3f27717b94c4b62d [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
danakjc492bf82020-09-09 20:02:445#include "content/browser/renderer_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
Avi Drissman650a39d12020-07-14 17:18:2975 // the WebContentsObserverConsistencyChecker 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
Aaron Colwelldc50263c2020-09-18 01:54:22116 request_->WillRedirectRequest(
Arthur Hemery920379612020-10-07 11:46:41117 GURL(), CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated(),
Aaron Colwelldc50263c2020-09-18 01:54:22118 nullptr /* post_redirect_process */);
clamy49678312015-10-22 21:59:00119 }
120
Lucas Garron0cedd962017-10-17 07:23:33121 // Helper function to call WillFailRequest on |handle|. If this function
122 // returns DEFER, |callback_result_| will be set to the actual result of the
123 // throttle checks when they are finished.
Lucas Garronc1edb5ab2017-11-08 03:31:13124 void SimulateWillFailRequest(
125 net::Error net_error_code,
126 const base::Optional<net::SSLInfo> ssl_info = base::nullopt) {
Lucas Garron0cedd962017-10-17 07:23:33127 was_callback_called_ = false;
128 callback_result_ = NavigationThrottle::DEFER;
Mohamed Abdelhalimb4db22a2019-06-18 10:46:52129 request_->set_net_error(net_error_code);
Lucas Garron0cedd962017-10-17 07:23:33130
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44131 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43132 // the NavigationRequestTest.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44133 request_->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18134 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
135 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44136
137 request_->WillFailRequest();
Lucas Garron0cedd962017-10-17 07:23:33138 }
139
clamy49678312015-10-22 21:59:00140 // Whether the callback was called.
141 bool was_callback_called() const { return was_callback_called_; }
142
143 // Returns the callback_result.
144 NavigationThrottle::ThrottleCheckResult callback_result() const {
145 return callback_result_;
146 }
147
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19148 NavigationRequest::NavigationState state() { return request_->state(); }
Mohamed Abdelhalimccd149af2019-10-31 14:48:53149
Lucas Garron0cedd962017-10-17 07:23:33150 bool call_counts_match(TestNavigationThrottle* throttle,
151 int start,
152 int redirect,
153 int failure,
154 int process) {
155 return start == throttle->GetCallCount(
156 TestNavigationThrottle::WILL_START_REQUEST) &&
157 redirect == throttle->GetCallCount(
158 TestNavigationThrottle::WILL_REDIRECT_REQUEST) &&
159 failure == throttle->GetCallCount(
160 TestNavigationThrottle::WILL_FAIL_REQUEST) &&
161 process == throttle->GetCallCount(
162 TestNavigationThrottle::WILL_PROCESS_RESPONSE);
163 }
164
165 // Creates, register and returns a TestNavigationThrottle that will
166 // synchronously return |result| on checks by default.
clamy49678312015-10-22 21:59:00167 TestNavigationThrottle* CreateTestNavigationThrottle(
168 NavigationThrottle::ThrottleCheckResult result) {
169 TestNavigationThrottle* test_throttle =
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31170 new TestNavigationThrottle(request_.get());
Lucas Garron79e1a972017-10-04 22:25:06171 test_throttle->SetResponseForAllMethods(TestNavigationThrottle::SYNCHRONOUS,
172 result);
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43173 request_->RegisterThrottleForTesting(
dcheng9bfa5162016-04-09 01:00:57174 std::unique_ptr<TestNavigationThrottle>(test_throttle));
clamy49678312015-10-22 21:59:00175 return test_throttle;
176 }
177
Lucas Garron0cedd962017-10-17 07:23:33178 // Creates, register and returns a TestNavigationThrottle that will
179 // synchronously return |result| on check for the given |method|, and
180 // NavigationThrottle::PROCEED otherwise.
181 TestNavigationThrottle* CreateTestNavigationThrottle(
182 TestNavigationThrottle::ThrottleMethod method,
183 NavigationThrottle::ThrottleCheckResult result) {
184 TestNavigationThrottle* test_throttle =
185 CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
186 test_throttle->SetResponse(method, TestNavigationThrottle::SYNCHRONOUS,
187 result);
188 return test_throttle;
189 }
190
Mohamed Abdelhalim9ef43fc2019-04-05 13:09:43191 // TODO(zetamoo): Use NavigationSimulator instead of creating
192 // NavigationRequest and NavigationHandleImpl.
clamy1d4e78fd2017-07-11 12:59:19193 void CreateNavigationHandle() {
Lucas Furukawa Gadanieeddf2de2019-08-01 23:37:57194 auto common_params = CreateCommonNavigationParams();
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51195 common_params->initiator_origin =
Lukasz Anforowicz435bcb582019-07-12 20:50:06196 url::Origin::Create(GURL("https://initiator.example.com"));
arthursonzogni70ac7302020-05-28 08:49:05197 auto commit_params = CreateCommitNavigationParams();
198 commit_params->frame_policy =
199 main_test_rfh()->frame_tree_node()->pending_frame_policy();
Camille Lamy7c02ec702019-01-17 17:50:23200 request_ = NavigationRequest::CreateBrowserInitiated(
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51201 main_test_rfh()->frame_tree_node(), std::move(common_params),
arthursonzogni70ac7302020-05-28 08:49:05202 std::move(commit_params), false /* browser-initiated */,
John Delaneyf43556d2020-05-04 23:19:06203 GlobalFrameRoutingId() /* initiator_routing_id */,
John Delaney50425f82020-04-07 16:26:21204 std::string() /* extra_headers */, nullptr /* frame_entry */,
205 nullptr /* entry */, nullptr /* post_body */,
206 nullptr /* navigation_ui_data */, base::nullopt /* impression */);
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31207 request_->StartNavigation(true);
clamy1d4e78fd2017-07-11 12:59:19208 }
209
clamy49678312015-10-22 21:59:00210 private:
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31211 // The callback provided to NavigationRequest::WillStartRequest,
212 // NavigationRequest::WillRedirectRequest, and
213 // NavigationRequest::WillFailRequest during the tests.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44214 bool UpdateThrottleCheckResult(
clamy49678312015-10-22 21:59:00215 NavigationThrottle::ThrottleCheckResult result) {
216 callback_result_ = result;
217 was_callback_called_ = true;
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44218 return true;
clamy49678312015-10-22 21:59:00219 }
220
Camille Lamy7c02ec702019-01-17 17:50:23221 std::unique_ptr<NavigationRequest> request_;
clamy49678312015-10-22 21:59:00222 bool was_callback_called_;
223 NavigationThrottle::ThrottleCheckResult callback_result_;
224};
225
carlosk489d9e22016-07-25 14:25:43226// Checks that the request_context_type is properly set.
227// Note: can be extended to cover more internal members.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43228TEST_F(NavigationRequestTest, SimpleDataChecksRedirectAndProcess) {
Camille Lamy62b826012019-02-26 09:15:47229 const GURL kUrl1 = GURL("http://chromium.org");
230 const GURL kUrl2 = GURL("http://google.com");
231 auto navigation =
232 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
233 navigation->Start();
234 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05235 NavigationRequest::From(navigation->GetNavigationHandle())
236 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11237 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47238 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43239
Camille Lamy62b826012019-02-26 09:15:47240 navigation->set_http_connection_info(
241 net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1);
242 navigation->Redirect(kUrl2);
243 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05244 NavigationRequest::From(navigation->GetNavigationHandle())
245 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11246 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
Camille Lamy62b826012019-02-26 09:15:47247 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43248
Camille Lamy62b826012019-02-26 09:15:47249 navigation->set_http_connection_info(
250 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
251 navigation->ReadyToCommit();
252 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05253 NavigationRequest::From(navigation->GetNavigationHandle())
254 ->request_context_type());
bnc90be5dd782016-11-09 16:28:44255 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47256 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11257}
258
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43259TEST_F(NavigationRequestTest, SimpleDataCheckNoRedirect) {
Camille Lamy62b826012019-02-26 09:15:47260 const GURL kUrl = GURL("http://chromium.org");
261 auto navigation =
262 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
263 navigation->Start();
jkarlinbb150112016-11-02 17:55:11264 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47265 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11266
Camille Lamy62b826012019-02-26 09:15:47267 navigation->set_http_connection_info(
268 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
269 navigation->ReadyToCommit();
bnc90be5dd782016-11-09 16:28:44270 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47271 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43272}
273
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43274TEST_F(NavigationRequestTest, SimpleDataChecksFailure) {
Camille Lamy62b826012019-02-26 09:15:47275 const GURL kUrl = GURL("http://chromium.org");
276 auto navigation =
277 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
278 navigation->Start();
279 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05280 NavigationRequest::From(navigation->GetNavigationHandle())
281 ->request_context_type());
Lucas Garron0cedd962017-10-17 07:23:33282 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47283 navigation->GetNavigationHandle()->GetConnectionInfo());
Lucas Garron0cedd962017-10-17 07:23:33284
Camille Lamy62b826012019-02-26 09:15:47285 navigation->Fail(net::ERR_CERT_DATE_INVALID);
286 EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05287 NavigationRequest::From(navigation->GetNavigationHandle())
288 ->request_context_type());
Camille Lamy62b826012019-02-26 09:15:47289 EXPECT_EQ(net::ERR_CERT_DATE_INVALID,
290 navigation->GetNavigationHandle()->GetNetErrorCode());
Lucas Garron0cedd962017-10-17 07:23:33291}
292
clamye88533842015-11-18 12:48:57293// Checks that a navigation deferred during WillStartRequest can be properly
294// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53295TEST_F(NavigationRequestTest, CancelDeferredWillStart) {
clamye88533842015-11-18 12:48:57296 TestNavigationThrottle* test_throttle =
297 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19298 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33299 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57300
301 // Simulate WillStartRequest. The request should be deferred. The callback
302 // should not have been called.
303 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19304 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
clamye88533842015-11-18 12:48:57305 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33306 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57307
308 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21309 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19310 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57311 EXPECT_TRUE(was_callback_called());
312 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33313 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57314}
315
316// Checks that a navigation deferred during WillRedirectRequest can be properly
317// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53318TEST_F(NavigationRequestTest, CancelDeferredWillRedirect) {
clamye88533842015-11-18 12:48:57319 TestNavigationThrottle* test_throttle =
320 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19321 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33322 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57323
324 // Simulate WillRedirectRequest. The request should be deferred. The callback
325 // should not have been called.
326 SimulateWillRedirectRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19327 EXPECT_EQ(NavigationRequest::WILL_REDIRECT_REQUEST, state());
clamye88533842015-11-18 12:48:57328 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33329 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
clamye88533842015-11-18 12:48:57330
331 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21332 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19333 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57334 EXPECT_TRUE(was_callback_called());
335 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33336 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
337}
338
339// Checks that a navigation deferred during WillFailRequest can be properly
340// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53341TEST_F(NavigationRequestTest, CancelDeferredWillFail) {
Lucas Garron0cedd962017-10-17 07:23:33342 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
343 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19344 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33345 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
346
347 // Simulate WillStartRequest.
348 SimulateWillStartRequest();
349 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
350
351 // Simulate WillFailRequest. The request should be deferred. The callback
352 // should not have been called.
353 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19354 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33355 EXPECT_FALSE(was_callback_called());
356 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
357
358 // Cancel the request. The callback should have been called.
359 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19360 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33361 EXPECT_TRUE(was_callback_called());
362 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
363 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
clamye88533842015-11-18 12:48:57364}
365
366// Checks that a navigation deferred can be canceled and not ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53367TEST_F(NavigationRequestTest, CancelDeferredWillRedirectNoIgnore) {
clamye88533842015-11-18 12:48:57368 TestNavigationThrottle* test_throttle =
369 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
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, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57372
Lucas Garron0cedd962017-10-17 07:23:33373 // Simulate WillStartRequest. The request should be deferred. The callback
clamye88533842015-11-18 12:48:57374 // should not have been called.
375 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19376 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33377 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57378
379 // Cancel the request. The callback should have been called with CANCEL, and
380 // not CANCEL_AND_IGNORE.
Charles Harrison4f2bf1a2017-07-18 20:21:21381 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19382 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57383 EXPECT_TRUE(was_callback_called());
384 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33385 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57386}
387
Lucas Garron0cedd962017-10-17 07:23:33388// Checks that a navigation deferred by WillFailRequest can be canceled and not
389// ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53390TEST_F(NavigationRequestTest, CancelDeferredWillFailNoIgnore) {
Lucas Garron0cedd962017-10-17 07:23:33391 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
392 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19393 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33394 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
395
396 // Simulate WillStartRequest.
397 SimulateWillStartRequest();
398 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
399
400 // Simulate WillFailRequest. The request should be deferred. The callback
401 // should not have been called.
402 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19403 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33404 EXPECT_FALSE(was_callback_called());
405 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
406
407 // Cancel the request. The callback should have been called with CANCEL, and
408 // not CANCEL_AND_IGNORE.
409 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19410 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33411 EXPECT_TRUE(was_callback_called());
412 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
413 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
414}
415
Lucas Garronc1edb5ab2017-11-08 03:31:13416// Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
John Abd-El-Malekf36e05f2017-11-30 16:17:52417// stored on the handle.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43418TEST_F(NavigationRequestTest, WillFailRequestSetsSSLInfo) {
Lucas Garronc1edb5ab2017-11-08 03:31:13419 uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
420 int connection_status = 0;
421 net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
422
423 // Set some test values.
424 net::SSLInfo ssl_info;
425 ssl_info.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
426 ssl_info.connection_status = connection_status;
427
Camille Lamy62b826012019-02-26 09:15:47428 const GURL kUrl = GURL("https://chromium.org");
429 auto navigation =
430 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
Emily Starkfd6978ad12019-04-30 21:20:07431 navigation->SetSSLInfo(ssl_info);
Camille Lamy62b826012019-02-26 09:15:47432 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Lucas Garronc1edb5ab2017-11-08 03:31:13433
434 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID,
Camille Lamy62b826012019-02-26 09:15:47435 navigation->GetNavigationHandle()->GetSSLInfo()->cert_status);
436 EXPECT_EQ(connection_status,
437 navigation->GetNavigationHandle()->GetSSLInfo()->connection_status);
Lucas Garronc1edb5ab2017-11-08 03:31:13438}
439
Camille Lamy62b826012019-02-26 09:15:47440namespace {
441
Alex Moshchuk1a66b1d2018-05-15 21:18:26442// Helper throttle which checks that it can access NavigationHandle's
443// RenderFrameHost in WillFailRequest() and then defers the failure.
444class GetRenderFrameHostOnFailureNavigationThrottle
445 : public NavigationThrottle {
446 public:
447 GetRenderFrameHostOnFailureNavigationThrottle(NavigationHandle* handle)
448 : NavigationThrottle(handle) {}
449 ~GetRenderFrameHostOnFailureNavigationThrottle() override {}
450
451 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
452 EXPECT_TRUE(navigation_handle()->GetRenderFrameHost());
453 return NavigationThrottle::DEFER;
454 }
455
456 const char* GetNameForLogging() override {
457 return "GetRenderFrameHostOnFailureNavigationThrottle";
458 }
459
460 private:
461 DISALLOW_COPY_AND_ASSIGN(GetRenderFrameHostOnFailureNavigationThrottle);
462};
463
Camille Lamy62b826012019-02-26 09:15:47464class ThrottleTestContentBrowserClient : public ContentBrowserClient {
465 std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation(
466 NavigationHandle* navigation_handle) override {
467 std::vector<std::unique_ptr<NavigationThrottle>> throttle;
468 throttle.push_back(
469 std::make_unique<GetRenderFrameHostOnFailureNavigationThrottle>(
470 navigation_handle));
471 return throttle;
472 }
473};
474
475} // namespace
476
Alex Moshchuk1a66b1d2018-05-15 21:18:26477// Verify that the NavigationHandle::GetRenderFrameHost() can be retrieved by a
478// throttle in WillFailRequest(), as well as after deferring the failure. This
479// is allowed, since at that point the final RenderFrameHost will have already
480// been chosen. See https://crbug.com/817881.
Mohamed Abdelhalimba020672019-10-31 16:18:53481TEST_F(NavigationRequestTest, WillFailRequestCanAccessRenderFrameHost) {
Camille Lamy62b826012019-02-26 09:15:47482 std::unique_ptr<ContentBrowserClient> client(
483 new ThrottleTestContentBrowserClient);
484 ContentBrowserClient* old_browser_client =
485 SetBrowserClientForTesting(client.get());
486
487 const GURL kUrl = GURL("http://chromium.org");
488 auto navigation =
489 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
490 navigation->SetAutoAdvance(false);
491 navigation->Start();
492 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalim3b235272019-11-05 15:06:07493 EXPECT_EQ(
494 NavigationRequest::WILL_FAIL_REQUEST,
495 NavigationRequest::From(navigation->GetNavigationHandle())->state());
Camille Lamy62b826012019-02-26 09:15:47496 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
Mohamed Abdelhalim40c35d22019-09-19 15:59:05497 NavigationRequest::From(navigation->GetNavigationHandle())
danakjf26536bf2020-09-10 00:46:13498 ->GetNavigationThrottleRunnerForTesting()
Mohamed Abdelhalim40c35d22019-09-19 15:59:05499 ->CallResumeForTesting();
Camille Lamy62b826012019-02-26 09:15:47500 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
501
502 SetBrowserClientForTesting(old_browser_client);
Alex Moshchuk1a66b1d2018-05-15 21:18:26503}
504
Antonio Sartori3cfa3b62020-10-09 10:42:40505TEST_F(NavigationRequestTest, PolicyContainerInheritance) {
506 struct TestCase {
507 const char* url;
508 bool expect_inherit;
509 } cases[]{{"about:blank", true},
510 {"data:text/plain,hello", true},
511 {"file://local", false},
512 {"http://chromium.org", false}};
513
514 const GURL kUrl1 = GURL("http://chromium.org");
515 auto navigation =
516 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
517 navigation->Commit();
518
519 for (auto test : cases) {
520 // We navigate child frames because the BlockedSchemeNavigationThrottle
521 // restricts navigations in the main frame.
522 auto* child_frame = static_cast<TestRenderFrameHost*>(
523 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child"));
524
525 // We set the referrer policy of the frame to "always". We then create a new
526 // navigation, set as initiator the frame itself, start the navigation, and
527 // change the referrer policy of the frame to "never". After we commit the
528 // navigation:
529 // - If navigating to a local scheme, the target frame should have inherited
530 // the referrer policy of the initiator ("always").
531 // - If navigating to a non-local scheme, the target frame should have a new
532 // policy container (hence referrer policy set to "default").
533 const GURL kUrl = GURL(test.url);
534 auto navigation =
535 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_frame);
Antonio Sartori5b2f8042020-10-23 18:13:26536 static_cast<blink::mojom::PolicyContainerHost*>(
537 child_frame->policy_container())
538 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kAlways);
Antonio Sartori3cfa3b62020-10-09 10:42:40539 navigation->SetInitiatorFrame(child_frame);
540 navigation->Start();
Antonio Sartori5b2f8042020-10-23 18:13:26541 static_cast<blink::mojom::PolicyContainerHost*>(
542 child_frame->policy_container())
543 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
Antonio Sartori3cfa3b62020-10-09 10:42:40544 navigation->Commit();
545 EXPECT_EQ(
546 test.expect_inherit ? network::mojom::ReferrerPolicy::kAlways
547 : network::mojom::ReferrerPolicy::kDefault,
548 static_cast<RenderFrameHostImpl*>(navigation->GetFinalRenderFrameHost())
549 ->policy_container()
550 ->referrer_policy());
551 }
552}
553
clamy49678312015-10-22 21:59:00554} // namespace content