Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: net/cert_net/cert_net_fetcher_impl_unittest.cc

Issue 908863004: Initial implementation for CertNetFetcher. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add missing comma Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cert_net/cert_net_fetcher_impl.cc ('k') | net/data/cert_net_fetcher_impl_unittest/404.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
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_impl.h"
6
7 #include <string>
8
9 #include "base/compiler_specific.h"
10 #include "base/run_loop.h"
11 #include "net/cert/mock_cert_verifier.h"
12 #include "net/dns/mock_host_resolver.h"
13 #include "net/http/http_server_properties_impl.h"
14 #include "net/test/spawned_test_server/spawned_test_server.h"
15 #include "net/url_request/url_request_job_factory_impl.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "testing/platform_test.h"
19
20 // TODO(eroman): Test that cookies aren't sent.
21
22 using base::ASCIIToUTF16;
23
24 namespace net {
25
26 namespace {
27
28 const base::FilePath::CharType kDocRoot[] =
29 FILE_PATH_LITERAL("net/data/cert_net_fetcher_impl_unittest");
30
31 // A non-mock URLRequestContext which can access http:// urls.
32 class RequestContext : public URLRequestContext {
33 public:
34 RequestContext() : storage_(this) {
35 ProxyConfig no_proxy;
36 storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
37 storage_.set_cert_verifier(new MockCertVerifier);
38 storage_.set_transport_security_state(new TransportSecurityState);
39 storage_.set_proxy_service(ProxyService::CreateFixed(no_proxy));
40 storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
41 storage_.set_http_server_properties(
42 scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
43
44 HttpNetworkSession::Params params;
45 params.host_resolver = host_resolver();
46 params.cert_verifier = cert_verifier();
47 params.transport_security_state = transport_security_state();
48 params.proxy_service = proxy_service();
49 params.ssl_config_service = ssl_config_service();
50 params.http_server_properties = http_server_properties();
51 scoped_refptr<HttpNetworkSession> network_session(
52 new HttpNetworkSession(params));
53 storage_.set_http_transaction_factory(new HttpCache(
54 network_session.get(), HttpCache::DefaultBackend::InMemory(0)));
55 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl();
56 storage_.set_job_factory(job_factory);
57 }
58
59 ~RequestContext() override { AssertNoURLRequests(); }
60
61 private:
62 URLRequestContextStorage storage_;
63 };
64
65 class FetchResult {
66 public:
67 FetchResult(Error net_error, const std::vector<uint8_t>& response_body)
68 : net_error_(net_error), response_body_(response_body) {}
69
70 void VerifySuccess(const std::string& expected_body) {
71 EXPECT_EQ(OK, net_error_);
72 EXPECT_EQ(expected_body,
73 std::string(response_body_.begin(), response_body_.end()));
74 }
75
76 void VerifyFailure(Error expected_error) {
77 EXPECT_EQ(expected_error, net_error_);
78 EXPECT_EQ(0u, response_body_.size());
79 }
80
81 private:
82 const Error net_error_;
83 const std::vector<uint8_t> response_body_;
84 };
85
86 // Helper to synchronously wait for the fetch completion. This is similar to
87 // net's TestCompletionCallback, but built around FetchCallback.
88 class TestFetchCallback {
89 public:
90 TestFetchCallback()
91 : callback_(base::Bind(&TestFetchCallback::OnCallback,
92 base::Unretained(this))) {}
93
94 const CertNetFetcher::FetchCallback& callback() const { return callback_; }
95
96 scoped_ptr<FetchResult> WaitForResult() {
97 DCHECK(quit_closure_.is_null());
98 while (!HasResult()) {
99 base::RunLoop run_loop;
100 quit_closure_ = run_loop.QuitClosure();
101 run_loop.Run();
102 quit_closure_.Reset();
103 }
104 return result_.Pass();
105 }
106
107 bool HasResult() const { return result_.get(); }
108
109 // Sets an extra action (in addition to recording the result) that is run when
110 // the FetchCallback is invoked.
111 void set_extra_closure(const base::Closure& closure) {
112 extra_closure_ = closure;
113 }
114
115 private:
116 void OnCallback(Error net_error, const std::vector<uint8_t>& response_body) {
117 DCHECK(!HasResult());
118 result_.reset(new FetchResult(net_error, response_body));
119
120 if (!extra_closure_.is_null())
121 extra_closure_.Run();
122
123 if (!quit_closure_.is_null())
124 quit_closure_.Run();
125 }
126
127 CertNetFetcher::FetchCallback callback_;
128 scoped_ptr<FetchResult> result_;
129 base::Closure quit_closure_;
130 base::Closure extra_closure_;
131 };
132
133 } // namespace
134
135 class CertNetFetcherImplTest : public PlatformTest {
136 public:
137 CertNetFetcherImplTest()
138 : test_server_(SpawnedTestServer::TYPE_HTTP,
139 net::SpawnedTestServer::kLocalhost,
140 base::FilePath(kDocRoot)) {
141 context_.set_network_delegate(&network_delegate_);
142 }
143
144 protected:
145 SpawnedTestServer test_server_;
146 TestNetworkDelegate network_delegate_;
147 RequestContext context_;
148 };
149
150 // Helper to start an AIA fetch using default parameters.
151 WARN_UNUSED_RESULT scoped_ptr<CertNetFetcher::Request> StartRequest(
152 CertNetFetcher* fetcher,
153 const GURL& url,
154 const TestFetchCallback& callback) {
155 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT,
156 CertNetFetcher::DEFAULT, callback.callback());
157 }
158
159 // Fetch a few unique URLs using GET in parallel. Each URL has a different body
160 // and Content-Type.
161 TEST_F(CertNetFetcherImplTest, ParallelFetchNoDuplicates) {
162 ASSERT_TRUE(test_server_.Start());
163
164 CertNetFetcherImpl fetcher(&context_);
165 TestFetchCallback callback1;
166 TestFetchCallback callback2;
167 TestFetchCallback callback3;
168
169 // Request a URL with Content-Type "application/pkix-cert"
170 GURL url1 = test_server_.GetURL("files/cert.crt");
171 scoped_ptr<CertNetFetcher::Request> request1 =
172 StartRequest(&fetcher, url1, callback1);
173
174 // Request a URL with Content-Type "application/pkix-crl"
175 GURL url2 = test_server_.GetURL("files/root.crl");
176 scoped_ptr<CertNetFetcher::Request> request2 =
177 StartRequest(&fetcher, url2, callback2);
178
179 // Request a URL with Content-Type "application/pkcs7-mime"
180 GURL url3 = test_server_.GetURL("files/certs.p7c");
181 scoped_ptr<CertNetFetcher::Request> request3 =
182 StartRequest(&fetcher, url3, callback3);
183
184 // Wait for all of the requests to complete.
185 scoped_ptr<FetchResult> result1 = callback1.WaitForResult();
186 scoped_ptr<FetchResult> result2 = callback2.WaitForResult();
187 scoped_ptr<FetchResult> result3 = callback3.WaitForResult();
188
189 // Verify the fetch results.
190 result1->VerifySuccess("-cert.crt-\n");
191 result2->VerifySuccess("-root.crl-\n");
192 result3->VerifySuccess("-certs.p7c-\n");
193
194 EXPECT_EQ(3, network_delegate_.created_requests());
195 }
196
197 // Fetch a caIssuers URL which has an unexpected extension and Content-Type.
198 // The extension is .txt and the Content-Type is text/plain. Despite being
199 // unusual this succeeds as the extension and Content-Type are not required to
200 // be meaningful.
201 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) {
202 ASSERT_TRUE(test_server_.Start());
203
204 CertNetFetcherImpl fetcher(&context_);
205
206 TestFetchCallback callback;
207 GURL url = test_server_.GetURL("files/foo.txt");
208 scoped_ptr<CertNetFetcher::Request> request =
209 StartRequest(&fetcher, url, callback);
210 scoped_ptr<FetchResult> result = callback.WaitForResult();
211 result->VerifySuccess("-foo.txt-\n");
212 }
213
214 // Fetch a URLs whose HTTP response code is not 200. These are considered
215 // failures.
216 TEST_F(CertNetFetcherImplTest, HttpStatusCode) {
217 ASSERT_TRUE(test_server_.Start());
218
219 CertNetFetcherImpl fetcher(&context_);
220
221 // Response was HTTP status 404.
222 {
223 TestFetchCallback callback;
224 GURL url = test_server_.GetURL("files/404.html");
225 scoped_ptr<CertNetFetcher::Request> request =
226 StartRequest(&fetcher, url, callback);
227 scoped_ptr<FetchResult> result = callback.WaitForResult();
228 result->VerifyFailure(ERR_FAILED);
229 }
230
231 // Response was HTTP status 500.
232 {
233 TestFetchCallback callback;
234 GURL url = test_server_.GetURL("files/500.html");
235 scoped_ptr<CertNetFetcher::Request> request =
236 StartRequest(&fetcher, url, callback);
237 scoped_ptr<FetchResult> result = callback.WaitForResult();
238 result->VerifyFailure(ERR_FAILED);
239 }
240 }
241
242 // Fetching a URL with a Content-Disposition header should have no effect.
243 TEST_F(CertNetFetcherImplTest, ContentDisposition) {
244 ASSERT_TRUE(test_server_.Start());
245
246 CertNetFetcherImpl fetcher(&context_);
247
248 TestFetchCallback callback;
249 GURL url = test_server_.GetURL("files/downloadable.js");
250 scoped_ptr<CertNetFetcher::Request> request =
251 StartRequest(&fetcher, url, callback);
252 scoped_ptr<FetchResult> result = callback.WaitForResult();
253 result->VerifySuccess("-downloadable.js-\n");
254 }
255
256 // Verifies that a cachable request will be served from the HTTP cache the
257 // second time it is requested.
258 TEST_F(CertNetFetcherImplTest, Cache) {
259 ASSERT_TRUE(test_server_.Start());
260
261 CertNetFetcherImpl fetcher(&context_);
262
263 // Fetch a URL whose HTTP headers make it cacheable for 1 hour.
264 GURL url(test_server_.GetURL("files/cacheable_1hr.crt"));
265 {
266 TestFetchCallback callback;
267
268 scoped_ptr<CertNetFetcher::Request> request =
269 StartRequest(&fetcher, url, callback);
270 scoped_ptr<FetchResult> result = callback.WaitForResult();
271 result->VerifySuccess("-cacheable_1hr.crt-\n");
272 }
273
274 EXPECT_EQ(1, network_delegate_.created_requests());
275
276 // Kill the HTTP server.
277 ASSERT_TRUE(test_server_.Stop());
278
279 // Fetch again -- will fail unless served from cache.
280 {
281 TestFetchCallback callback;
282 scoped_ptr<CertNetFetcher::Request> request =
283 StartRequest(&fetcher, url, callback);
284 scoped_ptr<FetchResult> result = callback.WaitForResult();
285 result->VerifySuccess("-cacheable_1hr.crt-\n");
286 }
287
288 EXPECT_EQ(2, network_delegate_.created_requests());
289 }
290
291 // Verify that the maximum response body constraints are enforced by fetching a
292 // resource that is larger than the limit.
293 TEST_F(CertNetFetcherImplTest, TooLarge) {
294 ASSERT_TRUE(test_server_.Start());
295
296 CertNetFetcherImpl fetcher(&context_);
297
298 // This file has a response body 12 bytes long. So setting the maximum to 11
299 // bytes will cause it to fail.
300 GURL url(test_server_.GetURL("files/certs.p7c"));
301 TestFetchCallback callback;
302 scoped_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers(
303 url, CertNetFetcher::DEFAULT, 11, callback.callback());
304
305 scoped_ptr<FetchResult> result = callback.WaitForResult();
306 result->VerifyFailure(ERR_FILE_TOO_BIG);
307 }
308
309 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5
310 // seconds to complete. It should fail due to a timeout.
311 TEST_F(CertNetFetcherImplTest, Hang) {
312 ASSERT_TRUE(test_server_.Start());
313
314 CertNetFetcherImpl fetcher(&context_);
315
316 GURL url(test_server_.GetURL("slow/certs.p7c?5"));
317 TestFetchCallback callback;
318 scoped_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers(
319 url, 10, CertNetFetcher::DEFAULT, callback.callback());
320 scoped_ptr<FetchResult> result = callback.WaitForResult();
321 result->VerifyFailure(ERR_TIMED_OUT);
322 }
323
324 // Verify that if a response is gzip-encoded it gets inflated before being
325 // returned to the caller.
326 TEST_F(CertNetFetcherImplTest, Gzip) {
327 ASSERT_TRUE(test_server_.Start());
328
329 CertNetFetcherImpl fetcher(&context_);
330
331 GURL url(test_server_.GetURL("files/gzipped_crl"));
332 TestFetchCallback callback;
333 scoped_ptr<CertNetFetcher::Request> request =
334 StartRequest(&fetcher, url, callback);
335 scoped_ptr<FetchResult> result = callback.WaitForResult();
336 result->VerifySuccess("-gzipped_crl-\n");
337 }
338
339 // Try fetching an unsupported URL scheme (https).
340 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) {
341 ASSERT_TRUE(test_server_.Start());
342
343 CertNetFetcherImpl fetcher(&context_);
344
345 GURL url("https://foopy/foo.crt");
346 TestFetchCallback callback;
347 scoped_ptr<CertNetFetcher::Request> request =
348 StartRequest(&fetcher, url, callback);
349 // Should NOT complete synchronously despite being a test that could be done
350 // immediately.
351 EXPECT_FALSE(callback.HasResult());
352 scoped_ptr<FetchResult> result = callback.WaitForResult();
353 result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);
354
355 // No request was created because the URL scheme was unsupported.
356 EXPECT_EQ(0, network_delegate_.created_requests());
357 }
358
359 // Try fetching a URL which redirects to https.
360 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) {
361 ASSERT_TRUE(test_server_.Start());
362
363 CertNetFetcherImpl fetcher(&context_);
364
365 GURL url(test_server_.GetURL("files/redirect_https"));
366 TestFetchCallback callback;
367
368 scoped_ptr<CertNetFetcher::Request> request =
369 StartRequest(&fetcher, url, callback);
370 scoped_ptr<FetchResult> result = callback.WaitForResult();
371 result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);
372
373 EXPECT_EQ(1, network_delegate_.created_requests());
374 }
375
376 // Try fetching an unsupported URL scheme (https) and then immediately
377 // cancelling. This is a bit special because this codepath needs to post a task.
378 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) {
379 ASSERT_TRUE(test_server_.Start());
380
381 CertNetFetcherImpl fetcher(&context_);
382
383 GURL url("https://foopy/foo.crt");
384 TestFetchCallback callback;
385 scoped_ptr<CertNetFetcher::Request> request =
386 StartRequest(&fetcher, url, callback);
387
388 // Cancel the request.
389 request.reset();
390
391 // Spin the message loop to increase chance of catching a bug.
392 base::RunLoop().RunUntilIdle();
393
394 // Should NOT complete synchronously despite being a test that could be done
395 // immediately.
396 EXPECT_FALSE(callback.HasResult());
397
398 EXPECT_EQ(0, network_delegate_.created_requests());
399 }
400
401 // Start a few requests, and cancel one of them before running the message loop
402 // again.
403 TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) {
404 ASSERT_TRUE(test_server_.Start());
405
406 CertNetFetcherImpl fetcher(&context_);
407 TestFetchCallback callback1;
408 TestFetchCallback callback2;
409 TestFetchCallback callback3;
410
411 GURL url1 = test_server_.GetURL("files/cert.crt");
412 scoped_ptr<CertNetFetcher::Request> request1 =
413 StartRequest(&fetcher, url1, callback1);
414
415 GURL url2 = test_server_.GetURL("files/root.crl");
416 scoped_ptr<CertNetFetcher::Request> request2 =
417 StartRequest(&fetcher, url2, callback2);
418
419 GURL url3 = test_server_.GetURL("files/certs.p7c");
420
421 scoped_ptr<CertNetFetcher::Request> request3 =
422 StartRequest(&fetcher, url3, callback3);
423
424 EXPECT_EQ(3, network_delegate_.created_requests());
425 EXPECT_FALSE(callback1.HasResult());
426 EXPECT_FALSE(callback2.HasResult());
427 EXPECT_FALSE(callback3.HasResult());
428
429 // Cancel the second request.
430 request2.reset();
431
432 // Wait for the non-cancelled requests to complete.
433 scoped_ptr<FetchResult> result1 = callback1.WaitForResult();
434 scoped_ptr<FetchResult> result3 = callback3.WaitForResult();
435
436 // Verify the fetch results.
437 result1->VerifySuccess("-cert.crt-\n");
438 result3->VerifySuccess("-certs.p7c-\n");
439
440 EXPECT_FALSE(callback2.HasResult());
441 }
442
443 // Start several requests, and cancel one of them after the first has completed.
444 // NOTE: The python test server is single threaded and can only service one
445 // request at a time. After a socket is opened by the server it waits for it to
446 // be completed, and any subsequent request will hang until the first socket is
447 // closed.
448 // Cancelling the first request can therefore be problematic, since if
449 // cancellation is done after the socket is opened but before reading/writing,
450 // then the socket is re-cycled and things will be stalled until the cleanup
451 // timer (10 seconds) closes it.
452 // To work around this, the last request is cancelled, and hope that the
453 // requests are given opened sockets in a FIFO order.
454 // TODO(eroman): Make this more robust.
455 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) {
456 ASSERT_TRUE(test_server_.Start());
457
458 CertNetFetcherImpl fetcher(&context_);
459 TestFetchCallback callback1;
460 TestFetchCallback callback2;
461 TestFetchCallback callback3;
462
463 GURL url1 = test_server_.GetURL("files/cert.crt");
464
465 scoped_ptr<CertNetFetcher::Request> request1 =
466 StartRequest(&fetcher, url1, callback1);
467
468 GURL url2 = test_server_.GetURL("files/certs.p7c");
469 scoped_ptr<CertNetFetcher::Request> request2 =
470 StartRequest(&fetcher, url2, callback2);
471
472 GURL url3("ftp://www.not.supported.com/foo");
473 scoped_ptr<CertNetFetcher::Request> request3 =
474 StartRequest(&fetcher, url3, callback3);
475
476 EXPECT_FALSE(callback1.HasResult());
477 EXPECT_FALSE(callback2.HasResult());
478 EXPECT_FALSE(callback3.HasResult());
479
480 // Wait for the ftp request to complete (it should complete right away since
481 // it doesn't even try to connect to the server).
482 scoped_ptr<FetchResult> result3 = callback3.WaitForResult();
483 result3->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);
484
485 // Cancel the second outstanding request.
486 request2.reset();
487
488 // Wait for the first request to complete.
489 scoped_ptr<FetchResult> result2 = callback1.WaitForResult();
490
491 // Verify the fetch results.
492 result2->VerifySuccess("-cert.crt-\n");
493 }
494
495 // Delete a CertNetFetcherImpl with outstanding requests on it.
496 TEST_F(CertNetFetcherImplTest, DeleteCancels) {
497 ASSERT_TRUE(test_server_.Start());
498
499 scoped_ptr<CertNetFetcherImpl> fetcher(new CertNetFetcherImpl(&context_));
500
501 GURL url(test_server_.GetURL("slow/certs.p7c?20"));
502 TestFetchCallback callback;
503 scoped_ptr<CertNetFetcher::Request> request =
504 StartRequest(fetcher.get(), url, callback);
505
506 // Destroy the fetcher before the outstanding request.
507 fetcher.reset();
508 }
509
510 // Fetch the same URLs in parallel and verify that only 1 request is made per
511 // URL.
512 TEST_F(CertNetFetcherImplTest, ParallelFetchDuplicates) {
513 ASSERT_TRUE(test_server_.Start());
514
515 CertNetFetcherImpl fetcher(&context_);
516
517 GURL url1 = test_server_.GetURL("files/cert.crt");
518 GURL url2 = test_server_.GetURL("files/root.crl");
519
520 // Issue 3 requests for url1, and 3 requests for url2
521 TestFetchCallback callback1;
522 scoped_ptr<CertNetFetcher::Request> request1 =
523 StartRequest(&fetcher, url1, callback1);
524
525 TestFetchCallback callback2;
526 scoped_ptr<CertNetFetcher::Request> request2 =
527 StartRequest(&fetcher, url2, callback2);
528
529 TestFetchCallback callback3;
530 scoped_ptr<CertNetFetcher::Request> request3 =
531 StartRequest(&fetcher, url1, callback3);
532
533 TestFetchCallback callback4;
534 scoped_ptr<CertNetFetcher::Request> request4 =
535 StartRequest(&fetcher, url2, callback4);
536
537 TestFetchCallback callback5;
538 scoped_ptr<CertNetFetcher::Request> request5 =
539 StartRequest(&fetcher, url2, callback5);
540
541 TestFetchCallback callback6;
542 scoped_ptr<CertNetFetcher::Request> request6 =
543 StartRequest(&fetcher, url1, callback6);
544
545 // Cancel all but one of the requests for url1.
546 request1.reset();
547 request3.reset();
548
549 // Wait for the remaining requests to finish.
550 scoped_ptr<FetchResult> result2 = callback2.WaitForResult();
551 scoped_ptr<FetchResult> result4 = callback4.WaitForResult();
552 scoped_ptr<FetchResult> result5 = callback5.WaitForResult();
553 scoped_ptr<FetchResult> result6 = callback6.WaitForResult();
554
555 // Verify that none of the cancelled requests for url1 completed (since they
556 // were cancelled).
557 EXPECT_FALSE(callback1.HasResult());
558 EXPECT_FALSE(callback3.HasResult());
559
560 // Verify the fetch results.
561 result2->VerifySuccess("-root.crl-\n");
562 result4->VerifySuccess("-root.crl-\n");
563 result5->VerifySuccess("-root.crl-\n");
564 result6->VerifySuccess("-cert.crt-\n");
565
566 // Verify that only 2 URLRequests were started even though 6 requests were
567 // issued.
568 EXPECT_EQ(2, network_delegate_.created_requests());
569 }
570
571 // Cancel a request and then start another one for the same URL.
572 TEST_F(CertNetFetcherImplTest, CancelThenStart) {
573 ASSERT_TRUE(test_server_.Start());
574
575 CertNetFetcherImpl fetcher(&context_);
576 TestFetchCallback callback1;
577 TestFetchCallback callback2;
578 TestFetchCallback callback3;
579
580 GURL url = test_server_.GetURL("files/cert.crt");
581
582 scoped_ptr<CertNetFetcher::Request> request1 =
583 StartRequest(&fetcher, url, callback1);
584 request1.reset();
585
586 scoped_ptr<CertNetFetcher::Request> request2 =
587 StartRequest(&fetcher, url, callback2);
588
589 scoped_ptr<CertNetFetcher::Request> request3 =
590 StartRequest(&fetcher, url, callback3);
591 request3.reset();
592
593 // All but |request2| were canceled.
594 scoped_ptr<FetchResult> result = callback2.WaitForResult();
595
596 result->VerifySuccess("-cert.crt-\n");
597
598 EXPECT_FALSE(callback1.HasResult());
599 EXPECT_FALSE(callback3.HasResult());
600
601 // One URLRequest that was cancelled, then another right afterwards.
602 EXPECT_EQ(2, network_delegate_.created_requests());
603 }
604
605 // Start duplicate requests and then cancel all of them.
606 TEST_F(CertNetFetcherImplTest, CancelAll) {
607 ASSERT_TRUE(test_server_.Start());
608
609 CertNetFetcherImpl fetcher(&context_);
610 TestFetchCallback callback[3];
611 scoped_ptr<CertNetFetcher::Request> request[3];
612
613 GURL url = test_server_.GetURL("files/cert.crt");
614
615 for (size_t i = 0; i < arraysize(callback); ++i) {
616 request[i] = StartRequest(&fetcher, url, callback[i]);
617 }
618
619 // Cancel all the requests.
620 for (size_t i = 0; i < arraysize(request); ++i)
621 request[i].reset();
622
623 EXPECT_EQ(1, network_delegate_.created_requests());
624
625 for (size_t i = 0; i < arraysize(request); ++i)
626 EXPECT_FALSE(callback[i].HasResult());
627 }
628
629 void DeleteCertNetFetcher(CertNetFetcher* fetcher) {
630 delete fetcher;
631 }
632
633 // Delete the CertNetFetcherImpl within a request callback.
634 TEST_F(CertNetFetcherImplTest, DeleteWithinCallback) {
635 ASSERT_TRUE(test_server_.Start());
636
637 // Deleted by callback2.
638 CertNetFetcher* fetcher = new CertNetFetcherImpl(&context_);
639
640 GURL url = test_server_.GetURL("files/cert.crt");
641
642 TestFetchCallback callback[4];
643 scoped_ptr<CertNetFetcher::Request> reqs[4];
644 callback[1].set_extra_closure(base::Bind(DeleteCertNetFetcher, fetcher));
645
646 for (size_t i = 0; i < arraysize(callback); ++i)
647 reqs[i] = StartRequest(fetcher, url, callback[i]);
648
649 EXPECT_EQ(1, network_delegate_.created_requests());
650
651 callback[1].WaitForResult();
652
653 // Assume requests for the same URL are executed in FIFO order.
654 EXPECT_TRUE(callback[0].HasResult());
655 EXPECT_FALSE(callback[2].HasResult());
656 EXPECT_FALSE(callback[3].HasResult());
657 }
658
659 void FetchRequest(CertNetFetcher* fetcher,
660 const GURL& url,
661 TestFetchCallback* callback,
662 scoped_ptr<CertNetFetcher::Request>* request) {
663 *request = StartRequest(fetcher, url, *callback);
664 }
665
666 // Make a request during callback for the same URL.
667 TEST_F(CertNetFetcherImplTest, FetchWithinCallback) {
668 ASSERT_TRUE(test_server_.Start());
669
670 CertNetFetcherImpl fetcher(&context_);
671
672 GURL url = test_server_.GetURL("files/cert.crt");
673
674 TestFetchCallback callback[5];
675 scoped_ptr<CertNetFetcher::Request> req[5];
676 callback[1].set_extra_closure(
677 base::Bind(FetchRequest, &fetcher, url, &callback[4], &req[4]));
678
679 for (size_t i = 0; i < arraysize(callback) - 1; ++i)
680 req[i] = StartRequest(&fetcher, url, callback[i]);
681
682 EXPECT_EQ(1, network_delegate_.created_requests());
683
684 for (size_t i = 0; i < arraysize(callback); ++i) {
685 scoped_ptr<FetchResult> result = callback[i].WaitForResult();
686 result->VerifySuccess("-cert.crt-\n");
687 }
688
689 // The fetch started within a callback should have started a new request
690 // rather than attaching to the current job.
691 EXPECT_EQ(2, network_delegate_.created_requests());
692 }
693
694 void CancelRequest(scoped_ptr<CertNetFetcher::Request>* request) {
695 request->reset();
696 }
697
698 // Cancel a request while executing a callback for the same job.
699 TEST_F(CertNetFetcherImplTest, CancelWithinCallback) {
700 ASSERT_TRUE(test_server_.Start());
701
702 CertNetFetcherImpl fetcher(&context_);
703
704 GURL url = test_server_.GetURL("files/cert.crt");
705
706 TestFetchCallback callback[4];
707 scoped_ptr<CertNetFetcher::Request> request[4];
708
709 for (size_t i = 0; i < arraysize(callback); ++i)
710 request[i] = StartRequest(&fetcher, url, callback[i]);
711
712 // Cancel request[2] when the callback for request[1] runs.
713 callback[1].set_extra_closure(base::Bind(CancelRequest, &request[2]));
714
715 EXPECT_EQ(1, network_delegate_.created_requests());
716
717 for (size_t i = 0; i < arraysize(request); ++i) {
718 if (i == 2)
719 continue;
720
721 scoped_ptr<FetchResult> result = callback[i].WaitForResult();
722 result->VerifySuccess("-cert.crt-\n");
723 }
724
725 // request[2] was cancelled.
726 EXPECT_FALSE(callback[2].HasResult());
727 }
728
729 } // namespace net
OLDNEW
« no previous file with comments | « net/cert_net/cert_net_fetcher_impl.cc ('k') | net/data/cert_net_fetcher_impl_unittest/404.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698