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