blob: a55d28712a51b19e7ba57aa31d0c757de7db23ec [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2015 The Chromium Authors
clamy49678312015-10-22 21:59:002// 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
Peter Birk Pakkenberg73e07b62022-09-21 11:20:3010#include "base/containers/flat_map.h"
Avi Drissmanadac21992023-01-11 23:46:3911#include "base/functional/bind.h"
arthursonzogni898dcda52021-01-21 08:50:1012#include "base/i18n/number_formatting.h"
Yao Xiao6e1f7d32022-01-07 03:28:4013#include "base/test/scoped_feature_list.h"
Becky Zhou9898cb6e2019-06-05 00:35:3014#include "build/build_config.h"
clamy49678312015-10-22 21:59:0015#include "content/public/browser/navigation_throttle.h"
Peter Birk Pakkenberg73e07b62022-09-21 11:20:3016#include "content/public/browser/origin_trials_controller_delegate.h"
jam6d47c3452016-09-09 18:51:0117#include "content/public/browser/ssl_status.h"
Hans Wennborg5ffd1392019-10-16 11:00:0218#include "content/public/common/content_client.h"
Peter Birk Pakkenberg73e07b62022-09-21 11:20:3019#include "content/public/common/content_features.h"
Robbie McElrath5641d572022-05-20 17:15:2920#include "content/public/common/content_switches.h"
Charles Harrison860f7ef2017-06-28 15:31:4121#include "content/public/common/url_constants.h"
Peter Birk Pakkenberg73e07b62022-09-21 11:20:3022#include "content/public/test/test_browser_context.h"
Lucas Garron79e1a972017-10-04 22:25:0623#include "content/public/test/test_navigation_throttle.h"
Yao Xiao1099e4c2022-03-24 22:40:3724#include "content/test/fenced_frame_test_utils.h"
Camille Lamy62b826012019-02-26 09:15:4725#include "content/test/navigation_simulator_impl.h"
Charles Harrison860f7ef2017-06-28 15:31:4126#include "content/test/test_content_browser_client.h"
clamy49678312015-10-22 21:59:0027#include "content/test/test_render_frame_host.h"
scottmg276753cf2016-10-27 18:25:2228#include "content/test/test_web_contents.h"
Lucas Garronc1edb5ab2017-11-08 03:31:1329#include "net/ssl/ssl_connection_status_flags.h"
arthursonzogni898dcda52021-01-21 08:50:1030#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
Cammie Smith Barnesa0da2cf2021-01-11 22:09:3731#include "testing/gmock/include/gmock/gmock.h"
Anton Bikineevf62d1bf2021-05-15 17:56:0732#include "third_party/abseil-cpp/absl/types/optional.h"
Minggang Wanga13c796e2021-07-02 05:54:4333#include "third_party/blink/public/common/navigation/navigation_params.h"
Peter Birk Pakkenberg73e07b62022-09-21 11:20:3034#include "third_party/blink/public/common/origin_trials/scoped_test_origin_trial_policy.h"
Richard Lie6899952018-11-30 08:42:0035#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
clamy49678312015-10-22 21:59:0036
37namespace content {
38
clamy1d4e78fd2017-07-11 12:59:1939// Test version of a NavigationThrottle that will execute a callback when
40// called.
Lucas Garron79e1a972017-10-04 22:25:0641class DeletingNavigationThrottle : public NavigationThrottle {
clamy1d4e78fd2017-07-11 12:59:1942 public:
Lucas Garron79e1a972017-10-04 22:25:0643 DeletingNavigationThrottle(NavigationHandle* handle,
44 const base::RepeatingClosure& deletion_callback)
45 : NavigationThrottle(handle), deletion_callback_(deletion_callback) {}
Fergal Dalya1d569972021-03-16 03:24:5346 ~DeletingNavigationThrottle() override = default;
clamy1d4e78fd2017-07-11 12:59:1947
48 NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0649 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1950 return NavigationThrottle::PROCEED;
51 }
52
53 NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0654 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1955 return NavigationThrottle::PROCEED;
56 }
57
Lucas Garron0cedd962017-10-17 07:23:3358 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
59 deletion_callback_.Run();
60 return NavigationThrottle::PROCEED;
61 }
62
clamy1d4e78fd2017-07-11 12:59:1963 NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
Lucas Garron79e1a972017-10-04 22:25:0664 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1965 return NavigationThrottle::PROCEED;
66 }
67
68 const char* GetNameForLogging() override {
Lucas Garron79e1a972017-10-04 22:25:0669 return "DeletingNavigationThrottle";
clamy1d4e78fd2017-07-11 12:59:1970 }
71
72 private:
Lucas Garron79e1a972017-10-04 22:25:0673 base::RepeatingClosure deletion_callback_;
clamy1d4e78fd2017-07-11 12:59:1974};
75
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4376class NavigationRequestTest : public RenderViewHostImplTestHarness {
clamy49678312015-10-22 21:59:0077 public:
Fergal Dalya1d569972021-03-16 03:24:5378 NavigationRequestTest() : callback_result_(NavigationThrottle::DEFER) {}
clamy49678312015-10-22 21:59:0079
80 void SetUp() override {
81 RenderViewHostImplTestHarness::SetUp();
clamy1d4e78fd2017-07-11 12:59:1982 CreateNavigationHandle();
Dave Tapuska327c06c92022-06-13 20:31:5183 contents()->GetPrimaryMainFrame()->InitializeRenderFrameIfNeeded();
clamy49678312015-10-22 21:59:0084 }
85
Dmitrii Kuraginb7f90da2022-11-02 22:09:3086 void TearDown() override { RenderViewHostImplTestHarness::TearDown(); }
clamy49678312015-10-22 21:59:0087
Charles Harrison4f2bf1a2017-07-18 20:21:2188 void CancelDeferredNavigation(
89 NavigationThrottle::ThrottleCheckResult result) {
Hiroki Nakagawaadcffc502021-06-16 10:47:5190 GetNavigationRequest()->CancelDeferredNavigationInternal(result);
Charles Harrison4f2bf1a2017-07-18 20:21:2191 }
92
clamy49678312015-10-22 21:59:0093 // Helper function to call WillStartRequest on |handle|. If this function
94 // returns DEFER, |callback_result_| will be set to the actual result of
95 // the throttle checks when they are finished.
96 void SimulateWillStartRequest() {
97 was_callback_called_ = false;
98 callback_result_ = NavigationThrottle::DEFER;
99
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44100 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43101 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51102 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18103 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
104 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44105
Hiroki Nakagawaadcffc502021-06-16 10:47:51106 GetNavigationRequest()->WillStartRequest();
clamy49678312015-10-22 21:59:00107 }
108
109 // Helper function to call WillRedirectRequest on |handle|. If this function
110 // returns DEFER, |callback_result_| will be set to the actual result of the
111 // throttle checks when they are finished.
clamye88533842015-11-18 12:48:57112 // TODO(clamy): this should also simulate that WillStartRequest was called if
113 // it has not been called before.
clamy49678312015-10-22 21:59:00114 void SimulateWillRedirectRequest() {
115 was_callback_called_ = false;
116 callback_result_ = NavigationThrottle::DEFER;
117
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44118 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43119 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51120 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18121 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
122 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44123
Hiroki Nakagawaadcffc502021-06-16 10:47:51124 GetNavigationRequest()->WillRedirectRequest(
Arthur Hemery3a991c092021-12-22 12:04:24125 GURL(), nullptr /* post_redirect_process */);
clamy49678312015-10-22 21:59:00126 }
127
Lucas Garron0cedd962017-10-17 07:23:33128 // Helper function to call WillFailRequest on |handle|. If this function
129 // returns DEFER, |callback_result_| will be set to the actual result of the
130 // throttle checks when they are finished.
Lucas Garronc1edb5ab2017-11-08 03:31:13131 void SimulateWillFailRequest(
132 net::Error net_error_code,
Anton Bikineevf62d1bf2021-05-15 17:56:07133 const absl::optional<net::SSLInfo> ssl_info = absl::nullopt) {
Lucas Garron0cedd962017-10-17 07:23:33134 was_callback_called_ = false;
135 callback_result_ = NavigationThrottle::DEFER;
Hiroki Nakagawaadcffc502021-06-16 10:47:51136 GetNavigationRequest()->set_net_error(net_error_code);
Lucas Garron0cedd962017-10-17 07:23:33137
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44138 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43139 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51140 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18141 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
142 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44143
Hiroki Nakagawaadcffc502021-06-16 10:47:51144 GetNavigationRequest()->WillFailRequest();
Lucas Garron0cedd962017-10-17 07:23:33145 }
146
Nate Chapin060cb952023-02-08 21:13:07147 // Helper function to call WillCommitWithoutUrlLoader on |handle|. If this
148 // function returns DEFER, |callback_result_| will be set to the actual result
149 // of the throttle checks when they are finished.
150 void SimulateWillCommitWithoutUrlLoader() {
151 was_callback_called_ = false;
152 callback_result_ = NavigationThrottle::DEFER;
153
154 // It's safe to use base::Unretained since the NavigationRequest is owned by
155 // the NavigationRequestTest.
156 GetNavigationRequest()->set_complete_callback_for_testing(
157 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
158 base::Unretained(this)));
159
160 GetNavigationRequest()->WillCommitWithoutUrlLoader();
161 }
162
clamy49678312015-10-22 21:59:00163 // Whether the callback was called.
164 bool was_callback_called() const { return was_callback_called_; }
165
166 // Returns the callback_result.
167 NavigationThrottle::ThrottleCheckResult callback_result() const {
168 return callback_result_;
169 }
170
Hiroki Nakagawaadcffc502021-06-16 10:47:51171 NavigationRequest::NavigationState state() {
172 return GetNavigationRequest()->state();
173 }
Mohamed Abdelhalimccd149af2019-10-31 14:48:53174
Lucas Garron0cedd962017-10-17 07:23:33175 bool call_counts_match(TestNavigationThrottle* throttle,
176 int start,
177 int redirect,
178 int failure,
Nate Chapin060cb952023-02-08 21:13:07179 int process,
180 int withoutUrlLoader) {
Lucas Garron0cedd962017-10-17 07:23:33181 return start == throttle->GetCallCount(
182 TestNavigationThrottle::WILL_START_REQUEST) &&
183 redirect == throttle->GetCallCount(
184 TestNavigationThrottle::WILL_REDIRECT_REQUEST) &&
185 failure == throttle->GetCallCount(
186 TestNavigationThrottle::WILL_FAIL_REQUEST) &&
187 process == throttle->GetCallCount(
Nate Chapin060cb952023-02-08 21:13:07188 TestNavigationThrottle::WILL_PROCESS_RESPONSE) &&
189 withoutUrlLoader ==
190 throttle->GetCallCount(
191 TestNavigationThrottle::WILL_COMMIT_WITHOUT_URL_LOADER);
Lucas Garron0cedd962017-10-17 07:23:33192 }
193
194 // Creates, register and returns a TestNavigationThrottle that will
195 // synchronously return |result| on checks by default.
clamy49678312015-10-22 21:59:00196 TestNavigationThrottle* CreateTestNavigationThrottle(
197 NavigationThrottle::ThrottleCheckResult result) {
198 TestNavigationThrottle* test_throttle =
Hiroki Nakagawaadcffc502021-06-16 10:47:51199 new TestNavigationThrottle(GetNavigationRequest());
Lucas Garron79e1a972017-10-04 22:25:06200 test_throttle->SetResponseForAllMethods(TestNavigationThrottle::SYNCHRONOUS,
201 result);
Hiroki Nakagawaadcffc502021-06-16 10:47:51202 GetNavigationRequest()->RegisterThrottleForTesting(
dcheng9bfa5162016-04-09 01:00:57203 std::unique_ptr<TestNavigationThrottle>(test_throttle));
clamy49678312015-10-22 21:59:00204 return test_throttle;
205 }
206
Lucas Garron0cedd962017-10-17 07:23:33207 // Creates, register and returns a TestNavigationThrottle that will
208 // synchronously return |result| on check for the given |method|, and
209 // NavigationThrottle::PROCEED otherwise.
210 TestNavigationThrottle* CreateTestNavigationThrottle(
211 TestNavigationThrottle::ThrottleMethod method,
212 NavigationThrottle::ThrottleCheckResult result) {
213 TestNavigationThrottle* test_throttle =
214 CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
215 test_throttle->SetResponse(method, TestNavigationThrottle::SYNCHRONOUS,
216 result);
217 return test_throttle;
218 }
219
Mohamed Abdelhalim9ef43fc2019-04-05 13:09:43220 // TODO(zetamoo): Use NavigationSimulator instead of creating
221 // NavigationRequest and NavigationHandleImpl.
clamy1d4e78fd2017-07-11 12:59:19222 void CreateNavigationHandle() {
Minggang Wanga13c796e2021-07-02 05:54:43223 auto common_params = blink::CreateCommonNavigationParams();
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51224 common_params->initiator_origin =
Lukasz Anforowicz435bcb582019-07-12 20:50:06225 url::Origin::Create(GURL("https://initiator.example.com"));
Minggang Wanga13c796e2021-07-02 05:54:43226 auto commit_params = blink::CreateCommitNavigationParams();
arthursonzogni70ac7302020-05-28 08:49:05227 commit_params->frame_policy =
228 main_test_rfh()->frame_tree_node()->pending_frame_policy();
Hiroki Nakagawaadcffc502021-06-16 10:47:51229 auto request = NavigationRequest::CreateBrowserInitiated(
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51230 main_test_rfh()->frame_tree_node(), std::move(common_params),
Alex Moshchuk9321e6a2022-12-07 21:58:31231 std::move(commit_params), false /* was_opener_suppressed */,
232 nullptr /* initiator_frame_token */,
Antonio Sartori9a82f6f32020-12-14 09:22:45233 ChildProcessHost::kInvalidUniqueID /* initiator_process_id */,
John Delaney50425f82020-04-07 16:26:21234 std::string() /* extra_headers */, nullptr /* frame_entry */,
jongdeok.kim5de823b32022-06-14 04:37:50235 nullptr /* entry */, false /* is_form_submission */,
Daniel Hosseinianf0fbfb42021-09-08 02:20:47236 nullptr /* navigation_ui_data */, absl::nullopt /* impression */,
237 false /* is_pdf */);
Charlie Reis09952ee2022-12-08 16:35:07238 main_test_rfh()->frame_tree_node()->TakeNavigationRequest(
Hiroki Nakagawaadcffc502021-06-16 10:47:51239 std::move(request));
240 GetNavigationRequest()->StartNavigation();
clamy1d4e78fd2017-07-11 12:59:19241 }
242
Yao Xiao6e1f7d32022-01-07 03:28:40243 FrameTreeNode* AddFrame(FrameTree& frame_tree,
244 RenderFrameHostImpl* parent,
245 int process_id,
246 int new_routing_id,
247 const blink::FramePolicy& frame_policy,
248 blink::FrameOwnerElementType owner_type) {
249 return frame_tree.AddFrame(
250 parent, process_id, new_routing_id,
251 TestRenderFrameHost::CreateStubFrameRemote(),
252 TestRenderFrameHost::CreateStubBrowserInterfaceBrokerReceiver(),
253 TestRenderFrameHost::CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49254 TestRenderFrameHost::CreateStubAssociatedInterfaceProviderReceiver(),
Yao Xiao6e1f7d32022-01-07 03:28:40255 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
256 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34257 blink::DocumentToken(), frame_policy,
258 blink::mojom::FrameOwnerProperties(), false, owner_type,
Yao Xiao6e1f7d32022-01-07 03:28:40259 /*is_dummy_frame_for_inner_tree=*/false);
260 }
261
clamy49678312015-10-22 21:59:00262 private:
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31263 // The callback provided to NavigationRequest::WillStartRequest,
264 // NavigationRequest::WillRedirectRequest, and
265 // NavigationRequest::WillFailRequest during the tests.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44266 bool UpdateThrottleCheckResult(
clamy49678312015-10-22 21:59:00267 NavigationThrottle::ThrottleCheckResult result) {
268 callback_result_ = result;
269 was_callback_called_ = true;
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44270 return true;
clamy49678312015-10-22 21:59:00271 }
272
Hiroki Nakagawaadcffc502021-06-16 10:47:51273 // This must be called after CreateNavigationHandle().
274 NavigationRequest* GetNavigationRequest() {
275 return main_test_rfh()->frame_tree_node()->navigation_request();
276 }
277
Fergal Dalya1d569972021-03-16 03:24:53278 bool was_callback_called_ = false;
clamy49678312015-10-22 21:59:00279 NavigationThrottle::ThrottleCheckResult callback_result_;
280};
281
carlosk489d9e22016-07-25 14:25:43282// Checks that the request_context_type is properly set.
283// Note: can be extended to cover more internal members.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43284TEST_F(NavigationRequestTest, SimpleDataChecksRedirectAndProcess) {
Camille Lamy62b826012019-02-26 09:15:47285 const GURL kUrl1 = GURL("http://chromium.org");
286 const GURL kUrl2 = GURL("http://google.com");
287 auto navigation =
288 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
289 navigation->Start();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40290 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05291 NavigationRequest::From(navigation->GetNavigationHandle())
292 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11293 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47294 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43295
Camille Lamy62b826012019-02-26 09:15:47296 navigation->set_http_connection_info(
297 net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1);
298 navigation->Redirect(kUrl2);
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40299 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05300 NavigationRequest::From(navigation->GetNavigationHandle())
301 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11302 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
Camille Lamy62b826012019-02-26 09:15:47303 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43304
Camille Lamy62b826012019-02-26 09:15:47305 navigation->set_http_connection_info(
306 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
307 navigation->ReadyToCommit();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40308 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05309 NavigationRequest::From(navigation->GetNavigationHandle())
310 ->request_context_type());
bnc90be5dd782016-11-09 16:28:44311 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47312 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11313}
314
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43315TEST_F(NavigationRequestTest, SimpleDataCheckNoRedirect) {
Camille Lamy62b826012019-02-26 09:15:47316 const GURL kUrl = GURL("http://chromium.org");
317 auto navigation =
318 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
319 navigation->Start();
jkarlinbb150112016-11-02 17:55:11320 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47321 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11322
Camille Lamy62b826012019-02-26 09:15:47323 navigation->set_http_connection_info(
324 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
325 navigation->ReadyToCommit();
bnc90be5dd782016-11-09 16:28:44326 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47327 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43328}
329
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43330TEST_F(NavigationRequestTest, SimpleDataChecksFailure) {
Camille Lamy62b826012019-02-26 09:15:47331 const GURL kUrl = GURL("http://chromium.org");
332 auto navigation =
333 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
334 navigation->Start();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40335 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05336 NavigationRequest::From(navigation->GetNavigationHandle())
337 ->request_context_type());
Lucas Garron0cedd962017-10-17 07:23:33338 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47339 navigation->GetNavigationHandle()->GetConnectionInfo());
Lucas Garron0cedd962017-10-17 07:23:33340
Camille Lamy62b826012019-02-26 09:15:47341 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40342 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05343 NavigationRequest::From(navigation->GetNavigationHandle())
344 ->request_context_type());
Camille Lamy62b826012019-02-26 09:15:47345 EXPECT_EQ(net::ERR_CERT_DATE_INVALID,
346 navigation->GetNavigationHandle()->GetNetErrorCode());
Lucas Garron0cedd962017-10-17 07:23:33347}
348
clamye88533842015-11-18 12:48:57349// Checks that a navigation deferred during WillStartRequest can be properly
350// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53351TEST_F(NavigationRequestTest, CancelDeferredWillStart) {
clamye88533842015-11-18 12:48:57352 TestNavigationThrottle* test_throttle =
353 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19354 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Nate Chapin060cb952023-02-08 21:13:07355 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57356
357 // Simulate WillStartRequest. The request should be deferred. The callback
358 // should not have been called.
359 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19360 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
clamye88533842015-11-18 12:48:57361 EXPECT_FALSE(was_callback_called());
Nate Chapin060cb952023-02-08 21:13:07362 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57363
364 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21365 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19366 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57367 EXPECT_TRUE(was_callback_called());
368 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Nate Chapin060cb952023-02-08 21:13:07369 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57370}
371
372// Checks that a navigation deferred during WillRedirectRequest can be properly
373// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53374TEST_F(NavigationRequestTest, CancelDeferredWillRedirect) {
clamye88533842015-11-18 12:48:57375 TestNavigationThrottle* test_throttle =
376 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19377 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Nate Chapin060cb952023-02-08 21:13:07378 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57379
380 // Simulate WillRedirectRequest. The request should be deferred. The callback
381 // should not have been called.
382 SimulateWillRedirectRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19383 EXPECT_EQ(NavigationRequest::WILL_REDIRECT_REQUEST, state());
clamye88533842015-11-18 12:48:57384 EXPECT_FALSE(was_callback_called());
Nate Chapin060cb952023-02-08 21:13:07385 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57386
387 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21388 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19389 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57390 EXPECT_TRUE(was_callback_called());
391 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Nate Chapin060cb952023-02-08 21:13:07392 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33393}
394
395// Checks that a navigation deferred during WillFailRequest can be properly
396// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53397TEST_F(NavigationRequestTest, CancelDeferredWillFail) {
Lucas Garron0cedd962017-10-17 07:23:33398 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
399 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19400 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Nate Chapin060cb952023-02-08 21:13:07401 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33402
403 // Simulate WillStartRequest.
404 SimulateWillStartRequest();
Nate Chapin060cb952023-02-08 21:13:07405 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33406
407 // Simulate WillFailRequest. The request should be deferred. The callback
408 // should not have been called.
409 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19410 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33411 EXPECT_FALSE(was_callback_called());
Nate Chapin060cb952023-02-08 21:13:07412 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33413
414 // Cancel the request. The callback should have been called.
415 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19416 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33417 EXPECT_TRUE(was_callback_called());
418 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Nate Chapin060cb952023-02-08 21:13:07419 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0));
clamye88533842015-11-18 12:48:57420}
421
422// Checks that a navigation deferred can be canceled and not ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53423TEST_F(NavigationRequestTest, CancelDeferredWillRedirectNoIgnore) {
clamye88533842015-11-18 12:48:57424 TestNavigationThrottle* test_throttle =
425 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19426 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Nate Chapin060cb952023-02-08 21:13:07427 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57428
Lucas Garron0cedd962017-10-17 07:23:33429 // Simulate WillStartRequest. The request should be deferred. The callback
clamye88533842015-11-18 12:48:57430 // should not have been called.
431 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19432 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Nate Chapin060cb952023-02-08 21:13:07433 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57434
435 // Cancel the request. The callback should have been called with CANCEL, and
436 // not CANCEL_AND_IGNORE.
Charles Harrison4f2bf1a2017-07-18 20:21:21437 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19438 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57439 EXPECT_TRUE(was_callback_called());
440 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
Nate Chapin060cb952023-02-08 21:13:07441 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57442}
443
Lucas Garron0cedd962017-10-17 07:23:33444// Checks that a navigation deferred by WillFailRequest can be canceled and not
445// ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53446TEST_F(NavigationRequestTest, CancelDeferredWillFailNoIgnore) {
Lucas Garron0cedd962017-10-17 07:23:33447 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
448 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19449 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Nate Chapin060cb952023-02-08 21:13:07450 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33451
452 // Simulate WillStartRequest.
453 SimulateWillStartRequest();
Nate Chapin060cb952023-02-08 21:13:07454 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33455
456 // Simulate WillFailRequest. The request should be deferred. The callback
457 // should not have been called.
458 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19459 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33460 EXPECT_FALSE(was_callback_called());
Nate Chapin060cb952023-02-08 21:13:07461 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0));
Lucas Garron0cedd962017-10-17 07:23:33462
463 // Cancel the request. The callback should have been called with CANCEL, and
464 // not CANCEL_AND_IGNORE.
465 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19466 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33467 EXPECT_TRUE(was_callback_called());
468 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
Nate Chapin060cb952023-02-08 21:13:07469 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0));
470}
471
472// Checks that a navigation deferred during WillCommitWithoutUrlLoader can be
473// properly cancelled.
474TEST_F(NavigationRequestTest, CancelDeferredWillCommitWithoutUrlLoader) {
475 TestNavigationThrottle* test_throttle =
476 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
477 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
478 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0));
479
480 // Simulate WillCommitWithoutUrlLoader. The request should be deferred. The
481 // callback should not have been called.
482 SimulateWillCommitWithoutUrlLoader();
483 EXPECT_EQ(NavigationRequest::WILL_COMMIT_WITHOUT_URL_LOADER, state());
484 EXPECT_FALSE(was_callback_called());
485 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 1));
486
487 // Cancel the request. The callback should have been called.
488 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
489 EXPECT_EQ(NavigationRequest::CANCELING, state());
490 EXPECT_TRUE(was_callback_called());
491 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
492 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 1));
Lucas Garron0cedd962017-10-17 07:23:33493}
494
Lucas Garronc1edb5ab2017-11-08 03:31:13495// Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
John Abd-El-Malekf36e05f2017-11-30 16:17:52496// stored on the handle.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43497TEST_F(NavigationRequestTest, WillFailRequestSetsSSLInfo) {
Lucas Garronc1edb5ab2017-11-08 03:31:13498 uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
499 int connection_status = 0;
500 net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
501
502 // Set some test values.
503 net::SSLInfo ssl_info;
504 ssl_info.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
505 ssl_info.connection_status = connection_status;
506
Camille Lamy62b826012019-02-26 09:15:47507 const GURL kUrl = GURL("https://chromium.org");
508 auto navigation =
509 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
Emily Starkfd6978ad12019-04-30 21:20:07510 navigation->SetSSLInfo(ssl_info);
Camille Lamy62b826012019-02-26 09:15:47511 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Lucas Garronc1edb5ab2017-11-08 03:31:13512
513 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID,
Camille Lamy62b826012019-02-26 09:15:47514 navigation->GetNavigationHandle()->GetSSLInfo()->cert_status);
515 EXPECT_EQ(connection_status,
516 navigation->GetNavigationHandle()->GetSSLInfo()->connection_status);
Lucas Garronc1edb5ab2017-11-08 03:31:13517}
518
Camille Lamy62b826012019-02-26 09:15:47519namespace {
520
Alex Moshchuk1a66b1d2018-05-15 21:18:26521// Helper throttle which checks that it can access NavigationHandle's
522// RenderFrameHost in WillFailRequest() and then defers the failure.
523class GetRenderFrameHostOnFailureNavigationThrottle
524 : public NavigationThrottle {
525 public:
Fergal Dalya1d569972021-03-16 03:24:53526 explicit GetRenderFrameHostOnFailureNavigationThrottle(
527 NavigationHandle* handle)
Alex Moshchuk1a66b1d2018-05-15 21:18:26528 : NavigationThrottle(handle) {}
Peter Boström828b9022021-09-21 02:28:43529
530 GetRenderFrameHostOnFailureNavigationThrottle(
531 const GetRenderFrameHostOnFailureNavigationThrottle&) = delete;
532 GetRenderFrameHostOnFailureNavigationThrottle& operator=(
533 const GetRenderFrameHostOnFailureNavigationThrottle&) = delete;
534
Fergal Dalya1d569972021-03-16 03:24:53535 ~GetRenderFrameHostOnFailureNavigationThrottle() override = default;
Alex Moshchuk1a66b1d2018-05-15 21:18:26536
537 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
538 EXPECT_TRUE(navigation_handle()->GetRenderFrameHost());
539 return NavigationThrottle::DEFER;
540 }
541
542 const char* GetNameForLogging() override {
543 return "GetRenderFrameHostOnFailureNavigationThrottle";
544 }
Alex Moshchuk1a66b1d2018-05-15 21:18:26545};
546
Camille Lamy62b826012019-02-26 09:15:47547class ThrottleTestContentBrowserClient : public ContentBrowserClient {
548 std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation(
549 NavigationHandle* navigation_handle) override {
550 std::vector<std::unique_ptr<NavigationThrottle>> throttle;
551 throttle.push_back(
552 std::make_unique<GetRenderFrameHostOnFailureNavigationThrottle>(
553 navigation_handle));
554 return throttle;
555 }
556};
557
558} // namespace
559
Alex Moshchuk1a66b1d2018-05-15 21:18:26560// Verify that the NavigationHandle::GetRenderFrameHost() can be retrieved by a
561// throttle in WillFailRequest(), as well as after deferring the failure. This
562// is allowed, since at that point the final RenderFrameHost will have already
563// been chosen. See https://crbug.com/817881.
Mohamed Abdelhalimba020672019-10-31 16:18:53564TEST_F(NavigationRequestTest, WillFailRequestCanAccessRenderFrameHost) {
Camille Lamy62b826012019-02-26 09:15:47565 std::unique_ptr<ContentBrowserClient> client(
566 new ThrottleTestContentBrowserClient);
567 ContentBrowserClient* old_browser_client =
568 SetBrowserClientForTesting(client.get());
569
570 const GURL kUrl = GURL("http://chromium.org");
571 auto navigation =
572 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
573 navigation->SetAutoAdvance(false);
574 navigation->Start();
575 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalim3b235272019-11-05 15:06:07576 EXPECT_EQ(
577 NavigationRequest::WILL_FAIL_REQUEST,
578 NavigationRequest::From(navigation->GetNavigationHandle())->state());
Camille Lamy62b826012019-02-26 09:15:47579 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
Mohamed Abdelhalim40c35d22019-09-19 15:59:05580 NavigationRequest::From(navigation->GetNavigationHandle())
danakjf26536bf2020-09-10 00:46:13581 ->GetNavigationThrottleRunnerForTesting()
Mohamed Abdelhalim40c35d22019-09-19 15:59:05582 ->CallResumeForTesting();
Camille Lamy62b826012019-02-26 09:15:47583 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
584
585 SetBrowserClientForTesting(old_browser_client);
Alex Moshchuk1a66b1d2018-05-15 21:18:26586}
587
Antonio Sartori3cfa3b62020-10-09 10:42:40588TEST_F(NavigationRequestTest, PolicyContainerInheritance) {
589 struct TestCase {
590 const char* url;
591 bool expect_inherit;
592 } cases[]{{"about:blank", true},
593 {"data:text/plain,hello", true},
594 {"file://local", false},
595 {"http://chromium.org", false}};
596
597 const GURL kUrl1 = GURL("http://chromium.org");
598 auto navigation =
599 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
600 navigation->Commit();
601
602 for (auto test : cases) {
603 // We navigate child frames because the BlockedSchemeNavigationThrottle
604 // restricts navigations in the main frame.
605 auto* child_frame = static_cast<TestRenderFrameHost*>(
606 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child"));
607
608 // We set the referrer policy of the frame to "always". We then create a new
609 // navigation, set as initiator the frame itself, start the navigation, and
610 // change the referrer policy of the frame to "never". After we commit the
611 // navigation:
612 // - If navigating to a local scheme, the target frame should have inherited
613 // the referrer policy of the initiator ("always").
614 // - If navigating to a non-local scheme, the target frame should have a new
615 // policy container (hence referrer policy set to "default").
616 const GURL kUrl = GURL(test.url);
Peter Kastingeb8c3ce2021-08-20 04:39:35617 navigation =
Antonio Sartori3cfa3b62020-10-09 10:42:40618 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_frame);
Antonio Sartori5b2f8042020-10-23 18:13:26619 static_cast<blink::mojom::PolicyContainerHost*>(
Antonio Sartori9290b6b2020-11-09 10:09:33620 child_frame->policy_container_host())
Antonio Sartori5b2f8042020-10-23 18:13:26621 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kAlways);
Antonio Sartori3cfa3b62020-10-09 10:42:40622 navigation->SetInitiatorFrame(child_frame);
623 navigation->Start();
Antonio Sartori5b2f8042020-10-23 18:13:26624 static_cast<blink::mojom::PolicyContainerHost*>(
Antonio Sartori9290b6b2020-11-09 10:09:33625 child_frame->policy_container_host())
Antonio Sartori5b2f8042020-10-23 18:13:26626 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
Antonio Sartori3cfa3b62020-10-09 10:42:40627 navigation->Commit();
628 EXPECT_EQ(
629 test.expect_inherit ? network::mojom::ReferrerPolicy::kAlways
630 : network::mojom::ReferrerPolicy::kDefault,
631 static_cast<RenderFrameHostImpl*>(navigation->GetFinalRenderFrameHost())
Antonio Sartori9290b6b2020-11-09 10:09:33632 ->policy_container_host()
Antonio Sartori3cfa3b62020-10-09 10:42:40633 ->referrer_policy());
634 }
635}
636
Cammie Smith Barnesa0da2cf2021-01-11 22:09:37637TEST_F(NavigationRequestTest, DnsAliasesCanBeAccessed) {
638 // Create simulated NavigationRequest for the URL, which has aliases.
639 const GURL kUrl = GURL("http://chromium.org");
640 auto navigation =
641 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
642 std::vector<std::string> dns_aliases({"alias1", "alias2"});
643 navigation->SetResponseDnsAliases(std::move(dns_aliases));
644
645 // Start the navigation.
646 navigation->Start();
647 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
648 navigation->GetNavigationHandle()->GetConnectionInfo());
649
650 // Commit the navigation.
651 navigation->set_http_connection_info(
652 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
653 navigation->ReadyToCommit();
654 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
655 navigation->GetNavigationHandle()->GetConnectionInfo());
656
657 // Verify that the aliases are accessible from the NavigationRequest.
658 EXPECT_THAT(navigation->GetNavigationHandle()->GetDnsAliases(),
659 testing::ElementsAre("alias1", "alias2"));
660}
661
662TEST_F(NavigationRequestTest, NoDnsAliases) {
663 // Create simulated NavigationRequest for the URL, which does not
664 // have aliases. (Note the empty alias list.)
665 const GURL kUrl = GURL("http://chromium.org");
666 auto navigation =
667 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
668 std::vector<std::string> dns_aliases;
669 navigation->SetResponseDnsAliases(std::move(dns_aliases));
670
671 // Start the navigation.
672 navigation->Start();
673 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
674 navigation->GetNavigationHandle()->GetConnectionInfo());
675
676 // Commit the navigation.
677 navigation->set_http_connection_info(
678 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
679 navigation->ReadyToCommit();
680 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
681 navigation->GetNavigationHandle()->GetConnectionInfo());
682
683 // Verify that there are no aliases in the NavigationRequest.
684 EXPECT_TRUE(navigation->GetNavigationHandle()->GetDnsAliases().empty());
685}
686
Antonio Sartori3e8de6d2021-07-26 10:28:41687TEST_F(NavigationRequestTest, StorageKeyToCommit) {
688 TestRenderFrameHost* child_document = static_cast<TestRenderFrameHost*>(
689 content::RenderFrameHostTester::For(main_rfh())->AppendChild(""));
Yuzu Saijo03dbf9b2022-07-22 04:29:45690 auto attributes = child_document->frame_tree_node()->attributes_->Clone();
Arthur Sonzogni64457592022-11-22 11:08:59691 attributes->credentialless = true;
Yuzu Saijo03dbf9b2022-07-22 04:29:45692 child_document->frame_tree_node()->SetAttributes(std::move(attributes));
Antonio Sartori3e8de6d2021-07-26 10:28:41693
694 const GURL kUrl = GURL("http://chromium.org");
695 auto navigation =
696 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_document);
697 navigation->ReadyToCommit();
698 NavigationRequest* request =
699 NavigationRequest::From(navigation->GetNavigationHandle());
700 EXPECT_TRUE(request->commit_params().storage_key.nonce().has_value());
Arthur Sonzogni64457592022-11-22 11:08:59701 EXPECT_EQ(child_document->GetMainFrame()->credentialless_iframes_nonce(),
Antonio Sartori3e8de6d2021-07-26 10:28:41702 request->commit_params().storage_key.nonce().value());
703
704 navigation->Commit();
705 child_document =
706 static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost());
Arthur Sonzogni64457592022-11-22 11:08:59707 EXPECT_TRUE(child_document->IsCredentialless());
Ari Chivukulad9e9c382023-02-15 23:30:09708 EXPECT_EQ(blink::StorageKey::CreateWithNonce(
Ali Hijazi78de14c2022-07-21 11:32:19709 url::Origin::Create(kUrl),
Arthur Sonzogni64457592022-11-22 11:08:59710 child_document->GetMainFrame()->credentialless_iframes_nonce()),
Ali Hijazi78de14c2022-07-21 11:32:19711 child_document->storage_key());
Antonio Sartori3e8de6d2021-07-26 10:28:41712}
713
Antonio Sartoribf27cc442021-08-25 13:08:23714TEST_F(NavigationRequestTest,
Arthur Sonzogni64457592022-11-22 11:08:59715 NavigationToCredentiallessDocumentNetworkIsolationInfo) {
Antonio Sartoribf27cc442021-08-25 13:08:23716 auto* child_frame = static_cast<TestRenderFrameHost*>(
717 content::RenderFrameHostTester::For(main_test_rfh())
718 ->AppendChild("child"));
Yuzu Saijo03dbf9b2022-07-22 04:29:45719 auto attributes = child_frame->frame_tree_node()->attributes_->Clone();
Arthur Sonzogni64457592022-11-22 11:08:59720 attributes->credentialless = true;
Yuzu Saijo03dbf9b2022-07-22 04:29:45721 child_frame->frame_tree_node()->SetAttributes(std::move(attributes));
Antonio Sartoribf27cc442021-08-25 13:08:23722
723 std::unique_ptr<NavigationSimulator> navigation =
724 NavigationSimulator::CreateRendererInitiated(
725 GURL("https://example.com/navigation.html"), child_frame);
726 navigation->ReadyToCommit();
727
Arthur Sonzogni64457592022-11-22 11:08:59728 EXPECT_EQ(main_test_rfh()->credentialless_iframes_nonce(),
Antonio Sartoribf27cc442021-08-25 13:08:23729 static_cast<NavigationRequest*>(navigation->GetNavigationHandle())
730 ->isolation_info_for_subresources()
731 .network_isolation_key()
732 .GetNonce());
Arthur Sonzogni64457592022-11-22 11:08:59733 EXPECT_EQ(main_test_rfh()->credentialless_iframes_nonce(),
Antonio Sartoribf27cc442021-08-25 13:08:23734 static_cast<NavigationRequest*>(navigation->GetNavigationHandle())
735 ->GetIsolationInfo()
736 .network_isolation_key()
737 .GetNonce());
738}
739
Robbie McElrath5641d572022-05-20 17:15:29740class ScopedIsolatedAppBrowserClient : public ContentBrowserClient {
741 public:
Robbie McElrathc91ce362022-11-18 18:08:12742 explicit ScopedIsolatedAppBrowserClient(const GURL& isolated_url)
743 : isolated_host_(isolated_url.host()),
744 old_client_(SetBrowserClientForTesting(this)) {}
Robbie McElrath5641d572022-05-20 17:15:29745
746 ~ScopedIsolatedAppBrowserClient() override {
747 SetBrowserClientForTesting(old_client_);
748 }
749
Robbie McElrath4e8596d2023-02-07 21:59:13750 bool ShouldUrlUseApplicationIsolationLevel(BrowserContext* browser_context,
751 const GURL& url) override {
Robbie McElrathc91ce362022-11-18 18:08:12752 return url.host() == isolated_host_;
Robbie McElrath5641d572022-05-20 17:15:29753 }
754
755 private:
Robbie McElrathc91ce362022-11-18 18:08:12756 std::string isolated_host_;
Robbie McElrath5641d572022-05-20 17:15:29757 raw_ptr<ContentBrowserClient> old_client_;
758};
759
760TEST_F(NavigationRequestTest, IsolatedAppPolicyInjection) {
761 const GURL kUrl = GURL("https://chromium.org");
Robbie McElrathc91ce362022-11-18 18:08:12762 ScopedIsolatedAppBrowserClient client(kUrl);
Robbie McElrath5641d572022-05-20 17:15:29763
764 auto navigation =
765 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
766 navigation->ReadyToCommit();
767
768 // Validate the COOP/COEP headers.
769 const PolicyContainerPolicies& policies =
770 navigation->GetNavigationHandle()->GetPolicyContainerPolicies();
771 EXPECT_EQ(network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep,
772 policies.cross_origin_opener_policy.value);
773 EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp,
774 policies.cross_origin_embedder_policy.value);
775
776 // Validate CSP.
777 EXPECT_EQ(1UL, policies.content_security_policies.size());
778 const auto& csp = policies.content_security_policies[0];
Ovidio Ruiz-Henríquezadd3f402022-10-17 19:10:31779 EXPECT_EQ(10UL, csp->raw_directives.size());
Robbie McElrath5641d572022-05-20 17:15:29780 using Directive = network::mojom::CSPDirectiveName;
781 EXPECT_EQ("'none'", csp->raw_directives[Directive::BaseURI]);
782 EXPECT_EQ("'none'", csp->raw_directives[Directive::ObjectSrc]);
783 EXPECT_EQ("'self'", csp->raw_directives[Directive::DefaultSrc]);
784 EXPECT_EQ("'self' https:", csp->raw_directives[Directive::FrameSrc]);
785 EXPECT_EQ("'self' https:", csp->raw_directives[Directive::ConnectSrc]);
Robbie McElrathb062f3d2022-08-09 17:48:44786 EXPECT_EQ("'self' 'wasm-unsafe-eval'",
787 csp->raw_directives[Directive::ScriptSrc]);
Ovidio Ruiz-Henríquezadd3f402022-10-17 19:10:31788 EXPECT_EQ("'self' data:", csp->raw_directives[Directive::ImgSrc]);
789 EXPECT_EQ("'self' data:", csp->raw_directives[Directive::MediaSrc]);
790 EXPECT_EQ("'self' data:", csp->raw_directives[Directive::FontSrc]);
Robbie McElrath5641d572022-05-20 17:15:29791 EXPECT_EQ("'script'", csp->raw_directives[Directive::RequireTrustedTypesFor]);
792}
793
arthursonzogni898dcda52021-01-21 08:50:10794// Test that the required CSP of every frame is computed/inherited correctly and
795// that the Sec-Required-CSP header is set.
796class CSPEmbeddedEnforcementUnitTest : public NavigationRequestTest {
797 protected:
798 TestRenderFrameHost* main_rfh() {
799 return static_cast<TestRenderFrameHost*>(NavigationRequestTest::main_rfh());
800 }
801
802 // Simulate the |csp| attribute being set in |rfh|'s frame. Then navigate it.
803 // Returns the request's Sec-Required-CSP header.
804 std::string NavigateWithRequiredCSP(TestRenderFrameHost** rfh,
805 std::string required_csp) {
806 TestRenderFrameHost* document = *rfh;
807
808 if (!required_csp.empty()) {
809 auto headers =
810 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
811 headers->SetHeader("Content-Security-Policy", required_csp);
812 std::vector<network::mojom::ContentSecurityPolicyPtr> policies;
813 network::AddContentSecurityPolicyFromHeaders(
814 *headers, GURL("https://example.com/"), &policies);
Yuzu Saijo03dbf9b2022-07-22 04:29:45815 auto attributes = document->frame_tree_node()->attributes_->Clone();
816 // Set csp value.
817 attributes->parsed_csp_attribute = std::move(policies[0]);
818 document->frame_tree_node()->SetAttributes(std::move(attributes));
arthursonzogni898dcda52021-01-21 08:50:10819 }
820
821 // Chrome blocks a document navigating to a URL if more than one of its
822 // ancestors have the same URL. Use a different URL every time, to
823 // avoid blocking navigation of the grandchild frame.
824 static int nonce = 0;
825 GURL url("https://www.example.com" + base::NumberToString(nonce++));
826
827 auto navigation =
828 content::NavigationSimulator::CreateRendererInitiated(url, *rfh);
829 navigation->Start();
830 NavigationRequest* request =
831 NavigationRequest::From(navigation->GetNavigationHandle());
832 std::string sec_required_csp;
833 request->GetRequestHeaders().GetHeader("sec-required-csp",
834 &sec_required_csp);
835
836 // Complete the navigation so that the required csp is stored in the
837 // RenderFrameHost, so that when we will add children to this document they
838 // will be able to get the parent's required csp (and hence also test that
839 // the whole logic works).
840 auto response_headers =
841 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
842 response_headers->SetHeader("Allow-CSP-From", "*");
843 navigation->SetResponseHeaders(response_headers);
844 navigation->Commit();
845
846 *rfh = static_cast<TestRenderFrameHost*>(
847 navigation->GetFinalRenderFrameHost());
848
849 return sec_required_csp;
850 }
851
852 TestRenderFrameHost* AddChild(TestRenderFrameHost* parent) {
853 return static_cast<TestRenderFrameHost*>(
854 content::RenderFrameHostTester::For(parent)->AppendChild(""));
855 }
856};
857
858TEST_F(CSPEmbeddedEnforcementUnitTest, TopLevel) {
859 TestRenderFrameHost* top_document = main_rfh();
860 std::string sec_required_csp = NavigateWithRequiredCSP(&top_document, "");
861 EXPECT_EQ("", sec_required_csp);
862 EXPECT_FALSE(top_document->required_csp());
863}
864
865TEST_F(CSPEmbeddedEnforcementUnitTest, ChildNoCSP) {
866 TestRenderFrameHost* top_document = main_rfh();
867 TestRenderFrameHost* child_document = AddChild(top_document);
868 std::string sec_required_csp = NavigateWithRequiredCSP(&child_document, "");
869 EXPECT_EQ("", sec_required_csp);
870 EXPECT_FALSE(child_document->required_csp());
871}
872
873TEST_F(CSPEmbeddedEnforcementUnitTest, ChildWithCSP) {
874 TestRenderFrameHost* top_document = main_rfh();
875 TestRenderFrameHost* child_document = AddChild(top_document);
876 std::string sec_required_csp =
877 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
878 EXPECT_EQ("script-src 'none'", sec_required_csp);
879 EXPECT_TRUE(child_document->required_csp());
880 EXPECT_EQ("script-src 'none'",
881 child_document->required_csp()->header->header_value);
882}
883
884TEST_F(CSPEmbeddedEnforcementUnitTest, ChildSiblingNoCSP) {
885 TestRenderFrameHost* top_document = main_rfh();
886 TestRenderFrameHost* child_document = AddChild(top_document);
887 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
888 TestRenderFrameHost* sibling_document = AddChild(top_document);
889 std::string sec_required_csp = NavigateWithRequiredCSP(&sibling_document, "");
890 EXPECT_FALSE(sibling_document->required_csp());
891}
892
893TEST_F(CSPEmbeddedEnforcementUnitTest, ChildSiblingCSP) {
894 TestRenderFrameHost* top_document = main_rfh();
895 TestRenderFrameHost* child_document = AddChild(top_document);
896 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
897 TestRenderFrameHost* sibling_document = AddChild(top_document);
898 std::string sec_required_csp =
899 NavigateWithRequiredCSP(&sibling_document, "script-src 'none'");
900 EXPECT_EQ("script-src 'none'", sec_required_csp);
901 EXPECT_TRUE(sibling_document->required_csp());
902 EXPECT_EQ("script-src 'none'",
903 sibling_document->required_csp()->header->header_value);
904}
905
906TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildNoCSP) {
907 TestRenderFrameHost* top_document = main_rfh();
908 TestRenderFrameHost* child_document = AddChild(top_document);
909 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
910 TestRenderFrameHost* grand_child_document = AddChild(child_document);
911 std::string sec_required_csp =
912 NavigateWithRequiredCSP(&grand_child_document, "");
913 EXPECT_EQ("script-src 'none'", sec_required_csp);
914 EXPECT_TRUE(grand_child_document->required_csp());
915 EXPECT_EQ("script-src 'none'",
916 grand_child_document->required_csp()->header->header_value);
917}
918
919TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildSameCSP) {
920 TestRenderFrameHost* top_document = main_rfh();
921 TestRenderFrameHost* child_document = AddChild(top_document);
922 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
923 TestRenderFrameHost* grand_child_document = AddChild(child_document);
924 std::string sec_required_csp =
925 NavigateWithRequiredCSP(&grand_child_document, "script-src 'none'");
926 EXPECT_EQ("script-src 'none'", sec_required_csp);
927 EXPECT_TRUE(grand_child_document->required_csp());
928 EXPECT_EQ("script-src 'none'",
929 grand_child_document->required_csp()->header->header_value);
930}
931
932TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildDifferentCSP) {
933 TestRenderFrameHost* top_document = main_rfh();
934 TestRenderFrameHost* child_document = AddChild(top_document);
935 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
936 TestRenderFrameHost* grand_child_document = AddChild(child_document);
937 std::string sec_required_csp =
938 NavigateWithRequiredCSP(&grand_child_document, "img-src 'none'");
939
940 // This seems weird, but it is the intended behaviour according to the spec.
941 // The problem is that "script-src 'none'" does not subsume "img-src 'none'",
942 // so "img-src 'none'" on the grandchild is an invalid csp attribute, and we
943 // just discard it in favour of the parent's csp attribute.
944 //
945 // This should probably be fixed in the specification:
946 // https://github.com/w3c/webappsec-cspee/pull/11
947 EXPECT_EQ("script-src 'none'", sec_required_csp);
948 EXPECT_TRUE(grand_child_document->required_csp());
949 EXPECT_EQ("script-src 'none'",
950 grand_child_document->required_csp()->header->header_value);
951}
952
953TEST_F(CSPEmbeddedEnforcementUnitTest, InvalidCSP) {
954 TestRenderFrameHost* top_document = main_rfh();
955 TestRenderFrameHost* child_document = AddChild(top_document);
956 std::string sec_required_csp =
957 NavigateWithRequiredCSP(&child_document, "report-to group");
958 EXPECT_EQ("", sec_required_csp);
959 EXPECT_FALSE(child_document->required_csp());
960}
961
962TEST_F(CSPEmbeddedEnforcementUnitTest, InvalidCspAndInheritFromParent) {
963 TestRenderFrameHost* top_document = main_rfh();
964 TestRenderFrameHost* child_document = AddChild(top_document);
965 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
966 TestRenderFrameHost* grand_child_document = AddChild(child_document);
967 std::string sec_required_csp =
Antonio Sartori4231e932021-02-04 12:01:14968 NavigateWithRequiredCSP(&grand_child_document, "report-to group");
arthursonzogni898dcda52021-01-21 08:50:10969 EXPECT_EQ("script-src 'none'", sec_required_csp);
970 EXPECT_TRUE(grand_child_document->required_csp());
971 EXPECT_EQ("script-src 'none'",
972 grand_child_document->required_csp()->header->header_value);
973}
974
975TEST_F(CSPEmbeddedEnforcementUnitTest,
976 SemiInvalidCspAndInheritSameCspFromParent) {
977 TestRenderFrameHost* top_document = main_rfh();
978 TestRenderFrameHost* child_document = AddChild(top_document);
979 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
980 TestRenderFrameHost* grand_child_document = AddChild(child_document);
981 std::string sec_required_csp = NavigateWithRequiredCSP(
Antonio Sartori4231e932021-02-04 12:01:14982 &grand_child_document, "script-src 'none'; report-to group");
arthursonzogni898dcda52021-01-21 08:50:10983 EXPECT_EQ("script-src 'none'", sec_required_csp);
984 EXPECT_TRUE(grand_child_document->required_csp());
985 EXPECT_EQ("script-src 'none'",
986 grand_child_document->required_csp()->header->header_value);
987}
988
989TEST_F(CSPEmbeddedEnforcementUnitTest,
990 SemiInvalidCspAndInheritDifferentCspFromParent) {
991 TestRenderFrameHost* top_document = main_rfh();
992 TestRenderFrameHost* child_document = AddChild(top_document);
993 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
994 TestRenderFrameHost* grand_child_document = AddChild(child_document);
995 std::string sec_required_csp = NavigateWithRequiredCSP(
Antonio Sartori4231e932021-02-04 12:01:14996 &grand_child_document, "sandbox; report-to group");
arthursonzogni898dcda52021-01-21 08:50:10997 EXPECT_EQ("script-src 'none'", sec_required_csp);
998 EXPECT_TRUE(grand_child_document->required_csp());
999 EXPECT_EQ("script-src 'none'",
1000 grand_child_document->required_csp()->header->header_value);
1001}
1002
Peter Birk Pakkenberg73e07b62022-09-21 11:20:301003namespace {
1004
1005// Mock that allows us to avoid depending on the origin_trials component.
1006class OriginTrialsControllerDelegateMock
1007 : public OriginTrialsControllerDelegate {
1008 public:
1009 ~OriginTrialsControllerDelegateMock() override = default;
1010
1011 void PersistTrialsFromTokens(
1012 const url::Origin& origin,
Peter Birk Pakkenbergf62286a2023-01-25 19:44:071013 const url::Origin& partition_origin,
Peter Birk Pakkenberg73e07b62022-09-21 11:20:301014 const base::span<const std::string> header_tokens,
1015 const base::Time current_time) override {
1016 persisted_tokens_[origin] =
1017 std::vector<std::string>(header_tokens.begin(), header_tokens.end());
1018 }
1019 bool IsTrialPersistedForOrigin(const url::Origin& origin,
Peter Birk Pakkenbergf62286a2023-01-25 19:44:071020 const url::Origin& partition_origin,
Peter Birk Pakkenberg73e07b62022-09-21 11:20:301021 const base::StringPiece trial_name,
1022 const base::Time current_time) override {
1023 DCHECK(false) << "Method not implemented for test.";
1024 return false;
1025 }
1026
Peter Birk Pakkenberg4c1bb272022-09-27 10:51:291027 base::flat_set<std::string> GetPersistedTrialsForOrigin(
1028 const url::Origin& origin,
Peter Birk Pakkenbergf62286a2023-01-25 19:44:071029 const url::Origin& partition_origin,
Peter Birk Pakkenberg4c1bb272022-09-27 10:51:291030 base::Time current_time) override {
1031 DCHECK(false) << "Method not implemented for test.";
1032 return base::flat_set<std::string>();
1033 }
1034
Peter Birk Pakkenbergd74c6f82022-11-08 17:44:381035 void ClearPersistedTokens() override { persisted_tokens_.clear(); }
1036
Peter Birk Pakkenberg73e07b62022-09-21 11:20:301037 base::flat_map<url::Origin, std::vector<std::string>> persisted_tokens_;
1038};
1039
1040} // namespace
1041
1042class PersistentOriginTrialNavigationRequestTest
1043 : public NavigationRequestTest {
1044 public:
1045 PersistentOriginTrialNavigationRequestTest()
1046 : delegate_mock_(std::make_unique<OriginTrialsControllerDelegateMock>()) {
1047
1048 }
1049 ~PersistentOriginTrialNavigationRequestTest() override = default;
1050
1051 std::vector<std::string> GetPersistedTokens(const url::Origin& origin) {
1052 return delegate_mock_->persisted_tokens_[origin];
1053 }
1054
1055 protected:
1056 std::unique_ptr<BrowserContext> CreateBrowserContext() override {
1057 std::unique_ptr<TestBrowserContext> context =
1058 std::make_unique<TestBrowserContext>();
1059 context->SetOriginTrialsControllerDelegate(delegate_mock_.get());
1060 return context;
1061 }
1062
1063 private:
1064 std::unique_ptr<OriginTrialsControllerDelegateMock> delegate_mock_;
1065};
1066
1067// Ensure that navigations with a valid Origin-Trial header with a persistent
1068// origin trial token results in the trial being marked as enabled.
1069// Then check that subsequent navigations without headers trigger an update
1070// that clears out stored trials.
1071TEST_F(PersistentOriginTrialNavigationRequestTest,
1072 NavigationCommitsPersistentOriginTrials) {
1073 // Generated with:
1074 // tools/origin_trials/generate_token.py https://example.com
1075 // FrobulatePersistent
1076 // --expire-timestamp=2000000000
1077 const char kPersistentOriginTrialToken[] =
1078 "AzZfd1vKZ0SSGRGk/"
1079 "8nIszQSlHYjbuYVE3jwaNZG3X4t11zRhzPWWJwTZ+JJDS3JJsyEZcpz+y20pAP6/"
1080 "6upOQ4AAABdeyJvcmlnaW4iOiAiaHR0cHM6Ly9leGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZ"
1081 "SI"
1082 "6ICJGcm9idWxhdGVQZXJzaXN0ZW50IiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9";
1083
1084 base::test::ScopedFeatureList scoped_feature_list;
1085 scoped_feature_list.InitAndEnableFeature(features::kPersistentOriginTrials);
1086 blink::ScopedTestOriginTrialPolicy origin_trial_policy_;
1087
1088 const GURL kUrl = GURL("https://example.com");
1089 auto navigation =
1090 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
1091
1092 auto response_headers =
1093 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
1094 response_headers->SetHeader("Origin-Trial", kPersistentOriginTrialToken);
1095 navigation->SetResponseHeaders(response_headers);
1096
1097 navigation->Commit();
1098
1099 url::Origin origin = url::Origin::Create(kUrl);
1100 EXPECT_EQ(std::vector<std::string>{kPersistentOriginTrialToken},
1101 GetPersistedTokens(origin));
1102
1103 // Navigate again without response headers to assert the trial information is
1104 // still updated and cleared.
1105 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh())->Commit();
1106 EXPECT_EQ(std::vector<std::string>(), GetPersistedTokens(origin));
1107}
1108
clamy49678312015-10-22 21:59:001109} // namespace content