xref: /aosp_15_r20/external/cronet/net/cert_net/cert_net_fetcher_url_request_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 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/cert_net/cert_net_fetcher_url_request.h"
6 
7 #include <memory>
8 #include <string>
9 #include <utility>
10 
11 #include "base/functional/bind.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/message_loop/message_pump_type.h"
14 #include "base/run_loop.h"
15 #include "base/synchronization/lock.h"
16 #include "net/cert/cert_net_fetcher.h"
17 #include "net/cert/mock_cert_verifier.h"
18 #include "net/cert/multi_log_ct_verifier.h"
19 #include "net/dns/mock_host_resolver.h"
20 #include "net/dns/public/secure_dns_policy.h"
21 #include "net/http/http_server_properties.h"
22 #include "net/http/transport_security_state.h"
23 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
24 #include "net/quic/quic_context.h"
25 #include "net/test/embedded_test_server/embedded_test_server.h"
26 #include "net/test/gtest_util.h"
27 #include "net/test/test_with_task_environment.h"
28 #include "net/test/url_request/url_request_hanging_read_job.h"
29 #include "net/traffic_annotation/network_traffic_annotation_test_helper.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_interceptor.h"
33 #include "net/url_request/url_request_job_factory.h"
34 #include "net/url_request/url_request_test_util.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "testing/platform_test.h"
38 
39 using net::test::IsOk;
40 
41 // TODO(eroman): Test that cookies aren't sent.
42 
43 namespace net {
44 
45 namespace {
46 
47 const base::FilePath::CharType kDocRoot[] =
48     FILE_PATH_LITERAL("net/data/cert_net_fetcher_impl_unittest");
49 
50 const char kMockSecureDnsHostname[] = "mock.secure.dns.check";
51 
52 // Wait for the request to complete, and verify that it completed successfully
53 // with the indicated bytes.
VerifySuccess(const std::string & expected_body,CertNetFetcher::Request * request)54 void VerifySuccess(const std::string& expected_body,
55                    CertNetFetcher::Request* request) {
56   Error actual_error;
57   std::vector<uint8_t> actual_body;
58   request->WaitForResult(&actual_error, &actual_body);
59 
60   EXPECT_THAT(actual_error, IsOk());
61   EXPECT_EQ(expected_body, std::string(actual_body.begin(), actual_body.end()));
62 }
63 
64 // Wait for the request to complete, and verify that it completed with the
65 // indicated failure.
VerifyFailure(Error expected_error,CertNetFetcher::Request * request)66 void VerifyFailure(Error expected_error, CertNetFetcher::Request* request) {
67   Error actual_error;
68   std::vector<uint8_t> actual_body;
69   request->WaitForResult(&actual_error, &actual_body);
70 
71   EXPECT_EQ(expected_error, actual_error);
72   EXPECT_EQ(0u, actual_body.size());
73 }
74 
75 struct NetworkThreadState {
76   std::unique_ptr<URLRequestContext> context;
77   // Owned by `context`.
78   raw_ptr<TestNetworkDelegate> network_delegate;
79 };
80 
81 class CertNetFetcherURLRequestTest : public PlatformTest {
82  public:
CertNetFetcherURLRequestTest()83   CertNetFetcherURLRequestTest() {
84     test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
85     StartNetworkThread();
86   }
87 
~CertNetFetcherURLRequestTest()88   ~CertNetFetcherURLRequestTest() override {
89     if (!network_thread_)
90       return;
91     network_thread_->task_runner()->PostTask(
92         FROM_HERE,
93         base::BindOnce(&CertNetFetcherURLRequestTest::TeardownOnNetworkThread,
94                        base::Unretained(this)));
95     network_thread_->Stop();
96   }
97 
98  protected:
fetcher() const99   CertNetFetcher* fetcher() const { return fetcher_.get(); }
100 
CreateFetcherOnNetworkThread(base::WaitableEvent * done)101   void CreateFetcherOnNetworkThread(base::WaitableEvent* done) {
102     fetcher_ = base::MakeRefCounted<CertNetFetcherURLRequest>();
103     fetcher_->SetURLRequestContext(state_->context.get());
104     done->Signal();
105   }
106 
CreateFetcher()107   void CreateFetcher() {
108     base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
109                              base::WaitableEvent::InitialState::NOT_SIGNALED);
110     network_thread_->task_runner()->PostTask(
111         FROM_HERE,
112         base::BindOnce(
113             &CertNetFetcherURLRequestTest::CreateFetcherOnNetworkThread,
114             base::Unretained(this), &done));
115     done.Wait();
116   }
117 
ShutDownFetcherOnNetworkThread(base::WaitableEvent * done)118   void ShutDownFetcherOnNetworkThread(base::WaitableEvent* done) {
119     fetcher_->Shutdown();
120     done->Signal();
121   }
122 
ShutDownFetcher()123   void ShutDownFetcher() {
124     base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
125                              base::WaitableEvent::InitialState::NOT_SIGNALED);
126     network_thread_->task_runner()->PostTask(
127         FROM_HERE,
128         base::BindOnce(
129             &CertNetFetcherURLRequestTest::ShutDownFetcherOnNetworkThread,
130             base::Unretained(this), &done));
131     done.Wait();
132   }
133 
NumCreatedRequests()134   int NumCreatedRequests() {
135     int count = 0;
136     base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
137                              base::WaitableEvent::InitialState::NOT_SIGNALED);
138     network_thread_->task_runner()->PostTask(
139         FROM_HERE,
140         base::BindOnce(&CertNetFetcherURLRequestTest::CountCreatedRequests,
141                        base::Unretained(this), &count, &done));
142     done.Wait();
143     return count;
144   }
145 
StartNetworkThread()146   void StartNetworkThread() {
147     // Start the network thread.
148     network_thread_ = std::make_unique<base::Thread>("network thread");
149     base::Thread::Options options(base::MessagePumpType::IO, 0);
150     EXPECT_TRUE(network_thread_->StartWithOptions(std::move(options)));
151 
152     // Initialize the URLRequestContext (and wait till it has completed).
153     base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
154                              base::WaitableEvent::InitialState::NOT_SIGNALED);
155     network_thread_->task_runner()->PostTask(
156         FROM_HERE,
157         base::BindOnce(&CertNetFetcherURLRequestTest::InitOnNetworkThread,
158                        base::Unretained(this), &done));
159     done.Wait();
160   }
161 
InitOnNetworkThread(base::WaitableEvent * done)162   void InitOnNetworkThread(base::WaitableEvent* done) {
163     state_ = std::make_unique<NetworkThreadState>();
164     auto builder = CreateTestURLRequestContextBuilder();
165     state_->network_delegate =
166         builder->set_network_delegate(std::make_unique<TestNetworkDelegate>());
167     state_->context = builder->Build();
168     done->Signal();
169   }
170 
ResetStateOnNetworkThread(base::WaitableEvent * done)171   void ResetStateOnNetworkThread(base::WaitableEvent* done) {
172     state_.reset();
173     done->Signal();
174   }
175 
ResetState()176   void ResetState() {
177     base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
178                              base::WaitableEvent::InitialState::NOT_SIGNALED);
179     network_thread_->task_runner()->PostTask(
180         FROM_HERE,
181         base::BindOnce(&CertNetFetcherURLRequestTest::ResetStateOnNetworkThread,
182                        base::Unretained(this), &done));
183     done.Wait();
184   }
185 
TeardownOnNetworkThread()186   void TeardownOnNetworkThread() {
187     fetcher_->Shutdown();
188     state_.reset();
189     fetcher_ = nullptr;
190   }
191 
CountCreatedRequests(int * count,base::WaitableEvent * done)192   void CountCreatedRequests(int* count, base::WaitableEvent* done) {
193     *count = state_->network_delegate->created_requests();
194     done->Signal();
195   }
196 
197   EmbeddedTestServer test_server_;
198   std::unique_ptr<base::Thread> network_thread_;
199   scoped_refptr<CertNetFetcherURLRequest> fetcher_;
200 
201   std::unique_ptr<NetworkThreadState> state_;
202 };
203 
204 // Installs URLRequestHangingReadJob handlers and clears them on teardown.
205 class CertNetFetcherURLRequestTestWithHangingReadHandler
206     : public CertNetFetcherURLRequestTest,
207       public WithTaskEnvironment {
208  protected:
SetUp()209   void SetUp() override { URLRequestHangingReadJob::AddUrlHandler(); }
210 
TearDown()211   void TearDown() override { URLRequestFilter::GetInstance()->ClearHandlers(); }
212 };
213 
214 // Interceptor to check that secure DNS has been disabled.
215 class SecureDnsInterceptor : public net::URLRequestInterceptor {
216  public:
SecureDnsInterceptor(bool * invoked_interceptor)217   explicit SecureDnsInterceptor(bool* invoked_interceptor)
218       : invoked_interceptor_(invoked_interceptor) {}
219   ~SecureDnsInterceptor() override = default;
220 
221  private:
222   // URLRequestInterceptor implementation:
MaybeInterceptRequest(net::URLRequest * request) const223   std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
224       net::URLRequest* request) const override {
225     EXPECT_EQ(SecureDnsPolicy::kDisable, request->secure_dns_policy());
226     *invoked_interceptor_ = true;
227     return nullptr;
228   }
229 
230   raw_ptr<bool> invoked_interceptor_;
231 };
232 
233 class CertNetFetcherURLRequestTestWithSecureDnsInterceptor
234     : public CertNetFetcherURLRequestTest,
235       public WithTaskEnvironment {
236  public:
237   CertNetFetcherURLRequestTestWithSecureDnsInterceptor() = default;
238 
SetUp()239   void SetUp() override {
240     URLRequestFilter::GetInstance()->AddHostnameInterceptor(
241         "http", kMockSecureDnsHostname,
242         std::make_unique<SecureDnsInterceptor>(&invoked_interceptor_));
243   }
244 
TearDown()245   void TearDown() override { URLRequestFilter::GetInstance()->ClearHandlers(); }
246 
invoked_interceptor()247   bool invoked_interceptor() { return invoked_interceptor_; }
248 
249  private:
250   bool invoked_interceptor_ = false;
251 };
252 
253 // Helper to start an AIA fetch using default parameters.
StartRequest(CertNetFetcher * fetcher,const GURL & url)254 [[nodiscard]] std::unique_ptr<CertNetFetcher::Request> StartRequest(
255     CertNetFetcher* fetcher,
256     const GURL& url) {
257   return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT,
258                                  CertNetFetcher::DEFAULT);
259 }
260 
261 // Fetch a few unique URLs using GET in parallel. Each URL has a different body
262 // and Content-Type.
TEST_F(CertNetFetcherURLRequestTest,ParallelFetchNoDuplicates)263 TEST_F(CertNetFetcherURLRequestTest, ParallelFetchNoDuplicates) {
264   ASSERT_TRUE(test_server_.Start());
265   CreateFetcher();
266 
267   // Request a URL with Content-Type "application/pkix-cert"
268   GURL url1 = test_server_.GetURL("/cert.crt");
269   std::unique_ptr<CertNetFetcher::Request> request1 =
270       StartRequest(fetcher(), url1);
271 
272   // Request a URL with Content-Type "application/pkix-crl"
273   GURL url2 = test_server_.GetURL("/root.crl");
274   std::unique_ptr<CertNetFetcher::Request> request2 =
275       StartRequest(fetcher(), url2);
276 
277   // Request a URL with Content-Type "application/pkcs7-mime"
278   GURL url3 = test_server_.GetURL("/certs.p7c");
279   std::unique_ptr<CertNetFetcher::Request> request3 =
280       StartRequest(fetcher(), url3);
281 
282   // Wait for all of the requests to complete and verify the fetch results.
283   VerifySuccess("-cert.crt-\n", request1.get());
284   VerifySuccess("-root.crl-\n", request2.get());
285   VerifySuccess("-certs.p7c-\n", request3.get());
286 
287   EXPECT_EQ(3, NumCreatedRequests());
288 }
289 
290 // Fetch a caIssuers URL which has an unexpected extension and Content-Type.
291 // The extension is .txt and the Content-Type is text/plain. Despite being
292 // unusual this succeeds as the extension and Content-Type are not required to
293 // be meaningful.
TEST_F(CertNetFetcherURLRequestTest,ContentTypeDoesntMatter)294 TEST_F(CertNetFetcherURLRequestTest, ContentTypeDoesntMatter) {
295   ASSERT_TRUE(test_server_.Start());
296   CreateFetcher();
297 
298   GURL url = test_server_.GetURL("/foo.txt");
299   std::unique_ptr<CertNetFetcher::Request> request =
300       StartRequest(fetcher(), url);
301   VerifySuccess("-foo.txt-\n", request.get());
302 }
303 
304 // Fetch a URLs whose HTTP response code is not 200. These are considered
305 // failures.
TEST_F(CertNetFetcherURLRequestTest,HttpStatusCode)306 TEST_F(CertNetFetcherURLRequestTest, HttpStatusCode) {
307   ASSERT_TRUE(test_server_.Start());
308   CreateFetcher();
309 
310   // Response was HTTP status 404.
311   {
312     GURL url = test_server_.GetURL("/404.html");
313     std::unique_ptr<CertNetFetcher::Request> request =
314         StartRequest(fetcher(), url);
315     VerifyFailure(ERR_HTTP_RESPONSE_CODE_FAILURE, request.get());
316   }
317 
318   // Response was HTTP status 500.
319   {
320     GURL url = test_server_.GetURL("/500.html");
321     std::unique_ptr<CertNetFetcher::Request> request =
322         StartRequest(fetcher(), url);
323     VerifyFailure(ERR_HTTP_RESPONSE_CODE_FAILURE, request.get());
324   }
325 }
326 
327 // Fetching a URL with a Content-Disposition header should have no effect.
TEST_F(CertNetFetcherURLRequestTest,ContentDisposition)328 TEST_F(CertNetFetcherURLRequestTest, ContentDisposition) {
329   ASSERT_TRUE(test_server_.Start());
330   CreateFetcher();
331 
332   GURL url = test_server_.GetURL("/downloadable.js");
333   std::unique_ptr<CertNetFetcher::Request> request =
334       StartRequest(fetcher(), url);
335   VerifySuccess("-downloadable.js-\n", request.get());
336 }
337 
338 // Verifies that a cacheable request will be served from the HTTP cache the
339 // second time it is requested.
TEST_F(CertNetFetcherURLRequestTest,Cache)340 TEST_F(CertNetFetcherURLRequestTest, Cache) {
341   ASSERT_TRUE(test_server_.Start());
342 
343   CreateFetcher();
344 
345   // Fetch a URL whose HTTP headers make it cacheable for 1 hour.
346   GURL url(test_server_.GetURL("/cacheable_1hr.crt"));
347   {
348     std::unique_ptr<CertNetFetcher::Request> request =
349         StartRequest(fetcher(), url);
350     VerifySuccess("-cacheable_1hr.crt-\n", request.get());
351   }
352 
353   EXPECT_EQ(1, NumCreatedRequests());
354 
355   // Kill the HTTP server.
356   ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
357 
358   // Fetch again -- will fail unless served from cache.
359   {
360     std::unique_ptr<CertNetFetcher::Request> request =
361         StartRequest(fetcher(), url);
362     VerifySuccess("-cacheable_1hr.crt-\n", request.get());
363   }
364 
365   EXPECT_EQ(2, NumCreatedRequests());
366 }
367 
368 // Verify that the maximum response body constraints are enforced by fetching a
369 // resource that is larger than the limit.
TEST_F(CertNetFetcherURLRequestTest,TooLarge)370 TEST_F(CertNetFetcherURLRequestTest, TooLarge) {
371   ASSERT_TRUE(test_server_.Start());
372 
373   CreateFetcher();
374 
375   // This file has a response body 12 bytes long. So setting the maximum to 11
376   // bytes will cause it to fail.
377   GURL url(test_server_.GetURL("/certs.p7c"));
378   std::unique_ptr<CertNetFetcher::Request> request =
379       fetcher()->FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11);
380 
381   VerifyFailure(ERR_FILE_TOO_BIG, request.get());
382 }
383 
384 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5
385 // seconds to complete. It should fail due to a timeout.
TEST_F(CertNetFetcherURLRequestTest,Hang)386 TEST_F(CertNetFetcherURLRequestTest, Hang) {
387   ASSERT_TRUE(test_server_.Start());
388 
389   CreateFetcher();
390 
391   GURL url(test_server_.GetURL("/slow/certs.p7c?5"));
392   std::unique_ptr<CertNetFetcher::Request> request =
393       fetcher()->FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT);
394   VerifyFailure(ERR_TIMED_OUT, request.get());
395 }
396 
397 // Verify that if a response is gzip-encoded it gets inflated before being
398 // returned to the caller.
TEST_F(CertNetFetcherURLRequestTest,Gzip)399 TEST_F(CertNetFetcherURLRequestTest, Gzip) {
400   ASSERT_TRUE(test_server_.Start());
401 
402   CreateFetcher();
403 
404   GURL url(test_server_.GetURL("/gzipped_crl"));
405   std::unique_ptr<CertNetFetcher::Request> request =
406       StartRequest(fetcher(), url);
407   VerifySuccess("-gzipped_crl-\n", request.get());
408 }
409 
410 // Try fetching an unsupported URL scheme (https).
TEST_F(CertNetFetcherURLRequestTest,HttpsNotAllowed)411 TEST_F(CertNetFetcherURLRequestTest, HttpsNotAllowed) {
412   ASSERT_TRUE(test_server_.Start());
413 
414   CreateFetcher();
415 
416   GURL url("https://foopy/foo.crt");
417   std::unique_ptr<CertNetFetcher::Request> request =
418       StartRequest(fetcher(), url);
419   VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get());
420 
421   // No request was created because the URL scheme was unsupported.
422   EXPECT_EQ(0, NumCreatedRequests());
423 }
424 
425 // Try fetching a URL which redirects to https.
TEST_F(CertNetFetcherURLRequestTest,RedirectToHttpsNotAllowed)426 TEST_F(CertNetFetcherURLRequestTest, RedirectToHttpsNotAllowed) {
427   ASSERT_TRUE(test_server_.Start());
428 
429   CreateFetcher();
430 
431   GURL url(test_server_.GetURL("/redirect_https"));
432 
433   std::unique_ptr<CertNetFetcher::Request> request =
434       StartRequest(fetcher(), url);
435   VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get());
436 
437   EXPECT_EQ(1, NumCreatedRequests());
438 }
439 
440 // Try fetching an unsupported URL scheme (https) and then immediately
441 // cancelling. This is a bit special because this codepath needs to post a task.
TEST_F(CertNetFetcherURLRequestTest,CancelHttpsNotAllowed)442 TEST_F(CertNetFetcherURLRequestTest, CancelHttpsNotAllowed) {
443   ASSERT_TRUE(test_server_.Start());
444 
445   CreateFetcher();
446 
447   GURL url("https://foopy/foo.crt");
448   std::unique_ptr<CertNetFetcher::Request> request =
449       StartRequest(fetcher(), url);
450 
451   // Cancel the request (May or may not have started yet, as the request is
452   // running on another thread).
453   request.reset();
454 }
455 
456 // Start a few requests, and cancel one of them before running the message loop
457 // again.
TEST_F(CertNetFetcherURLRequestTest,CancelBeforeRunningMessageLoop)458 TEST_F(CertNetFetcherURLRequestTest, CancelBeforeRunningMessageLoop) {
459   ASSERT_TRUE(test_server_.Start());
460 
461   CreateFetcher();
462 
463   GURL url1 = test_server_.GetURL("/cert.crt");
464   std::unique_ptr<CertNetFetcher::Request> request1 =
465       StartRequest(fetcher(), url1);
466 
467   GURL url2 = test_server_.GetURL("/root.crl");
468   std::unique_ptr<CertNetFetcher::Request> request2 =
469       StartRequest(fetcher(), url2);
470 
471   GURL url3 = test_server_.GetURL("/certs.p7c");
472 
473   std::unique_ptr<CertNetFetcher::Request> request3 =
474       StartRequest(fetcher(), url3);
475 
476   // Cancel the second request.
477   request2.reset();
478 
479   // Wait for the non-cancelled requests to complete, and verify the fetch
480   // results.
481   VerifySuccess("-cert.crt-\n", request1.get());
482   VerifySuccess("-certs.p7c-\n", request3.get());
483 }
484 
485 // Start several requests, and cancel one of them after the first has completed.
486 // NOTE: The python test server is single threaded and can only service one
487 // request at a time. After a socket is opened by the server it waits for it to
488 // be completed, and any subsequent request will hang until the first socket is
489 // closed.
490 // Cancelling the first request can therefore be problematic, since if
491 // cancellation is done after the socket is opened but before reading/writing,
492 // then the socket is re-cycled and things will be stalled until the cleanup
493 // timer (10 seconds) closes it.
494 // To work around this, the last request is cancelled, and hope that the
495 // requests are given opened sockets in a FIFO order.
496 // TODO(eroman): Make this more robust.
497 // TODO(eroman): Rename this test.
TEST_F(CertNetFetcherURLRequestTest,CancelAfterRunningMessageLoop)498 TEST_F(CertNetFetcherURLRequestTest, CancelAfterRunningMessageLoop) {
499   ASSERT_TRUE(test_server_.Start());
500 
501   CreateFetcher();
502 
503   GURL url1 = test_server_.GetURL("/cert.crt");
504 
505   std::unique_ptr<CertNetFetcher::Request> request1 =
506       StartRequest(fetcher(), url1);
507 
508   GURL url2 = test_server_.GetURL("/certs.p7c");
509   std::unique_ptr<CertNetFetcher::Request> request2 =
510       StartRequest(fetcher(), url2);
511 
512   GURL url3("ftp://www.not.supported.com/foo");
513   std::unique_ptr<CertNetFetcher::Request> request3 =
514       StartRequest(fetcher(), url3);
515 
516   // Wait for the ftp request to complete (it should complete right away since
517   // it doesn't even try to connect to the server).
518   VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request3.get());
519 
520   // Cancel the second outstanding request.
521   request2.reset();
522 
523   // Wait for the first request to complete and verify the fetch result.
524   VerifySuccess("-cert.crt-\n", request1.get());
525 }
526 
527 // Fetch the same URLs in parallel and verify that only 1 request is made per
528 // URL.
529 // b/283075390
TEST_F(CertNetFetcherURLRequestTest,ParallelFetchDuplicates)530 TEST_F(CertNetFetcherURLRequestTest, ParallelFetchDuplicates) {
531   ASSERT_TRUE(test_server_.Start());
532 
533   CreateFetcher();
534 
535   GURL url1 = test_server_.GetURL("/cert.crt");
536   GURL url2 = test_server_.GetURL("/root.crl");
537 
538   // Issue 3 requests for url1, and 3 requests for url2
539   std::unique_ptr<CertNetFetcher::Request> request1 =
540       StartRequest(fetcher(), url1);
541 
542   std::unique_ptr<CertNetFetcher::Request> request2 =
543       StartRequest(fetcher(), url2);
544 
545   std::unique_ptr<CertNetFetcher::Request> request3 =
546       StartRequest(fetcher(), url1);
547 
548   std::unique_ptr<CertNetFetcher::Request> request4 =
549       StartRequest(fetcher(), url2);
550 
551   std::unique_ptr<CertNetFetcher::Request> request5 =
552       StartRequest(fetcher(), url2);
553 
554   std::unique_ptr<CertNetFetcher::Request> request6 =
555       StartRequest(fetcher(), url1);
556 
557   // Cancel all but one of the requests for url1.
558   request1.reset();
559   request3.reset();
560 
561   // Wait for the remaining requests to finish and verify the fetch results.
562   VerifySuccess("-root.crl-\n", request2.get());
563   VerifySuccess("-root.crl-\n", request4.get());
564   VerifySuccess("-root.crl-\n", request5.get());
565   VerifySuccess("-cert.crt-\n", request6.get());
566 
567   // Verify that only 2 URLRequests were started even though 6 requests were
568   // issued.
569   EXPECT_EQ(2, NumCreatedRequests());
570 }
571 
572 // Cancel a request and then start another one for the same URL.
TEST_F(CertNetFetcherURLRequestTest,CancelThenStart)573 TEST_F(CertNetFetcherURLRequestTest, CancelThenStart) {
574   ASSERT_TRUE(test_server_.Start());
575 
576   CreateFetcher();
577 
578   GURL url = test_server_.GetURL("/cert.crt");
579 
580   std::unique_ptr<CertNetFetcher::Request> request1 =
581       StartRequest(fetcher(), url);
582   request1.reset();
583 
584   std::unique_ptr<CertNetFetcher::Request> request2 =
585       StartRequest(fetcher(), url);
586 
587   std::unique_ptr<CertNetFetcher::Request> request3 =
588       StartRequest(fetcher(), url);
589   request3.reset();
590 
591   // All but |request2| were canceled.
592   VerifySuccess("-cert.crt-\n", request2.get());
593 }
594 
595 // Start duplicate requests and then cancel all of them.
TEST_F(CertNetFetcherURLRequestTest,CancelAll)596 TEST_F(CertNetFetcherURLRequestTest, CancelAll) {
597   ASSERT_TRUE(test_server_.Start());
598 
599   CreateFetcher();
600   std::unique_ptr<CertNetFetcher::Request> requests[3];
601 
602   GURL url = test_server_.GetURL("/cert.crt");
603 
604   for (auto& request : requests) {
605     request = StartRequest(fetcher(), url);
606   }
607 
608   // Cancel all the requests.
609   for (auto& request : requests) {
610     request.reset();
611   }
612 
613   EXPECT_EQ(1, NumCreatedRequests());
614 }
615 
616 // Tests that Requests are signalled for completion even if they are
617 // created after the CertNetFetcher has been shutdown.
TEST_F(CertNetFetcherURLRequestTest,RequestsAfterShutdown)618 TEST_F(CertNetFetcherURLRequestTest, RequestsAfterShutdown) {
619   ASSERT_TRUE(test_server_.Start());
620   CreateFetcher();
621   ShutDownFetcher();
622 
623   GURL url = test_server_.GetURL("/cert.crt");
624   std::unique_ptr<CertNetFetcher::Request> request =
625       StartRequest(fetcher(), url);
626   VerifyFailure(ERR_ABORTED, request.get());
627   EXPECT_EQ(0, NumCreatedRequests());
628 }
629 
630 // Tests that Requests are signalled for completion if the fetcher is
631 // shutdown and the network thread stopped before the request is
632 // started.
TEST_F(CertNetFetcherURLRequestTest,RequestAfterShutdownAndNetworkThreadStopped)633 TEST_F(CertNetFetcherURLRequestTest,
634        RequestAfterShutdownAndNetworkThreadStopped) {
635   ASSERT_TRUE(test_server_.Start());
636   CreateFetcher();
637   ShutDownFetcher();
638   ResetState();
639   network_thread_.reset();
640 
641   GURL url = test_server_.GetURL("/cert.crt");
642   std::unique_ptr<CertNetFetcher::Request> request =
643       StartRequest(fetcher(), url);
644   VerifyFailure(ERR_ABORTED, request.get());
645 }
646 
647 // Tests that outstanding Requests are cancelled when Shutdown is called.
TEST_F(CertNetFetcherURLRequestTestWithHangingReadHandler,ShutdownCancelsRequests)648 TEST_F(CertNetFetcherURLRequestTestWithHangingReadHandler,
649        ShutdownCancelsRequests) {
650   CreateFetcher();
651 
652   GURL url = URLRequestHangingReadJob::GetMockHttpUrl();
653   std::unique_ptr<CertNetFetcher::Request> request =
654       StartRequest(fetcher(), url);
655 
656   ShutDownFetcher();
657   VerifyFailure(ERR_ABORTED, request.get());
658 }
659 
TEST_F(CertNetFetcherURLRequestTestWithSecureDnsInterceptor,SecureDnsDisabled)660 TEST_F(CertNetFetcherURLRequestTestWithSecureDnsInterceptor,
661        SecureDnsDisabled) {
662   CreateFetcher();
663   std::unique_ptr<net::CertNetFetcher::Request> request = StartRequest(
664       fetcher(),
665       GURL("http://" + std::string(kMockSecureDnsHostname) + "/cert.crt"));
666   Error actual_error;
667   std::vector<uint8_t> actual_body;
668   request->WaitForResult(&actual_error, &actual_body);
669   EXPECT_TRUE(invoked_interceptor());
670 }
671 
672 }  // namespace
673 
674 }  // namespace net
675