blob: 5aa2e232c6e44caccf75c0eb7ec8477af85bc970 [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"
Cammie Smith Barnesa0da2cf2021-01-11 22:09:376
7#include <string>
8#include <vector>
9
Sebastien Marchandf8cbfab2019-01-25 16:02:3010#include "base/bind.h"
arthursonzogni898dcda52021-01-21 08:50:1011#include "base/i18n/number_formatting.h"
Yao Xiao6e1f7d32022-01-07 03:28:4012#include "base/test/scoped_feature_list.h"
Becky Zhou9898cb6e2019-06-05 00:35:3013#include "build/build_config.h"
clamy49678312015-10-22 21:59:0014#include "content/public/browser/navigation_throttle.h"
Robbie McElrath5641d572022-05-20 17:15:2915#include "content/public/browser/site_isolation_policy.h"
jam6d47c3452016-09-09 18:51:0116#include "content/public/browser/ssl_status.h"
Hans Wennborg5ffd1392019-10-16 11:00:0217#include "content/public/common/content_client.h"
Robbie McElrath5641d572022-05-20 17:15:2918#include "content/public/common/content_switches.h"
Charles Harrison860f7ef2017-06-28 15:31:4119#include "content/public/common/url_constants.h"
Lucas Garron79e1a972017-10-04 22:25:0620#include "content/public/test/test_navigation_throttle.h"
Yao Xiao1099e4c2022-03-24 22:40:3721#include "content/test/fenced_frame_test_utils.h"
Camille Lamy62b826012019-02-26 09:15:4722#include "content/test/navigation_simulator_impl.h"
Charles Harrison860f7ef2017-06-28 15:31:4123#include "content/test/test_content_browser_client.h"
clamy49678312015-10-22 21:59:0024#include "content/test/test_render_frame_host.h"
scottmg276753cf2016-10-27 18:25:2225#include "content/test/test_web_contents.h"
Lucas Garronc1edb5ab2017-11-08 03:31:1326#include "net/ssl/ssl_connection_status_flags.h"
arthursonzogni898dcda52021-01-21 08:50:1027#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
Cammie Smith Barnesa0da2cf2021-01-11 22:09:3728#include "testing/gmock/include/gmock/gmock.h"
Anton Bikineevf62d1bf2021-05-15 17:56:0729#include "third_party/abseil-cpp/absl/types/optional.h"
Minggang Wanga13c796e2021-07-02 05:54:4330#include "third_party/blink/public/common/navigation/navigation_params.h"
Richard Lie6899952018-11-30 08:42:0031#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
clamy49678312015-10-22 21:59:0032
33namespace content {
34
clamy1d4e78fd2017-07-11 12:59:1935// Test version of a NavigationThrottle that will execute a callback when
36// called.
Lucas Garron79e1a972017-10-04 22:25:0637class DeletingNavigationThrottle : public NavigationThrottle {
clamy1d4e78fd2017-07-11 12:59:1938 public:
Lucas Garron79e1a972017-10-04 22:25:0639 DeletingNavigationThrottle(NavigationHandle* handle,
40 const base::RepeatingClosure& deletion_callback)
41 : NavigationThrottle(handle), deletion_callback_(deletion_callback) {}
Fergal Dalya1d569972021-03-16 03:24:5342 ~DeletingNavigationThrottle() override = default;
clamy1d4e78fd2017-07-11 12:59:1943
44 NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0645 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1946 return NavigationThrottle::PROCEED;
47 }
48
49 NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0650 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1951 return NavigationThrottle::PROCEED;
52 }
53
Lucas Garron0cedd962017-10-17 07:23:3354 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
55 deletion_callback_.Run();
56 return NavigationThrottle::PROCEED;
57 }
58
clamy1d4e78fd2017-07-11 12:59:1959 NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
Lucas Garron79e1a972017-10-04 22:25:0660 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1961 return NavigationThrottle::PROCEED;
62 }
63
64 const char* GetNameForLogging() override {
Lucas Garron79e1a972017-10-04 22:25:0665 return "DeletingNavigationThrottle";
clamy1d4e78fd2017-07-11 12:59:1966 }
67
68 private:
Lucas Garron79e1a972017-10-04 22:25:0669 base::RepeatingClosure deletion_callback_;
clamy1d4e78fd2017-07-11 12:59:1970};
71
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4372class NavigationRequestTest : public RenderViewHostImplTestHarness {
clamy49678312015-10-22 21:59:0073 public:
Fergal Dalya1d569972021-03-16 03:24:5374 NavigationRequestTest() : callback_result_(NavigationThrottle::DEFER) {}
clamy49678312015-10-22 21:59:0075
76 void SetUp() override {
77 RenderViewHostImplTestHarness::SetUp();
clamy1d4e78fd2017-07-11 12:59:1978 CreateNavigationHandle();
Dave Tapuska327c06c92022-06-13 20:31:5179 contents()->GetPrimaryMainFrame()->InitializeRenderFrameIfNeeded();
clamy49678312015-10-22 21:59:0080 }
81
82 void TearDown() override {
clamy49678312015-10-22 21:59:0083 RenderViewHostImplTestHarness::TearDown();
84 }
85
Charles Harrison4f2bf1a2017-07-18 20:21:2186 void CancelDeferredNavigation(
87 NavigationThrottle::ThrottleCheckResult result) {
Hiroki Nakagawaadcffc502021-06-16 10:47:5188 GetNavigationRequest()->CancelDeferredNavigationInternal(result);
Charles Harrison4f2bf1a2017-07-18 20:21:2189 }
90
clamy49678312015-10-22 21:59:0091 // Helper function to call WillStartRequest on |handle|. If this function
92 // returns DEFER, |callback_result_| will be set to the actual result of
93 // the throttle checks when they are finished.
94 void SimulateWillStartRequest() {
95 was_callback_called_ = false;
96 callback_result_ = NavigationThrottle::DEFER;
97
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:4498 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4399 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51100 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18101 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
102 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44103
Hiroki Nakagawaadcffc502021-06-16 10:47:51104 GetNavigationRequest()->WillStartRequest();
clamy49678312015-10-22 21:59:00105 }
106
107 // Helper function to call WillRedirectRequest on |handle|. If this function
108 // returns DEFER, |callback_result_| will be set to the actual result of the
109 // throttle checks when they are finished.
clamye88533842015-11-18 12:48:57110 // TODO(clamy): this should also simulate that WillStartRequest was called if
111 // it has not been called before.
clamy49678312015-10-22 21:59:00112 void SimulateWillRedirectRequest() {
113 was_callback_called_ = false;
114 callback_result_ = NavigationThrottle::DEFER;
115
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44116 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43117 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51118 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18119 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
120 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44121
Hiroki Nakagawaadcffc502021-06-16 10:47:51122 GetNavigationRequest()->WillRedirectRequest(
Arthur Hemery3a991c092021-12-22 12:04:24123 GURL(), nullptr /* post_redirect_process */);
clamy49678312015-10-22 21:59:00124 }
125
Lucas Garron0cedd962017-10-17 07:23:33126 // Helper function to call WillFailRequest on |handle|. If this function
127 // returns DEFER, |callback_result_| will be set to the actual result of the
128 // throttle checks when they are finished.
Lucas Garronc1edb5ab2017-11-08 03:31:13129 void SimulateWillFailRequest(
130 net::Error net_error_code,
Anton Bikineevf62d1bf2021-05-15 17:56:07131 const absl::optional<net::SSLInfo> ssl_info = absl::nullopt) {
Lucas Garron0cedd962017-10-17 07:23:33132 was_callback_called_ = false;
133 callback_result_ = NavigationThrottle::DEFER;
Hiroki Nakagawaadcffc502021-06-16 10:47:51134 GetNavigationRequest()->set_net_error(net_error_code);
Lucas Garron0cedd962017-10-17 07:23:33135
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44136 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43137 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51138 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18139 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
140 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44141
Hiroki Nakagawaadcffc502021-06-16 10:47:51142 GetNavigationRequest()->WillFailRequest();
Lucas Garron0cedd962017-10-17 07:23:33143 }
144
clamy49678312015-10-22 21:59:00145 // Whether the callback was called.
146 bool was_callback_called() const { return was_callback_called_; }
147
148 // Returns the callback_result.
149 NavigationThrottle::ThrottleCheckResult callback_result() const {
150 return callback_result_;
151 }
152
Hiroki Nakagawaadcffc502021-06-16 10:47:51153 NavigationRequest::NavigationState state() {
154 return GetNavigationRequest()->state();
155 }
Mohamed Abdelhalimccd149af2019-10-31 14:48:53156
Lucas Garron0cedd962017-10-17 07:23:33157 bool call_counts_match(TestNavigationThrottle* throttle,
158 int start,
159 int redirect,
160 int failure,
161 int process) {
162 return start == throttle->GetCallCount(
163 TestNavigationThrottle::WILL_START_REQUEST) &&
164 redirect == throttle->GetCallCount(
165 TestNavigationThrottle::WILL_REDIRECT_REQUEST) &&
166 failure == throttle->GetCallCount(
167 TestNavigationThrottle::WILL_FAIL_REQUEST) &&
168 process == throttle->GetCallCount(
169 TestNavigationThrottle::WILL_PROCESS_RESPONSE);
170 }
171
172 // Creates, register and returns a TestNavigationThrottle that will
173 // synchronously return |result| on checks by default.
clamy49678312015-10-22 21:59:00174 TestNavigationThrottle* CreateTestNavigationThrottle(
175 NavigationThrottle::ThrottleCheckResult result) {
176 TestNavigationThrottle* test_throttle =
Hiroki Nakagawaadcffc502021-06-16 10:47:51177 new TestNavigationThrottle(GetNavigationRequest());
Lucas Garron79e1a972017-10-04 22:25:06178 test_throttle->SetResponseForAllMethods(TestNavigationThrottle::SYNCHRONOUS,
179 result);
Hiroki Nakagawaadcffc502021-06-16 10:47:51180 GetNavigationRequest()->RegisterThrottleForTesting(
dcheng9bfa5162016-04-09 01:00:57181 std::unique_ptr<TestNavigationThrottle>(test_throttle));
clamy49678312015-10-22 21:59:00182 return test_throttle;
183 }
184
Lucas Garron0cedd962017-10-17 07:23:33185 // Creates, register and returns a TestNavigationThrottle that will
186 // synchronously return |result| on check for the given |method|, and
187 // NavigationThrottle::PROCEED otherwise.
188 TestNavigationThrottle* CreateTestNavigationThrottle(
189 TestNavigationThrottle::ThrottleMethod method,
190 NavigationThrottle::ThrottleCheckResult result) {
191 TestNavigationThrottle* test_throttle =
192 CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
193 test_throttle->SetResponse(method, TestNavigationThrottle::SYNCHRONOUS,
194 result);
195 return test_throttle;
196 }
197
Mohamed Abdelhalim9ef43fc2019-04-05 13:09:43198 // TODO(zetamoo): Use NavigationSimulator instead of creating
199 // NavigationRequest and NavigationHandleImpl.
clamy1d4e78fd2017-07-11 12:59:19200 void CreateNavigationHandle() {
Minggang Wanga13c796e2021-07-02 05:54:43201 auto common_params = blink::CreateCommonNavigationParams();
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51202 common_params->initiator_origin =
Lukasz Anforowicz435bcb582019-07-12 20:50:06203 url::Origin::Create(GURL("https://initiator.example.com"));
Minggang Wanga13c796e2021-07-02 05:54:43204 auto commit_params = blink::CreateCommitNavigationParams();
arthursonzogni70ac7302020-05-28 08:49:05205 commit_params->frame_policy =
206 main_test_rfh()->frame_tree_node()->pending_frame_policy();
Hiroki Nakagawaadcffc502021-06-16 10:47:51207 auto request = NavigationRequest::CreateBrowserInitiated(
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51208 main_test_rfh()->frame_tree_node(), std::move(common_params),
arthursonzogni70ac7302020-05-28 08:49:05209 std::move(commit_params), false /* browser-initiated */,
Takashi Toyoshimae87b7be2021-01-22 11:51:08210 false /* was_opener_suppressed */, nullptr /* initiator_frame_token */,
Antonio Sartori9a82f6f32020-12-14 09:22:45211 ChildProcessHost::kInvalidUniqueID /* initiator_process_id */,
John Delaney50425f82020-04-07 16:26:21212 std::string() /* extra_headers */, nullptr /* frame_entry */,
jongdeok.kim5de823b32022-06-14 04:37:50213 nullptr /* entry */, false /* is_form_submission */,
Daniel Hosseinianf0fbfb42021-09-08 02:20:47214 nullptr /* navigation_ui_data */, absl::nullopt /* impression */,
215 false /* is_pdf */);
Hiroki Nakagawaadcffc502021-06-16 10:47:51216 main_test_rfh()->frame_tree_node()->CreatedNavigationRequest(
217 std::move(request));
218 GetNavigationRequest()->StartNavigation();
clamy1d4e78fd2017-07-11 12:59:19219 }
220
Yao Xiao6e1f7d32022-01-07 03:28:40221 FrameTreeNode* AddFrame(FrameTree& frame_tree,
222 RenderFrameHostImpl* parent,
223 int process_id,
224 int new_routing_id,
225 const blink::FramePolicy& frame_policy,
226 blink::FrameOwnerElementType owner_type) {
227 return frame_tree.AddFrame(
228 parent, process_id, new_routing_id,
229 TestRenderFrameHost::CreateStubFrameRemote(),
230 TestRenderFrameHost::CreateStubBrowserInterfaceBrokerReceiver(),
231 TestRenderFrameHost::CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49232 TestRenderFrameHost::CreateStubAssociatedInterfaceProviderReceiver(),
Yao Xiao6e1f7d32022-01-07 03:28:40233 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
234 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
235 frame_policy, blink::mojom::FrameOwnerProperties(), false, owner_type,
236 /*is_dummy_frame_for_inner_tree=*/false);
237 }
238
clamy49678312015-10-22 21:59:00239 private:
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31240 // The callback provided to NavigationRequest::WillStartRequest,
241 // NavigationRequest::WillRedirectRequest, and
242 // NavigationRequest::WillFailRequest during the tests.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44243 bool UpdateThrottleCheckResult(
clamy49678312015-10-22 21:59:00244 NavigationThrottle::ThrottleCheckResult result) {
245 callback_result_ = result;
246 was_callback_called_ = true;
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44247 return true;
clamy49678312015-10-22 21:59:00248 }
249
Hiroki Nakagawaadcffc502021-06-16 10:47:51250 // This must be called after CreateNavigationHandle().
251 NavigationRequest* GetNavigationRequest() {
252 return main_test_rfh()->frame_tree_node()->navigation_request();
253 }
254
Fergal Dalya1d569972021-03-16 03:24:53255 bool was_callback_called_ = false;
clamy49678312015-10-22 21:59:00256 NavigationThrottle::ThrottleCheckResult callback_result_;
257};
258
carlosk489d9e22016-07-25 14:25:43259// Checks that the request_context_type is properly set.
260// Note: can be extended to cover more internal members.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43261TEST_F(NavigationRequestTest, SimpleDataChecksRedirectAndProcess) {
Camille Lamy62b826012019-02-26 09:15:47262 const GURL kUrl1 = GURL("http://chromium.org");
263 const GURL kUrl2 = GURL("http://google.com");
264 auto navigation =
265 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
266 navigation->Start();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40267 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05268 NavigationRequest::From(navigation->GetNavigationHandle())
269 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11270 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47271 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43272
Camille Lamy62b826012019-02-26 09:15:47273 navigation->set_http_connection_info(
274 net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1);
275 navigation->Redirect(kUrl2);
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40276 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05277 NavigationRequest::From(navigation->GetNavigationHandle())
278 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11279 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
Camille Lamy62b826012019-02-26 09:15:47280 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43281
Camille Lamy62b826012019-02-26 09:15:47282 navigation->set_http_connection_info(
283 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
284 navigation->ReadyToCommit();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40285 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05286 NavigationRequest::From(navigation->GetNavigationHandle())
287 ->request_context_type());
bnc90be5dd782016-11-09 16:28:44288 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47289 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11290}
291
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43292TEST_F(NavigationRequestTest, SimpleDataCheckNoRedirect) {
Camille Lamy62b826012019-02-26 09:15:47293 const GURL kUrl = GURL("http://chromium.org");
294 auto navigation =
295 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
296 navigation->Start();
jkarlinbb150112016-11-02 17:55:11297 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47298 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11299
Camille Lamy62b826012019-02-26 09:15:47300 navigation->set_http_connection_info(
301 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
302 navigation->ReadyToCommit();
bnc90be5dd782016-11-09 16:28:44303 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47304 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43305}
306
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43307TEST_F(NavigationRequestTest, SimpleDataChecksFailure) {
Camille Lamy62b826012019-02-26 09:15:47308 const GURL kUrl = GURL("http://chromium.org");
309 auto navigation =
310 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
311 navigation->Start();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40312 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05313 NavigationRequest::From(navigation->GetNavigationHandle())
314 ->request_context_type());
Lucas Garron0cedd962017-10-17 07:23:33315 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47316 navigation->GetNavigationHandle()->GetConnectionInfo());
Lucas Garron0cedd962017-10-17 07:23:33317
Camille Lamy62b826012019-02-26 09:15:47318 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40319 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05320 NavigationRequest::From(navigation->GetNavigationHandle())
321 ->request_context_type());
Camille Lamy62b826012019-02-26 09:15:47322 EXPECT_EQ(net::ERR_CERT_DATE_INVALID,
323 navigation->GetNavigationHandle()->GetNetErrorCode());
Lucas Garron0cedd962017-10-17 07:23:33324}
325
Yao Xiao6e1f7d32022-01-07 03:28:40326TEST_F(NavigationRequestTest, FencedFrameNavigationToPendingMappedURN) {
327 // Note that we only run this test for the ShadowDOM implementation of fenced
328 // frames, due to how they add subframes in a way that is very specific to the
329 // ShadowDOM implementation, and not suitable for the MPArch implementation.
330 base::test::ScopedFeatureList scoped_feature_list;
331 scoped_feature_list.InitAndEnableFeatureWithParameters(
332 blink::features::kFencedFrames, {{"implementation_type", "shadow_dom"}});
333
334 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
335 FrameTreeNode* root = frame_tree.root();
336 int process_id = root->current_frame_host()->GetProcess()->GetID();
337
338 // Add a fenced frame.
339 constexpr auto kFencedframeOwnerType =
340 blink::FrameOwnerElementType::kFencedframe;
341 blink::FramePolicy policy;
342 policy.is_fenced = true;
343 AddFrame(frame_tree, root->current_frame_host(), process_id, 15, policy,
344 kFencedframeOwnerType);
345
346 FrameTreeNode* fenced_frame_tree_node = root->child_at(0);
347 EXPECT_TRUE(fenced_frame_tree_node->IsFencedFrameRoot());
348 EXPECT_TRUE(fenced_frame_tree_node->IsInFencedFrameTree());
349
350 FencedFrameURLMapping& fenced_frame_urls_map =
351 main_test_rfh()->GetPage().fenced_frame_urls_map();
352
353 const GURL urn_uuid = fenced_frame_urls_map.GeneratePendingMappedURN();
Dominic Farolinoe724b5332022-04-26 05:00:06354 const GURL mapped_url = GURL("https://chromium.org");
Yao Xiao6e1f7d32022-01-07 03:28:40355
356 auto navigation_simulator = NavigationSimulatorImpl::CreateRendererInitiated(
357 urn_uuid, fenced_frame_tree_node->current_frame_host());
358
359 auto response_headers =
360 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
361 response_headers->SetHeader("Supports-Loading-Mode", "fenced-frame");
362
363 navigation_simulator->SetAutoAdvance(false);
364 navigation_simulator->SetResponseHeaders(response_headers);
365 navigation_simulator->SetTransition(ui::PAGE_TRANSITION_AUTO_SUBFRAME);
366
367 navigation_simulator->Start();
368
369 EXPECT_EQ(navigation_simulator->GetNavigationHandle()->GetURL(), urn_uuid);
370
Yao Xiao1099e4c2022-03-24 22:40:37371 SimulateSharedStorageURNMappingComplete(
372 fenced_frame_urls_map, urn_uuid, mapped_url,
373 /*shared_storage_origin=*/url::Origin::Create(GURL("https://bar.com")),
374 /*budget_to_charge=*/2.0);
Yao Xiao6e1f7d32022-01-07 03:28:40375
376 // Expect that the url in the NavigationRequest is already mapped.
377 EXPECT_EQ(navigation_simulator->GetNavigationHandle()->GetURL(), mapped_url);
378
379 navigation_simulator->Wait();
380
381 navigation_simulator->SetAutoAdvance(true);
382 navigation_simulator->ReadyToCommit();
383 navigation_simulator->Commit();
384
385 EXPECT_EQ(fenced_frame_tree_node->current_url(), mapped_url);
386}
387
clamye88533842015-11-18 12:48:57388// Checks that a navigation deferred during WillStartRequest can be properly
389// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53390TEST_F(NavigationRequestTest, CancelDeferredWillStart) {
clamye88533842015-11-18 12:48:57391 TestNavigationThrottle* test_throttle =
392 CreateTestNavigationThrottle(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));
clamye88533842015-11-18 12:48:57395
396 // Simulate WillStartRequest. The request should be deferred. The callback
397 // should not have been called.
398 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19399 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
clamye88533842015-11-18 12:48:57400 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33401 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57402
403 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21404 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19405 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57406 EXPECT_TRUE(was_callback_called());
407 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33408 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57409}
410
411// Checks that a navigation deferred during WillRedirectRequest can be properly
412// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53413TEST_F(NavigationRequestTest, CancelDeferredWillRedirect) {
clamye88533842015-11-18 12:48:57414 TestNavigationThrottle* test_throttle =
415 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19416 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33417 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57418
419 // Simulate WillRedirectRequest. The request should be deferred. The callback
420 // should not have been called.
421 SimulateWillRedirectRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19422 EXPECT_EQ(NavigationRequest::WILL_REDIRECT_REQUEST, state());
clamye88533842015-11-18 12:48:57423 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33424 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
clamye88533842015-11-18 12:48:57425
426 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21427 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19428 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57429 EXPECT_TRUE(was_callback_called());
430 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33431 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
432}
433
434// Checks that a navigation deferred during WillFailRequest can be properly
435// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53436TEST_F(NavigationRequestTest, CancelDeferredWillFail) {
Lucas Garron0cedd962017-10-17 07:23:33437 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
438 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19439 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33440 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
441
442 // Simulate WillStartRequest.
443 SimulateWillStartRequest();
444 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
445
446 // Simulate WillFailRequest. The request should be deferred. The callback
447 // should not have been called.
448 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19449 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33450 EXPECT_FALSE(was_callback_called());
451 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
452
453 // Cancel the request. The callback should have been called.
454 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19455 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33456 EXPECT_TRUE(was_callback_called());
457 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
458 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
clamye88533842015-11-18 12:48:57459}
460
461// Checks that a navigation deferred can be canceled and not ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53462TEST_F(NavigationRequestTest, CancelDeferredWillRedirectNoIgnore) {
clamye88533842015-11-18 12:48:57463 TestNavigationThrottle* test_throttle =
464 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19465 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33466 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57467
Lucas Garron0cedd962017-10-17 07:23:33468 // Simulate WillStartRequest. The request should be deferred. The callback
clamye88533842015-11-18 12:48:57469 // should not have been called.
470 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19471 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33472 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57473
474 // Cancel the request. The callback should have been called with CANCEL, and
475 // not CANCEL_AND_IGNORE.
Charles Harrison4f2bf1a2017-07-18 20:21:21476 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19477 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57478 EXPECT_TRUE(was_callback_called());
479 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33480 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57481}
482
Lucas Garron0cedd962017-10-17 07:23:33483// Checks that a navigation deferred by WillFailRequest can be canceled and not
484// ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53485TEST_F(NavigationRequestTest, CancelDeferredWillFailNoIgnore) {
Lucas Garron0cedd962017-10-17 07:23:33486 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
487 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19488 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33489 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
490
491 // Simulate WillStartRequest.
492 SimulateWillStartRequest();
493 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
494
495 // Simulate WillFailRequest. The request should be deferred. The callback
496 // should not have been called.
497 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19498 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33499 EXPECT_FALSE(was_callback_called());
500 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
501
502 // Cancel the request. The callback should have been called with CANCEL, and
503 // not CANCEL_AND_IGNORE.
504 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19505 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33506 EXPECT_TRUE(was_callback_called());
507 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
508 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
509}
510
Lucas Garronc1edb5ab2017-11-08 03:31:13511// Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
John Abd-El-Malekf36e05f2017-11-30 16:17:52512// stored on the handle.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43513TEST_F(NavigationRequestTest, WillFailRequestSetsSSLInfo) {
Lucas Garronc1edb5ab2017-11-08 03:31:13514 uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
515 int connection_status = 0;
516 net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
517
518 // Set some test values.
519 net::SSLInfo ssl_info;
520 ssl_info.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
521 ssl_info.connection_status = connection_status;
522
Camille Lamy62b826012019-02-26 09:15:47523 const GURL kUrl = GURL("https://chromium.org");
524 auto navigation =
525 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
Emily Starkfd6978ad12019-04-30 21:20:07526 navigation->SetSSLInfo(ssl_info);
Camille Lamy62b826012019-02-26 09:15:47527 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Lucas Garronc1edb5ab2017-11-08 03:31:13528
529 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID,
Camille Lamy62b826012019-02-26 09:15:47530 navigation->GetNavigationHandle()->GetSSLInfo()->cert_status);
531 EXPECT_EQ(connection_status,
532 navigation->GetNavigationHandle()->GetSSLInfo()->connection_status);
Lucas Garronc1edb5ab2017-11-08 03:31:13533}
534
Camille Lamy62b826012019-02-26 09:15:47535namespace {
536
Alex Moshchuk1a66b1d2018-05-15 21:18:26537// Helper throttle which checks that it can access NavigationHandle's
538// RenderFrameHost in WillFailRequest() and then defers the failure.
539class GetRenderFrameHostOnFailureNavigationThrottle
540 : public NavigationThrottle {
541 public:
Fergal Dalya1d569972021-03-16 03:24:53542 explicit GetRenderFrameHostOnFailureNavigationThrottle(
543 NavigationHandle* handle)
Alex Moshchuk1a66b1d2018-05-15 21:18:26544 : NavigationThrottle(handle) {}
Peter Boström828b9022021-09-21 02:28:43545
546 GetRenderFrameHostOnFailureNavigationThrottle(
547 const GetRenderFrameHostOnFailureNavigationThrottle&) = delete;
548 GetRenderFrameHostOnFailureNavigationThrottle& operator=(
549 const GetRenderFrameHostOnFailureNavigationThrottle&) = delete;
550
Fergal Dalya1d569972021-03-16 03:24:53551 ~GetRenderFrameHostOnFailureNavigationThrottle() override = default;
Alex Moshchuk1a66b1d2018-05-15 21:18:26552
553 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
554 EXPECT_TRUE(navigation_handle()->GetRenderFrameHost());
555 return NavigationThrottle::DEFER;
556 }
557
558 const char* GetNameForLogging() override {
559 return "GetRenderFrameHostOnFailureNavigationThrottle";
560 }
Alex Moshchuk1a66b1d2018-05-15 21:18:26561};
562
Camille Lamy62b826012019-02-26 09:15:47563class ThrottleTestContentBrowserClient : public ContentBrowserClient {
564 std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation(
565 NavigationHandle* navigation_handle) override {
566 std::vector<std::unique_ptr<NavigationThrottle>> throttle;
567 throttle.push_back(
568 std::make_unique<GetRenderFrameHostOnFailureNavigationThrottle>(
569 navigation_handle));
570 return throttle;
571 }
572};
573
574} // namespace
575
Alex Moshchuk1a66b1d2018-05-15 21:18:26576// Verify that the NavigationHandle::GetRenderFrameHost() can be retrieved by a
577// throttle in WillFailRequest(), as well as after deferring the failure. This
578// is allowed, since at that point the final RenderFrameHost will have already
579// been chosen. See https://crbug.com/817881.
Mohamed Abdelhalimba020672019-10-31 16:18:53580TEST_F(NavigationRequestTest, WillFailRequestCanAccessRenderFrameHost) {
Camille Lamy62b826012019-02-26 09:15:47581 std::unique_ptr<ContentBrowserClient> client(
582 new ThrottleTestContentBrowserClient);
583 ContentBrowserClient* old_browser_client =
584 SetBrowserClientForTesting(client.get());
585
586 const GURL kUrl = GURL("http://chromium.org");
587 auto navigation =
588 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
589 navigation->SetAutoAdvance(false);
590 navigation->Start();
591 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalim3b235272019-11-05 15:06:07592 EXPECT_EQ(
593 NavigationRequest::WILL_FAIL_REQUEST,
594 NavigationRequest::From(navigation->GetNavigationHandle())->state());
Camille Lamy62b826012019-02-26 09:15:47595 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
Mohamed Abdelhalim40c35d22019-09-19 15:59:05596 NavigationRequest::From(navigation->GetNavigationHandle())
danakjf26536bf2020-09-10 00:46:13597 ->GetNavigationThrottleRunnerForTesting()
Mohamed Abdelhalim40c35d22019-09-19 15:59:05598 ->CallResumeForTesting();
Camille Lamy62b826012019-02-26 09:15:47599 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
600
601 SetBrowserClientForTesting(old_browser_client);
Alex Moshchuk1a66b1d2018-05-15 21:18:26602}
603
Antonio Sartori3cfa3b62020-10-09 10:42:40604TEST_F(NavigationRequestTest, PolicyContainerInheritance) {
605 struct TestCase {
606 const char* url;
607 bool expect_inherit;
608 } cases[]{{"about:blank", true},
609 {"data:text/plain,hello", true},
610 {"file://local", false},
611 {"http://chromium.org", false}};
612
613 const GURL kUrl1 = GURL("http://chromium.org");
614 auto navigation =
615 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
616 navigation->Commit();
617
618 for (auto test : cases) {
619 // We navigate child frames because the BlockedSchemeNavigationThrottle
620 // restricts navigations in the main frame.
621 auto* child_frame = static_cast<TestRenderFrameHost*>(
622 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child"));
623
624 // We set the referrer policy of the frame to "always". We then create a new
625 // navigation, set as initiator the frame itself, start the navigation, and
626 // change the referrer policy of the frame to "never". After we commit the
627 // navigation:
628 // - If navigating to a local scheme, the target frame should have inherited
629 // the referrer policy of the initiator ("always").
630 // - If navigating to a non-local scheme, the target frame should have a new
631 // policy container (hence referrer policy set to "default").
632 const GURL kUrl = GURL(test.url);
Peter Kastingeb8c3ce2021-08-20 04:39:35633 navigation =
Antonio Sartori3cfa3b62020-10-09 10:42:40634 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_frame);
Antonio Sartori5b2f8042020-10-23 18:13:26635 static_cast<blink::mojom::PolicyContainerHost*>(
Antonio Sartori9290b6b2020-11-09 10:09:33636 child_frame->policy_container_host())
Antonio Sartori5b2f8042020-10-23 18:13:26637 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kAlways);
Antonio Sartori3cfa3b62020-10-09 10:42:40638 navigation->SetInitiatorFrame(child_frame);
639 navigation->Start();
Antonio Sartori5b2f8042020-10-23 18:13:26640 static_cast<blink::mojom::PolicyContainerHost*>(
Antonio Sartori9290b6b2020-11-09 10:09:33641 child_frame->policy_container_host())
Antonio Sartori5b2f8042020-10-23 18:13:26642 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
Antonio Sartori3cfa3b62020-10-09 10:42:40643 navigation->Commit();
644 EXPECT_EQ(
645 test.expect_inherit ? network::mojom::ReferrerPolicy::kAlways
646 : network::mojom::ReferrerPolicy::kDefault,
647 static_cast<RenderFrameHostImpl*>(navigation->GetFinalRenderFrameHost())
Antonio Sartori9290b6b2020-11-09 10:09:33648 ->policy_container_host()
Antonio Sartori3cfa3b62020-10-09 10:42:40649 ->referrer_policy());
650 }
651}
652
Cammie Smith Barnesa0da2cf2021-01-11 22:09:37653TEST_F(NavigationRequestTest, DnsAliasesCanBeAccessed) {
654 // Create simulated NavigationRequest for the URL, which has aliases.
655 const GURL kUrl = GURL("http://chromium.org");
656 auto navigation =
657 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
658 std::vector<std::string> dns_aliases({"alias1", "alias2"});
659 navigation->SetResponseDnsAliases(std::move(dns_aliases));
660
661 // Start the navigation.
662 navigation->Start();
663 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
664 navigation->GetNavigationHandle()->GetConnectionInfo());
665
666 // Commit the navigation.
667 navigation->set_http_connection_info(
668 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
669 navigation->ReadyToCommit();
670 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
671 navigation->GetNavigationHandle()->GetConnectionInfo());
672
673 // Verify that the aliases are accessible from the NavigationRequest.
674 EXPECT_THAT(navigation->GetNavigationHandle()->GetDnsAliases(),
675 testing::ElementsAre("alias1", "alias2"));
676}
677
678TEST_F(NavigationRequestTest, NoDnsAliases) {
679 // Create simulated NavigationRequest for the URL, which does not
680 // have aliases. (Note the empty alias list.)
681 const GURL kUrl = GURL("http://chromium.org");
682 auto navigation =
683 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
684 std::vector<std::string> dns_aliases;
685 navigation->SetResponseDnsAliases(std::move(dns_aliases));
686
687 // Start the navigation.
688 navigation->Start();
689 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
690 navigation->GetNavigationHandle()->GetConnectionInfo());
691
692 // Commit the navigation.
693 navigation->set_http_connection_info(
694 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
695 navigation->ReadyToCommit();
696 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
697 navigation->GetNavigationHandle()->GetConnectionInfo());
698
699 // Verify that there are no aliases in the NavigationRequest.
700 EXPECT_TRUE(navigation->GetNavigationHandle()->GetDnsAliases().empty());
701}
702
Antonio Sartori3e8de6d2021-07-26 10:28:41703TEST_F(NavigationRequestTest, StorageKeyToCommit) {
704 TestRenderFrameHost* child_document = static_cast<TestRenderFrameHost*>(
705 content::RenderFrameHostTester::For(main_rfh())->AppendChild(""));
Yuzu Saijo03dbf9b2022-07-22 04:29:45706 auto attributes = child_document->frame_tree_node()->attributes_->Clone();
707 // Set |anonymous| to true.
708 attributes->anonymous = true;
709 child_document->frame_tree_node()->SetAttributes(std::move(attributes));
Antonio Sartori3e8de6d2021-07-26 10:28:41710
711 const GURL kUrl = GURL("http://chromium.org");
712 auto navigation =
713 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_document);
714 navigation->ReadyToCommit();
715 NavigationRequest* request =
716 NavigationRequest::From(navigation->GetNavigationHandle());
717 EXPECT_TRUE(request->commit_params().storage_key.nonce().has_value());
Ali Hijazi78de14c2022-07-21 11:32:19718 EXPECT_EQ(child_document->GetMainFrame()->anonymous_iframes_nonce(),
Antonio Sartori3e8de6d2021-07-26 10:28:41719 request->commit_params().storage_key.nonce().value());
720
721 navigation->Commit();
722 child_document =
723 static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost());
Arthur Sonzognie41678a2022-06-16 15:51:19724 EXPECT_TRUE(child_document->IsAnonymous());
Ali Hijazi78de14c2022-07-21 11:32:19725 EXPECT_EQ(blink::StorageKey::CreateWithNonce(
726 url::Origin::Create(kUrl),
727 child_document->GetMainFrame()->anonymous_iframes_nonce()),
728 child_document->storage_key());
Antonio Sartori3e8de6d2021-07-26 10:28:41729}
730
Antonio Sartoribf27cc442021-08-25 13:08:23731TEST_F(NavigationRequestTest,
732 NavigationToAnonymousDocumentNetworkIsolationInfo) {
733 auto* child_frame = static_cast<TestRenderFrameHost*>(
734 content::RenderFrameHostTester::For(main_test_rfh())
735 ->AppendChild("child"));
Yuzu Saijo03dbf9b2022-07-22 04:29:45736 auto attributes = child_frame->frame_tree_node()->attributes_->Clone();
737 // Set |anonymous| to true.
738 attributes->anonymous = true;
739 child_frame->frame_tree_node()->SetAttributes(std::move(attributes));
Antonio Sartoribf27cc442021-08-25 13:08:23740
741 std::unique_ptr<NavigationSimulator> navigation =
742 NavigationSimulator::CreateRendererInitiated(
743 GURL("https://example.com/navigation.html"), child_frame);
744 navigation->ReadyToCommit();
745
Ali Hijazi78de14c2022-07-21 11:32:19746 EXPECT_EQ(main_test_rfh()->anonymous_iframes_nonce(),
Antonio Sartoribf27cc442021-08-25 13:08:23747 static_cast<NavigationRequest*>(navigation->GetNavigationHandle())
748 ->isolation_info_for_subresources()
749 .network_isolation_key()
750 .GetNonce());
Ali Hijazi78de14c2022-07-21 11:32:19751 EXPECT_EQ(main_test_rfh()->anonymous_iframes_nonce(),
Antonio Sartoribf27cc442021-08-25 13:08:23752 static_cast<NavigationRequest*>(navigation->GetNavigationHandle())
753 ->GetIsolationInfo()
754 .network_isolation_key()
755 .GetNonce());
756}
757
Robbie McElrath5641d572022-05-20 17:15:29758class ScopedIsolatedAppBrowserClient : public ContentBrowserClient {
759 public:
760 ScopedIsolatedAppBrowserClient()
761 : old_client_(SetBrowserClientForTesting(this)) {}
762
763 ~ScopedIsolatedAppBrowserClient() override {
764 SetBrowserClientForTesting(old_client_);
765 }
766
767 bool ShouldUrlUseApplicationIsolationLevel(BrowserContext* browser_context,
768 const GURL& url) override {
769 return true;
770 }
771
772 private:
773 raw_ptr<ContentBrowserClient> old_client_;
774};
775
776TEST_F(NavigationRequestTest, IsolatedAppPolicyInjection) {
777 const GURL kUrl = GURL("https://chromium.org");
778 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
779 switches::kIsolatedAppOrigins, kUrl.spec());
780 // Disable flag caching so the --isolated-app-origins value takes effect.
781 SiteIsolationPolicy::DisableFlagCachingForTesting();
782 ScopedIsolatedAppBrowserClient client;
783
784 auto navigation =
785 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
786 navigation->ReadyToCommit();
787
788 // Validate the COOP/COEP headers.
789 const PolicyContainerPolicies& policies =
790 navigation->GetNavigationHandle()->GetPolicyContainerPolicies();
791 EXPECT_EQ(network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep,
792 policies.cross_origin_opener_policy.value);
793 EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp,
794 policies.cross_origin_embedder_policy.value);
795
796 // Validate CSP.
797 EXPECT_EQ(1UL, policies.content_security_policies.size());
798 const auto& csp = policies.content_security_policies[0];
Robbie McElrathb062f3d2022-08-09 17:48:44799 EXPECT_EQ(7UL, csp->raw_directives.size());
Robbie McElrath5641d572022-05-20 17:15:29800 using Directive = network::mojom::CSPDirectiveName;
801 EXPECT_EQ("'none'", csp->raw_directives[Directive::BaseURI]);
802 EXPECT_EQ("'none'", csp->raw_directives[Directive::ObjectSrc]);
803 EXPECT_EQ("'self'", csp->raw_directives[Directive::DefaultSrc]);
804 EXPECT_EQ("'self' https:", csp->raw_directives[Directive::FrameSrc]);
805 EXPECT_EQ("'self' https:", csp->raw_directives[Directive::ConnectSrc]);
Robbie McElrathb062f3d2022-08-09 17:48:44806 EXPECT_EQ("'self' 'wasm-unsafe-eval'",
807 csp->raw_directives[Directive::ScriptSrc]);
Robbie McElrath5641d572022-05-20 17:15:29808 EXPECT_EQ("'script'", csp->raw_directives[Directive::RequireTrustedTypesFor]);
809}
810
arthursonzogni898dcda52021-01-21 08:50:10811// Test that the required CSP of every frame is computed/inherited correctly and
812// that the Sec-Required-CSP header is set.
813class CSPEmbeddedEnforcementUnitTest : public NavigationRequestTest {
814 protected:
815 TestRenderFrameHost* main_rfh() {
816 return static_cast<TestRenderFrameHost*>(NavigationRequestTest::main_rfh());
817 }
818
819 // Simulate the |csp| attribute being set in |rfh|'s frame. Then navigate it.
820 // Returns the request's Sec-Required-CSP header.
821 std::string NavigateWithRequiredCSP(TestRenderFrameHost** rfh,
822 std::string required_csp) {
823 TestRenderFrameHost* document = *rfh;
824
825 if (!required_csp.empty()) {
826 auto headers =
827 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
828 headers->SetHeader("Content-Security-Policy", required_csp);
829 std::vector<network::mojom::ContentSecurityPolicyPtr> policies;
830 network::AddContentSecurityPolicyFromHeaders(
831 *headers, GURL("https://example.com/"), &policies);
Yuzu Saijo03dbf9b2022-07-22 04:29:45832 auto attributes = document->frame_tree_node()->attributes_->Clone();
833 // Set csp value.
834 attributes->parsed_csp_attribute = std::move(policies[0]);
835 document->frame_tree_node()->SetAttributes(std::move(attributes));
arthursonzogni898dcda52021-01-21 08:50:10836 }
837
838 // Chrome blocks a document navigating to a URL if more than one of its
839 // ancestors have the same URL. Use a different URL every time, to
840 // avoid blocking navigation of the grandchild frame.
841 static int nonce = 0;
842 GURL url("https://www.example.com" + base::NumberToString(nonce++));
843
844 auto navigation =
845 content::NavigationSimulator::CreateRendererInitiated(url, *rfh);
846 navigation->Start();
847 NavigationRequest* request =
848 NavigationRequest::From(navigation->GetNavigationHandle());
849 std::string sec_required_csp;
850 request->GetRequestHeaders().GetHeader("sec-required-csp",
851 &sec_required_csp);
852
853 // Complete the navigation so that the required csp is stored in the
854 // RenderFrameHost, so that when we will add children to this document they
855 // will be able to get the parent's required csp (and hence also test that
856 // the whole logic works).
857 auto response_headers =
858 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
859 response_headers->SetHeader("Allow-CSP-From", "*");
860 navigation->SetResponseHeaders(response_headers);
861 navigation->Commit();
862
863 *rfh = static_cast<TestRenderFrameHost*>(
864 navigation->GetFinalRenderFrameHost());
865
866 return sec_required_csp;
867 }
868
869 TestRenderFrameHost* AddChild(TestRenderFrameHost* parent) {
870 return static_cast<TestRenderFrameHost*>(
871 content::RenderFrameHostTester::For(parent)->AppendChild(""));
872 }
873};
874
875TEST_F(CSPEmbeddedEnforcementUnitTest, TopLevel) {
876 TestRenderFrameHost* top_document = main_rfh();
877 std::string sec_required_csp = NavigateWithRequiredCSP(&top_document, "");
878 EXPECT_EQ("", sec_required_csp);
879 EXPECT_FALSE(top_document->required_csp());
880}
881
882TEST_F(CSPEmbeddedEnforcementUnitTest, ChildNoCSP) {
883 TestRenderFrameHost* top_document = main_rfh();
884 TestRenderFrameHost* child_document = AddChild(top_document);
885 std::string sec_required_csp = NavigateWithRequiredCSP(&child_document, "");
886 EXPECT_EQ("", sec_required_csp);
887 EXPECT_FALSE(child_document->required_csp());
888}
889
890TEST_F(CSPEmbeddedEnforcementUnitTest, ChildWithCSP) {
891 TestRenderFrameHost* top_document = main_rfh();
892 TestRenderFrameHost* child_document = AddChild(top_document);
893 std::string sec_required_csp =
894 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
895 EXPECT_EQ("script-src 'none'", sec_required_csp);
896 EXPECT_TRUE(child_document->required_csp());
897 EXPECT_EQ("script-src 'none'",
898 child_document->required_csp()->header->header_value);
899}
900
901TEST_F(CSPEmbeddedEnforcementUnitTest, ChildSiblingNoCSP) {
902 TestRenderFrameHost* top_document = main_rfh();
903 TestRenderFrameHost* child_document = AddChild(top_document);
904 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
905 TestRenderFrameHost* sibling_document = AddChild(top_document);
906 std::string sec_required_csp = NavigateWithRequiredCSP(&sibling_document, "");
907 EXPECT_FALSE(sibling_document->required_csp());
908}
909
910TEST_F(CSPEmbeddedEnforcementUnitTest, ChildSiblingCSP) {
911 TestRenderFrameHost* top_document = main_rfh();
912 TestRenderFrameHost* child_document = AddChild(top_document);
913 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
914 TestRenderFrameHost* sibling_document = AddChild(top_document);
915 std::string sec_required_csp =
916 NavigateWithRequiredCSP(&sibling_document, "script-src 'none'");
917 EXPECT_EQ("script-src 'none'", sec_required_csp);
918 EXPECT_TRUE(sibling_document->required_csp());
919 EXPECT_EQ("script-src 'none'",
920 sibling_document->required_csp()->header->header_value);
921}
922
923TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildNoCSP) {
924 TestRenderFrameHost* top_document = main_rfh();
925 TestRenderFrameHost* child_document = AddChild(top_document);
926 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
927 TestRenderFrameHost* grand_child_document = AddChild(child_document);
928 std::string sec_required_csp =
929 NavigateWithRequiredCSP(&grand_child_document, "");
930 EXPECT_EQ("script-src 'none'", sec_required_csp);
931 EXPECT_TRUE(grand_child_document->required_csp());
932 EXPECT_EQ("script-src 'none'",
933 grand_child_document->required_csp()->header->header_value);
934}
935
936TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildSameCSP) {
937 TestRenderFrameHost* top_document = main_rfh();
938 TestRenderFrameHost* child_document = AddChild(top_document);
939 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
940 TestRenderFrameHost* grand_child_document = AddChild(child_document);
941 std::string sec_required_csp =
942 NavigateWithRequiredCSP(&grand_child_document, "script-src 'none'");
943 EXPECT_EQ("script-src 'none'", sec_required_csp);
944 EXPECT_TRUE(grand_child_document->required_csp());
945 EXPECT_EQ("script-src 'none'",
946 grand_child_document->required_csp()->header->header_value);
947}
948
949TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildDifferentCSP) {
950 TestRenderFrameHost* top_document = main_rfh();
951 TestRenderFrameHost* child_document = AddChild(top_document);
952 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
953 TestRenderFrameHost* grand_child_document = AddChild(child_document);
954 std::string sec_required_csp =
955 NavigateWithRequiredCSP(&grand_child_document, "img-src 'none'");
956
957 // This seems weird, but it is the intended behaviour according to the spec.
958 // The problem is that "script-src 'none'" does not subsume "img-src 'none'",
959 // so "img-src 'none'" on the grandchild is an invalid csp attribute, and we
960 // just discard it in favour of the parent's csp attribute.
961 //
962 // This should probably be fixed in the specification:
963 // https://github.com/w3c/webappsec-cspee/pull/11
964 EXPECT_EQ("script-src 'none'", sec_required_csp);
965 EXPECT_TRUE(grand_child_document->required_csp());
966 EXPECT_EQ("script-src 'none'",
967 grand_child_document->required_csp()->header->header_value);
968}
969
970TEST_F(CSPEmbeddedEnforcementUnitTest, InvalidCSP) {
971 TestRenderFrameHost* top_document = main_rfh();
972 TestRenderFrameHost* child_document = AddChild(top_document);
973 std::string sec_required_csp =
974 NavigateWithRequiredCSP(&child_document, "report-to group");
975 EXPECT_EQ("", sec_required_csp);
976 EXPECT_FALSE(child_document->required_csp());
977}
978
979TEST_F(CSPEmbeddedEnforcementUnitTest, InvalidCspAndInheritFromParent) {
980 TestRenderFrameHost* top_document = main_rfh();
981 TestRenderFrameHost* child_document = AddChild(top_document);
982 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
983 TestRenderFrameHost* grand_child_document = AddChild(child_document);
984 std::string sec_required_csp =
Antonio Sartori4231e932021-02-04 12:01:14985 NavigateWithRequiredCSP(&grand_child_document, "report-to group");
arthursonzogni898dcda52021-01-21 08:50:10986 EXPECT_EQ("script-src 'none'", sec_required_csp);
987 EXPECT_TRUE(grand_child_document->required_csp());
988 EXPECT_EQ("script-src 'none'",
989 grand_child_document->required_csp()->header->header_value);
990}
991
992TEST_F(CSPEmbeddedEnforcementUnitTest,
993 SemiInvalidCspAndInheritSameCspFromParent) {
994 TestRenderFrameHost* top_document = main_rfh();
995 TestRenderFrameHost* child_document = AddChild(top_document);
996 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
997 TestRenderFrameHost* grand_child_document = AddChild(child_document);
998 std::string sec_required_csp = NavigateWithRequiredCSP(
Antonio Sartori4231e932021-02-04 12:01:14999 &grand_child_document, "script-src 'none'; report-to group");
arthursonzogni898dcda52021-01-21 08:50:101000 EXPECT_EQ("script-src 'none'", sec_required_csp);
1001 EXPECT_TRUE(grand_child_document->required_csp());
1002 EXPECT_EQ("script-src 'none'",
1003 grand_child_document->required_csp()->header->header_value);
1004}
1005
1006TEST_F(CSPEmbeddedEnforcementUnitTest,
1007 SemiInvalidCspAndInheritDifferentCspFromParent) {
1008 TestRenderFrameHost* top_document = main_rfh();
1009 TestRenderFrameHost* child_document = AddChild(top_document);
1010 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
1011 TestRenderFrameHost* grand_child_document = AddChild(child_document);
1012 std::string sec_required_csp = NavigateWithRequiredCSP(
Antonio Sartori4231e932021-02-04 12:01:141013 &grand_child_document, "sandbox; report-to group");
arthursonzogni898dcda52021-01-21 08:50:101014 EXPECT_EQ("script-src 'none'", sec_required_csp);
1015 EXPECT_TRUE(grand_child_document->required_csp());
1016 EXPECT_EQ("script-src 'none'",
1017 grand_child_document->required_csp()->header->header_value);
1018}
1019
clamy49678312015-10-22 21:59:001020} // namespace content