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