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