1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/url_request/url_request_test_util.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/check_op.h"
11 #include "base/compiler_specific.h"
12 #include "base/location.h"
13 #include "base/run_loop.h"
14 #include "base/supports_user_data.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "base/threading/thread.h"
17 #include "net/base/features.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/cert/cert_verifier.h"
20 #include "net/cert/do_nothing_ct_verifier.h"
21 #include "net/cookies/cookie_setting_override.h"
22 #include "net/cookies/cookie_util.h"
23 #include "net/dns/mock_host_resolver.h"
24 #include "net/http/http_network_session.h"
25 #include "net/http/http_response_headers.h"
26 #include "net/http/http_server_properties.h"
27 #include "net/http/transport_security_state.h"
28 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
29 #include "net/proxy_resolution/proxy_retry_info.h"
30 #include "net/quic/quic_context.h"
31 #include "net/url_request/redirect_info.h"
32 #include "net/url_request/static_http_user_agent_settings.h"
33 #include "net/url_request/url_request.h"
34 #include "net/url_request/url_request_context_builder.h"
35 #include "net/url_request/url_request_filter.h"
36 #include "net/url_request/url_request_job.h"
37 #include "net/url_request/url_request_job_factory.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39
40 namespace net {
41
42 namespace {
43
44 // These constants put the NetworkDelegate events of TestNetworkDelegate
45 // into an order. They are used in conjunction with
46 // |TestNetworkDelegate::next_states_| to check that we do not send
47 // events in the wrong order.
48 const int kStageBeforeURLRequest = 1 << 0;
49 const int kStageBeforeStartTransaction = 1 << 1;
50 const int kStageHeadersReceived = 1 << 2;
51 const int kStageBeforeRedirect = 1 << 3;
52 const int kStageBeforeRetry = 1 << 4;
53 const int kStageResponseStarted = 1 << 5;
54 const int kStageCompletedSuccess = 1 << 6;
55 const int kStageCompletedError = 1 << 7;
56 const int kStageURLRequestDestroyed = 1 << 8;
57 const int kStageDestruction = 1 << 9;
58
59 const char kTestNetworkDelegateRequestIdKey[] =
60 "TestNetworkDelegateRequestIdKey";
61
62 class TestRequestId : public base::SupportsUserData::Data {
63 public:
TestRequestId(int id)64 explicit TestRequestId(int id) : id_(id) {}
65 ~TestRequestId() override = default;
66
id() const67 int id() const { return id_; }
68
69 private:
70 const int id_;
71 };
72
73 } // namespace
74
CreateTestURLRequestContextBuilder()75 std::unique_ptr<URLRequestContextBuilder> CreateTestURLRequestContextBuilder() {
76 auto builder = std::make_unique<URLRequestContextBuilder>();
77 builder->set_host_resolver(std::make_unique<MockCachingHostResolver>(
78 /*cache_invalidation_num=*/0,
79 /*default_result=*/MockHostResolverBase::RuleResolver::
80 GetLocalhostResult()));
81 builder->set_proxy_resolution_service(
82 ConfiguredProxyResolutionService::CreateDirect());
83 builder->SetCertVerifier(
84 CertVerifier::CreateDefault(/*cert_net_fetcher=*/nullptr));
85 builder->set_ssl_config_service(std::make_unique<SSLConfigServiceDefaults>());
86 builder->SetHttpAuthHandlerFactory(HttpAuthHandlerFactory::CreateDefault());
87 builder->SetHttpServerProperties(std::make_unique<HttpServerProperties>());
88 builder->set_quic_context(std::make_unique<QuicContext>());
89 builder->SetCookieStore(std::make_unique<CookieMonster>(/*store=*/nullptr,
90 /*netlog=*/nullptr));
91 builder->set_http_user_agent_settings(
92 std::make_unique<StaticHttpUserAgentSettings>("en-us,fr", std::string()));
93 return builder;
94 }
95
TestURLRequestContextGetter(const scoped_refptr<base::SingleThreadTaskRunner> & network_task_runner)96 TestURLRequestContextGetter::TestURLRequestContextGetter(
97 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner)
98 : network_task_runner_(network_task_runner) {
99 DCHECK(network_task_runner_.get());
100 }
101
TestURLRequestContextGetter(const scoped_refptr<base::SingleThreadTaskRunner> & network_task_runner,std::unique_ptr<URLRequestContext> context)102 TestURLRequestContextGetter::TestURLRequestContextGetter(
103 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner,
104 std::unique_ptr<URLRequestContext> context)
105 : network_task_runner_(network_task_runner), context_(std::move(context)) {
106 DCHECK(network_task_runner_.get());
107 }
108
109 TestURLRequestContextGetter::~TestURLRequestContextGetter() = default;
110
GetURLRequestContext()111 URLRequestContext* TestURLRequestContextGetter::GetURLRequestContext() {
112 if (is_shut_down_)
113 return nullptr;
114
115 if (!context_.get())
116 context_ = CreateTestURLRequestContextBuilder()->Build();
117 return context_.get();
118 }
119
NotifyContextShuttingDown()120 void TestURLRequestContextGetter::NotifyContextShuttingDown() {
121 // This should happen before call to base NotifyContextShuttingDown() per that
122 // method's doc comments.
123 is_shut_down_ = true;
124
125 URLRequestContextGetter::NotifyContextShuttingDown();
126 context_ = nullptr;
127 }
128
129 scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const130 TestURLRequestContextGetter::GetNetworkTaskRunner() const {
131 return network_task_runner_;
132 }
133
134 const int TestDelegate::kBufferSize;
135
TestDelegate()136 TestDelegate::TestDelegate()
137 : buf_(base::MakeRefCounted<IOBufferWithSize>(kBufferSize)) {}
138
139 TestDelegate::~TestDelegate() = default;
140
RunUntilComplete()141 void TestDelegate::RunUntilComplete() {
142 base::RunLoop run_loop;
143 on_complete_ = run_loop.QuitClosure();
144 run_loop.Run();
145 }
146
RunUntilRedirect()147 void TestDelegate::RunUntilRedirect() {
148 base::RunLoop run_loop;
149 on_redirect_ = run_loop.QuitClosure();
150 run_loop.Run();
151 }
152
RunUntilAuthRequired()153 void TestDelegate::RunUntilAuthRequired() {
154 base::RunLoop run_loop;
155 on_auth_required_ = run_loop.QuitClosure();
156 run_loop.Run();
157 }
158
OnConnected(URLRequest * request,const TransportInfo & info,CompletionOnceCallback callback)159 int TestDelegate::OnConnected(URLRequest* request,
160 const TransportInfo& info,
161 CompletionOnceCallback callback) {
162 transports_.push_back(info);
163
164 if (on_connected_run_callback_) {
165 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
166 FROM_HERE, base::BindOnce(std::move(callback), on_connected_result_));
167 return net::ERR_IO_PENDING;
168 }
169
170 return on_connected_result_;
171 }
172
OnReceivedRedirect(URLRequest * request,const RedirectInfo & redirect_info,bool * defer_redirect)173 void TestDelegate::OnReceivedRedirect(URLRequest* request,
174 const RedirectInfo& redirect_info,
175 bool* defer_redirect) {
176 EXPECT_TRUE(request->is_redirecting());
177
178 redirect_info_ = redirect_info;
179
180 received_redirect_count_++;
181 if (on_redirect_) {
182 *defer_redirect = true;
183 std::move(on_redirect_).Run();
184 } else if (cancel_in_rr_) {
185 request->Cancel();
186 }
187 }
188
OnAuthRequired(URLRequest * request,const AuthChallengeInfo & auth_info)189 void TestDelegate::OnAuthRequired(URLRequest* request,
190 const AuthChallengeInfo& auth_info) {
191 auth_required_ = true;
192 if (on_auth_required_) {
193 std::move(on_auth_required_).Run();
194 return;
195 }
196 if (!credentials_.Empty()) {
197 request->SetAuth(credentials_);
198 } else {
199 request->CancelAuth();
200 }
201 }
202
OnSSLCertificateError(URLRequest * request,int net_error,const SSLInfo & ssl_info,bool fatal)203 void TestDelegate::OnSSLCertificateError(URLRequest* request,
204 int net_error,
205 const SSLInfo& ssl_info,
206 bool fatal) {
207 // The caller can control whether it needs all SSL requests to go through,
208 // independent of any possible errors, or whether it wants SSL errors to
209 // cancel the request.
210 have_certificate_errors_ = true;
211 certificate_errors_are_fatal_ = fatal;
212 certificate_net_error_ = net_error;
213 if (allow_certificate_errors_)
214 request->ContinueDespiteLastError();
215 else
216 request->Cancel();
217 }
218
OnResponseStarted(URLRequest * request,int net_error)219 void TestDelegate::OnResponseStarted(URLRequest* request, int net_error) {
220 // It doesn't make sense for the request to have IO pending at this point.
221 DCHECK_NE(ERR_IO_PENDING, net_error);
222 EXPECT_FALSE(request->is_redirecting());
223
224 response_started_count_++;
225 request_status_ = net_error;
226 if (cancel_in_rs_) {
227 request_status_ = request->Cancel();
228 // Canceling |request| will cause OnResponseCompleted() to be called.
229 } else if (net_error != OK) {
230 request_failed_ = true;
231 OnResponseCompleted(request);
232 } else {
233 // Initiate the first read.
234 int bytes_read = request->Read(buf_.get(), kBufferSize);
235 if (bytes_read >= 0)
236 OnReadCompleted(request, bytes_read);
237 else if (bytes_read != ERR_IO_PENDING)
238 OnResponseCompleted(request);
239 }
240 }
241
OnReadCompleted(URLRequest * request,int bytes_read)242 void TestDelegate::OnReadCompleted(URLRequest* request, int bytes_read) {
243 // It doesn't make sense for the request to have IO pending at this point.
244 DCHECK_NE(bytes_read, ERR_IO_PENDING);
245
246 // If you've reached this, you've either called "RunUntilComplete"
247 // If this DCHECK fails, that probably means you've run
248 // "RunUntilRedirect" or "RunUntilAuthRequired" and haven't
249 // redirected/auth-challenged
250 DCHECK(on_complete_);
251
252 // If the request was cancelled in a redirect, it should not signal
253 // OnReadCompleted. Note that |cancel_in_rs_| may be true due to
254 // https://crbug.com/564848.
255 EXPECT_FALSE(cancel_in_rr_);
256
257 if (response_started_count_ == 0)
258 received_data_before_response_ = true;
259
260 if (bytes_read >= 0) {
261 // There is data to read.
262 received_bytes_count_ += bytes_read;
263
264 // Consume the data.
265 data_received_.append(buf_->data(), bytes_read);
266
267 if (cancel_in_rd_) {
268 request_status_ = request->Cancel();
269 // If bytes_read is 0, won't get a notification on cancelation.
270 if (bytes_read == 0) {
271 std::move(on_complete_).Run();
272 }
273 return;
274 }
275 }
276
277 // If it was not end of stream, request to read more.
278 while (bytes_read > 0) {
279 bytes_read = request->Read(buf_.get(), kBufferSize);
280 if (bytes_read > 0) {
281 data_received_.append(buf_->data(), bytes_read);
282 received_bytes_count_ += bytes_read;
283 }
284 }
285
286 request_status_ = bytes_read;
287 if (request_status_ != ERR_IO_PENDING)
288 OnResponseCompleted(request);
289 else if (cancel_in_rd_pending_)
290 request_status_ = request->Cancel();
291 }
292
OnResponseCompleted(URLRequest * request)293 void TestDelegate::OnResponseCompleted(URLRequest* request) {
294 response_completed_ = true;
295 std::move(on_complete_).Run();
296 }
297
298 TestNetworkDelegate::TestNetworkDelegate() = default;
299
~TestNetworkDelegate()300 TestNetworkDelegate::~TestNetworkDelegate() {
301 for (auto i = next_states_.begin(); i != next_states_.end(); ++i) {
302 event_order_[i->first] += "~TestNetworkDelegate\n";
303 EXPECT_TRUE(i->second & kStageDestruction) << event_order_[i->first];
304 }
305 }
306
GetLoadTimingInfoBeforeRedirect(LoadTimingInfo * load_timing_info_before_redirect) const307 bool TestNetworkDelegate::GetLoadTimingInfoBeforeRedirect(
308 LoadTimingInfo* load_timing_info_before_redirect) const {
309 *load_timing_info_before_redirect = load_timing_info_before_redirect_;
310 return has_load_timing_info_before_redirect_;
311 }
312
InitRequestStatesIfNew(int request_id)313 void TestNetworkDelegate::InitRequestStatesIfNew(int request_id) {
314 if (next_states_.find(request_id) == next_states_.end()) {
315 // TODO(davidben): Although the URLRequest documentation does not allow
316 // calling Cancel() before Start(), the ResourceLoader does so. URLRequest's
317 // destructor also calls Cancel. Either officially support this or fix the
318 // ResourceLoader code.
319 next_states_[request_id] = kStageBeforeURLRequest | kStageCompletedError;
320 event_order_[request_id] = "";
321 }
322 }
323
OnBeforeURLRequest(URLRequest * request,CompletionOnceCallback callback,GURL * new_url)324 int TestNetworkDelegate::OnBeforeURLRequest(URLRequest* request,
325 CompletionOnceCallback callback,
326 GURL* new_url) {
327 int req_id = GetRequestId(request);
328 InitRequestStatesIfNew(req_id);
329 event_order_[req_id] += "OnBeforeURLRequest\n";
330 EXPECT_TRUE(next_states_[req_id] & kStageBeforeURLRequest) <<
331 event_order_[req_id];
332 next_states_[req_id] =
333 kStageBeforeStartTransaction |
334 kStageResponseStarted | // data: URLs do not trigger sending headers
335 kStageBeforeRedirect | // a delegate can trigger a redirection
336 kStageCompletedError; // request canceled by delegate
337 created_requests_++;
338 return OK;
339 }
340
OnBeforeStartTransaction(URLRequest * request,const HttpRequestHeaders & headers,OnBeforeStartTransactionCallback callback)341 int TestNetworkDelegate::OnBeforeStartTransaction(
342 URLRequest* request,
343 const HttpRequestHeaders& headers,
344 OnBeforeStartTransactionCallback callback) {
345 if (before_start_transaction_fails_)
346 return ERR_FAILED;
347
348 int req_id = GetRequestId(request);
349 InitRequestStatesIfNew(req_id);
350 event_order_[req_id] += "OnBeforeStartTransaction\n";
351 EXPECT_TRUE(next_states_[req_id] & kStageBeforeStartTransaction)
352 << event_order_[req_id];
353 next_states_[req_id] =
354 kStageHeadersReceived | kStageCompletedError | kStageBeforeRedirect;
355 before_start_transaction_count_++;
356 return OK;
357 }
358
OnHeadersReceived(URLRequest * request,CompletionOnceCallback callback,const HttpResponseHeaders * original_response_headers,scoped_refptr<HttpResponseHeaders> * override_response_headers,const IPEndPoint & endpoint,std::optional<GURL> * preserve_fragment_on_redirect_url)359 int TestNetworkDelegate::OnHeadersReceived(
360 URLRequest* request,
361 CompletionOnceCallback callback,
362 const HttpResponseHeaders* original_response_headers,
363 scoped_refptr<HttpResponseHeaders>* override_response_headers,
364 const IPEndPoint& endpoint,
365 std::optional<GURL>* preserve_fragment_on_redirect_url) {
366 EXPECT_FALSE(preserve_fragment_on_redirect_url->has_value());
367 int req_id = GetRequestId(request);
368 bool is_first_response =
369 event_order_[req_id].find("OnHeadersReceived\n") == std::string::npos;
370 event_order_[req_id] += "OnHeadersReceived\n";
371 InitRequestStatesIfNew(req_id);
372 EXPECT_TRUE(next_states_[req_id] & kStageHeadersReceived) <<
373 event_order_[req_id];
374 next_states_[req_id] = kStageBeforeRedirect | kStageBeforeRetry |
375 kStageResponseStarted |
376 kStageCompletedError; // e.g. proxy resolution problem
377
378 // Basic authentication sends a second request from the URLRequestHttpJob
379 // layer before the URLRequest reports that a response has started.
380 next_states_[req_id] |= kStageBeforeStartTransaction;
381
382 if (!redirect_on_headers_received_url_.is_empty()) {
383 *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>(
384 original_response_headers->raw_headers());
385 (*override_response_headers)->ReplaceStatusLine("HTTP/1.1 302 Found");
386 (*override_response_headers)->RemoveHeader("Location");
387 (*override_response_headers)
388 ->AddHeader("Location", redirect_on_headers_received_url_.spec());
389
390 redirect_on_headers_received_url_ = GURL();
391
392 // Since both values are std::optionals, can just copy this over.
393 *preserve_fragment_on_redirect_url = preserve_fragment_on_redirect_url_;
394 } else if (add_header_to_first_response_ && is_first_response) {
395 *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>(
396 original_response_headers->raw_headers());
397 (*override_response_headers)
398 ->AddHeader("X-Network-Delegate", "Greetings, planet");
399 }
400
401 headers_received_count_++;
402 return OK;
403 }
404
OnBeforeRedirect(URLRequest * request,const GURL & new_location)405 void TestNetworkDelegate::OnBeforeRedirect(URLRequest* request,
406 const GURL& new_location) {
407 load_timing_info_before_redirect_ = LoadTimingInfo();
408 request->GetLoadTimingInfo(&load_timing_info_before_redirect_);
409 has_load_timing_info_before_redirect_ = true;
410 EXPECT_FALSE(load_timing_info_before_redirect_.request_start_time.is_null());
411 EXPECT_FALSE(load_timing_info_before_redirect_.request_start.is_null());
412
413 int req_id = GetRequestId(request);
414 InitRequestStatesIfNew(req_id);
415 event_order_[req_id] += "OnBeforeRedirect\n";
416 EXPECT_TRUE(next_states_[req_id] & kStageBeforeRedirect) <<
417 event_order_[req_id];
418 next_states_[req_id] =
419 kStageBeforeURLRequest | // HTTP redirects trigger this.
420 kStageBeforeStartTransaction | // Redirects from the network delegate do
421 // not
422 // trigger onBeforeURLRequest.
423 kStageCompletedError;
424
425 // A redirect can lead to a file or a data URL. In this case, we do not send
426 // headers.
427 next_states_[req_id] |= kStageResponseStarted;
428 }
429
OnBeforeRetry(URLRequest * request)430 void TestNetworkDelegate::OnBeforeRetry(URLRequest* request) {
431 int req_id = GetRequestId(request);
432 InitRequestStatesIfNew(req_id);
433 event_order_[req_id] += "OnBeforeRetry\n";
434 EXPECT_TRUE(next_states_[req_id] & kStageBeforeRetry) << event_order_[req_id];
435 next_states_[req_id] = kStageBeforeURLRequest;
436 }
437
OnResponseStarted(URLRequest * request,int net_error)438 void TestNetworkDelegate::OnResponseStarted(URLRequest* request,
439 int net_error) {
440 DCHECK_NE(ERR_IO_PENDING, net_error);
441
442 LoadTimingInfo load_timing_info;
443 request->GetLoadTimingInfo(&load_timing_info);
444 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
445 EXPECT_FALSE(load_timing_info.request_start.is_null());
446
447 int req_id = GetRequestId(request);
448 InitRequestStatesIfNew(req_id);
449 event_order_[req_id] += "OnResponseStarted\n";
450 EXPECT_TRUE(next_states_[req_id] & kStageResponseStarted)
451 << event_order_[req_id];
452 next_states_[req_id] = kStageCompletedSuccess | kStageCompletedError;
453 if (net_error == ERR_ABORTED)
454 return;
455
456 if (net_error != OK) {
457 error_count_++;
458 last_error_ = net_error;
459 }
460 }
461
OnCompleted(URLRequest * request,bool started,int net_error)462 void TestNetworkDelegate::OnCompleted(URLRequest* request,
463 bool started,
464 int net_error) {
465 DCHECK_NE(net_error, net::ERR_IO_PENDING);
466
467 int req_id = GetRequestId(request);
468 InitRequestStatesIfNew(req_id);
469 event_order_[req_id] += "OnCompleted\n";
470 // Expect "Success -> (next_states_ & kStageCompletedSuccess)"
471 // is logically identical to
472 // Expect "!(Success) || (next_states_ & kStageCompletedSuccess)"
473 EXPECT_TRUE(net_error != OK ||
474 (next_states_[req_id] & kStageCompletedSuccess))
475 << event_order_[req_id];
476 EXPECT_TRUE(net_error == OK || (next_states_[req_id] & kStageCompletedError))
477 << event_order_[req_id];
478 next_states_[req_id] = kStageURLRequestDestroyed;
479 completed_requests_++;
480 if (net_error == ERR_ABORTED) {
481 canceled_requests_++;
482 } else if (net_error != OK) {
483 error_count_++;
484 last_error_ = net_error;
485 } else {
486 DCHECK_EQ(OK, net_error);
487 }
488 }
489
OnURLRequestDestroyed(URLRequest * request)490 void TestNetworkDelegate::OnURLRequestDestroyed(URLRequest* request) {
491 int req_id = GetRequestId(request);
492 InitRequestStatesIfNew(req_id);
493 event_order_[req_id] += "OnURLRequestDestroyed\n";
494 EXPECT_TRUE(next_states_[req_id] & kStageURLRequestDestroyed) <<
495 event_order_[req_id];
496 next_states_[req_id] = kStageDestruction;
497 destroyed_requests_++;
498 }
499
OnAnnotateAndMoveUserBlockedCookies(const URLRequest & request,const net::FirstPartySetMetadata & first_party_set_metadata,net::CookieAccessResultList & maybe_included_cookies,net::CookieAccessResultList & excluded_cookies)500 bool TestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies(
501 const URLRequest& request,
502 const net::FirstPartySetMetadata& first_party_set_metadata,
503 net::CookieAccessResultList& maybe_included_cookies,
504 net::CookieAccessResultList& excluded_cookies) {
505 RecordCookieSettingOverrides(request.cookie_setting_overrides());
506 bool allow = true;
507 if (cookie_options_bit_mask_ & NO_GET_COOKIES)
508 allow = false;
509
510 if (!allow) {
511 blocked_annotate_cookies_count_++;
512 ExcludeAllCookies(CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
513 maybe_included_cookies, excluded_cookies);
514 }
515
516 return allow;
517 }
518
OnForcePrivacyMode(const URLRequest & request) const519 NetworkDelegate::PrivacySetting TestNetworkDelegate::OnForcePrivacyMode(
520 const URLRequest& request) const {
521 RecordCookieSettingOverrides(request.cookie_setting_overrides());
522 return NetworkDelegate::PrivacySetting::kStateAllowed;
523 }
524
OnCanSetCookie(const URLRequest & request,const net::CanonicalCookie & cookie,CookieOptions * options,const net::FirstPartySetMetadata & first_party_set_metadata,CookieInclusionStatus * inclusion_status)525 bool TestNetworkDelegate::OnCanSetCookie(
526 const URLRequest& request,
527 const net::CanonicalCookie& cookie,
528 CookieOptions* options,
529 const net::FirstPartySetMetadata& first_party_set_metadata,
530 CookieInclusionStatus* inclusion_status) {
531 RecordCookieSettingOverrides(request.cookie_setting_overrides());
532 bool allow = true;
533 if (cookie_options_bit_mask_ & NO_SET_COOKIE)
534 allow = false;
535
536 if (!allow) {
537 blocked_set_cookie_count_++;
538 } else {
539 set_cookie_count_++;
540 }
541
542 return allow;
543 }
544
OnCancelURLRequestWithPolicyViolatingReferrerHeader(const URLRequest & request,const GURL & target_url,const GURL & referrer_url) const545 bool TestNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
546 const URLRequest& request,
547 const GURL& target_url,
548 const GURL& referrer_url) const {
549 return cancel_request_with_policy_violating_referrer_;
550 }
551
GetRequestId(URLRequest * request)552 int TestNetworkDelegate::GetRequestId(URLRequest* request) {
553 TestRequestId* test_request_id = reinterpret_cast<TestRequestId*>(
554 request->GetUserData(kTestNetworkDelegateRequestIdKey));
555 if (test_request_id)
556 return test_request_id->id();
557 int id = next_request_id_++;
558 request->SetUserData(kTestNetworkDelegateRequestIdKey,
559 std::make_unique<TestRequestId>(id));
560 return id;
561 }
562
563 std::optional<cookie_util::StorageAccessStatus>
OnGetStorageAccessStatus(const URLRequest & request,base::optional_ref<const RedirectInfo> redirect_info) const564 TestNetworkDelegate::OnGetStorageAccessStatus(
565 const URLRequest& request,
566 base::optional_ref<const RedirectInfo> redirect_info) const {
567 return storage_access_status_;
568 }
569
OnIsStorageAccessHeaderEnabled(const url::Origin * top_frame_origin,const GURL & url) const570 bool TestNetworkDelegate::OnIsStorageAccessHeaderEnabled(
571 const url::Origin* top_frame_origin,
572 const GURL& url) const {
573 return is_storage_access_header_enabled_;
574 }
575
576 FilteringTestNetworkDelegate::FilteringTestNetworkDelegate() = default;
577 FilteringTestNetworkDelegate::~FilteringTestNetworkDelegate() = default;
578
OnCanSetCookie(const URLRequest & request,const net::CanonicalCookie & cookie,CookieOptions * options,const net::FirstPartySetMetadata & first_party_set_metadata,CookieInclusionStatus * inclusion_status)579 bool FilteringTestNetworkDelegate::OnCanSetCookie(
580 const URLRequest& request,
581 const net::CanonicalCookie& cookie,
582 CookieOptions* options,
583 const net::FirstPartySetMetadata& first_party_set_metadata,
584 CookieInclusionStatus* inclusion_status) {
585 // Filter out cookies with the same name as |cookie_name_filter_| and
586 // combine with |allowed_from_caller|.
587 bool allowed = cookie.Name() != cookie_name_filter_;
588
589 ++set_cookie_called_count_;
590
591 if (!allowed)
592 ++blocked_set_cookie_count_;
593
594 // Call the nested delegate's method first to avoid a short circuit.
595 return TestNetworkDelegate::OnCanSetCookie(request, cookie, options,
596 first_party_set_metadata,
597 inclusion_status) &&
598 allowed;
599 }
600
601 NetworkDelegate::PrivacySetting
OnForcePrivacyMode(const URLRequest & request) const602 FilteringTestNetworkDelegate::OnForcePrivacyMode(
603 const URLRequest& request) const {
604 if (force_privacy_mode_) {
605 return partitioned_state_allowed_
606 ? NetworkDelegate::PrivacySetting::kPartitionedStateAllowedOnly
607 : NetworkDelegate::PrivacySetting::kStateDisallowed;
608 }
609
610 return TestNetworkDelegate::OnForcePrivacyMode(request);
611 }
612
OnAnnotateAndMoveUserBlockedCookies(const URLRequest & request,const net::FirstPartySetMetadata & first_party_set_metadata,net::CookieAccessResultList & maybe_included_cookies,net::CookieAccessResultList & excluded_cookies)613 bool FilteringTestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies(
614 const URLRequest& request,
615 const net::FirstPartySetMetadata& first_party_set_metadata,
616 net::CookieAccessResultList& maybe_included_cookies,
617 net::CookieAccessResultList& excluded_cookies) {
618 // Filter out cookies if |block_annotate_cookies_| is set and
619 // combine with |allowed_from_caller|.
620 bool allowed = !block_annotate_cookies_;
621
622 ++annotate_cookies_called_count_;
623
624 if (!allowed) {
625 ++blocked_annotate_cookies_count_;
626 ExcludeAllCookies(net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
627 maybe_included_cookies, excluded_cookies);
628 }
629
630 if (allowed && block_get_cookies_by_name_ && !cookie_name_filter_.empty()) {
631 for (auto& cookie : maybe_included_cookies) {
632 if (cookie.cookie.Name().find(cookie_name_filter_) != std::string::npos) {
633 cookie.access_result.status.AddExclusionReason(
634 net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
635 }
636 }
637 for (auto& cookie : excluded_cookies) {
638 if (cookie.cookie.Name().find(cookie_name_filter_) != std::string::npos) {
639 cookie.access_result.status.AddExclusionReason(
640 net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
641 }
642 }
643
644 MoveExcludedCookies(maybe_included_cookies, excluded_cookies);
645 }
646
647 // Call the nested delegate's method first to avoid a short circuit.
648 return TestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies(
649 request, first_party_set_metadata, maybe_included_cookies,
650 excluded_cookies) &&
651 allowed;
652 }
653
654 // URLRequestInterceptor that intercepts only the first request it sees,
655 // returning the provided URLRequestJob.
656 class TestScopedURLInterceptor::TestRequestInterceptor
657 : public URLRequestInterceptor {
658 public:
TestRequestInterceptor(std::unique_ptr<URLRequestJob> intercept_job)659 explicit TestRequestInterceptor(std::unique_ptr<URLRequestJob> intercept_job)
660 : intercept_job_(std::move(intercept_job)) {}
661
~TestRequestInterceptor()662 ~TestRequestInterceptor() override { CHECK(safe_to_delete_); }
663
MaybeInterceptRequest(URLRequest * request) const664 std::unique_ptr<URLRequestJob> MaybeInterceptRequest(
665 URLRequest* request) const override {
666 return std::move(intercept_job_);
667 }
668
job_used() const669 bool job_used() const { return intercept_job_.get() == nullptr; }
set_safe_to_delete()670 void set_safe_to_delete() { safe_to_delete_ = true; }
671
672 private:
673 mutable std::unique_ptr<URLRequestJob> intercept_job_;
674 // This is used to catch chases where the TestRequestInterceptor is destroyed
675 // before the TestScopedURLInterceptor.
676 bool safe_to_delete_ = false;
677 };
678
TestScopedURLInterceptor(const GURL & url,std::unique_ptr<URLRequestJob> intercept_job)679 TestScopedURLInterceptor::TestScopedURLInterceptor(
680 const GURL& url,
681 std::unique_ptr<URLRequestJob> intercept_job)
682 : url_(url) {
683 std::unique_ptr<TestRequestInterceptor> interceptor =
684 std::make_unique<TestRequestInterceptor>(std::move(intercept_job));
685 interceptor_ = interceptor.get();
686 URLRequestFilter::GetInstance()->AddUrlInterceptor(url_,
687 std::move(interceptor));
688 }
689
~TestScopedURLInterceptor()690 TestScopedURLInterceptor::~TestScopedURLInterceptor() {
691 DCHECK(interceptor_->job_used());
692 interceptor_->set_safe_to_delete();
693 interceptor_ = nullptr;
694 URLRequestFilter::GetInstance()->RemoveUrlHandler(url_);
695 }
696
697 } // namespace net
698