OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/cert_net_fetcher.h" | 5 #include "net/cert/cert_net_fetcher.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "net/cert/mock_cert_verifier.h" | 10 #include "net/cert/mock_cert_verifier.h" |
11 #include "net/dns/mock_host_resolver.h" | 11 #include "net/dns/mock_host_resolver.h" |
12 #include "net/http/http_server_properties_impl.h" | 12 #include "net/http/http_server_properties_impl.h" |
13 #include "net/test/spawned_test_server/spawned_test_server.h" | 13 #include "net/test/spawned_test_server/spawned_test_server.h" |
14 #include "net/url_request/url_request_job_factory_impl.h" | 14 #include "net/url_request/url_request_job_factory_impl.h" |
15 #include "net/url_request/url_request_test_util.h" | 15 #include "net/url_request/url_request_test_util.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "testing/platform_test.h" | 17 #include "testing/platform_test.h" |
18 | 18 |
19 // TODO(eroman): Test that cookies aren't sent. | 19 // TODO(eroman): Test that cookies aren't sent. |
20 // TODO(eroman): Request de-duplication | |
21 // TODO(eroman): Cancel duplicated requests within a callback | |
22 // TODO(eroman): Start requests for the same job within a callback | |
23 // TODO(eroman): Delete the CertNetFetcher within callback | |
24 | 20 |
25 using base::ASCIIToUTF16; | 21 using base::ASCIIToUTF16; |
26 | 22 |
27 namespace net { | 23 namespace net { |
28 | 24 |
29 namespace { | 25 namespace { |
30 | 26 |
31 const base::FilePath::CharType kDocRoot[] = | 27 const base::FilePath::CharType kDocRoot[] = |
32 FILE_PATH_LITERAL("net/data/cert_net_fetcher_unittest"); | 28 FILE_PATH_LITERAL("net/data/cert_net_fetcher_unittest"); |
33 | 29 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 waiting_for_result_ = true; | 88 waiting_for_result_ = true; |
93 base::MessageLoop::current()->Run(); | 89 base::MessageLoop::current()->Run(); |
94 waiting_for_result_ = false; | 90 waiting_for_result_ = false; |
95 } | 91 } |
96 have_result_ = false; // Auto-reset for next callback. | 92 have_result_ = false; // Auto-reset for next callback. |
97 return result_; | 93 return result_; |
98 } | 94 } |
99 | 95 |
100 bool HasResult() const { return have_result_; } | 96 bool HasResult() const { return have_result_; } |
101 | 97 |
| 98 // Sets an extra action (in addition to recording the result) that is run when |
| 99 // the FetchCallback is invoked. |
| 100 void set_extra_closure(const base::Closure& closure) { |
| 101 extra_closure_ = closure; |
| 102 } |
| 103 |
102 private: | 104 private: |
103 void OnCallback(int net_error, const std::vector<uint8_t>& response_body) { | 105 void OnCallback(int net_error, const std::vector<uint8_t>& response_body) { |
104 DCHECK(!have_result_); | 106 DCHECK(!have_result_); |
105 have_result_ = true; | 107 have_result_ = true; |
106 result_.net_error = net_error; | 108 result_.net_error = net_error; |
107 result_.response_body = response_body; | 109 result_.response_body = response_body; |
| 110 |
| 111 if (!extra_closure_.is_null()) |
| 112 extra_closure_.Run(); |
| 113 |
108 if (waiting_for_result_) | 114 if (waiting_for_result_) |
109 base::MessageLoop::current()->Quit(); | 115 base::MessageLoop::current()->Quit(); |
110 } | 116 } |
111 | 117 |
112 CertNetFetcher::FetchCallback callback_; | 118 CertNetFetcher::FetchCallback callback_; |
113 FetchResult result_; | 119 FetchResult result_; |
114 bool have_result_; | 120 bool have_result_; |
115 bool waiting_for_result_; | 121 bool waiting_for_result_; |
| 122 base::Closure extra_closure_; |
116 }; | 123 }; |
117 | 124 |
118 } // namespace | 125 } // namespace |
119 | 126 |
120 class CertNetFetcherTest : public PlatformTest { | 127 class CertNetFetcherTest : public PlatformTest { |
121 public: | 128 public: |
122 CertNetFetcherTest() | 129 CertNetFetcherTest() |
123 : test_server_(SpawnedTestServer::TYPE_HTTP, | 130 : test_server_(SpawnedTestServer::TYPE_HTTP, |
124 net::SpawnedTestServer::kLocalhost, | 131 net::SpawnedTestServer::kLocalhost, |
125 base::FilePath(kDocRoot)) {} | 132 base::FilePath(kDocRoot)) { |
| 133 context_.set_network_delegate(&network_delegate_); |
| 134 } |
126 | 135 |
127 protected: | 136 protected: |
128 SpawnedTestServer test_server_; | 137 SpawnedTestServer test_server_; |
| 138 TestNetworkDelegate network_delegate_; |
129 RequestContext context_; | 139 RequestContext context_; |
130 }; | 140 }; |
131 | 141 |
132 CertNetFetcher::RequestId StartRequest(const GURL& url, | 142 CertNetFetcher::RequestId StartRequest(const GURL& url, |
133 const TestFetchCallback& callback, | 143 const TestFetchCallback& callback, |
134 CertNetFetcher* fetcher) { | 144 CertNetFetcher* fetcher) { |
135 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, | 145 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, |
136 CertNetFetcher::DEFAULT, callback.callback()); | 146 CertNetFetcher::DEFAULT, callback.callback()); |
137 } | 147 } |
138 | 148 |
(...skipping 24 matching lines...) Expand all Loading... |
163 FetchResult result2 = callback2.WaitForResult(); | 173 FetchResult result2 = callback2.WaitForResult(); |
164 FetchResult result3 = callback3.WaitForResult(); | 174 FetchResult result3 = callback3.WaitForResult(); |
165 | 175 |
166 // Verify the fetch results. | 176 // Verify the fetch results. |
167 EXPECT_EQ(OK, result1.net_error); | 177 EXPECT_EQ(OK, result1.net_error); |
168 EXPECT_EQ("-cert.crt-\n", result1.GetBodyAsString()); | 178 EXPECT_EQ("-cert.crt-\n", result1.GetBodyAsString()); |
169 EXPECT_EQ(OK, result2.net_error); | 179 EXPECT_EQ(OK, result2.net_error); |
170 EXPECT_EQ("-root.crl-\n", result2.GetBodyAsString()); | 180 EXPECT_EQ("-root.crl-\n", result2.GetBodyAsString()); |
171 EXPECT_EQ(OK, result3.net_error); | 181 EXPECT_EQ(OK, result3.net_error); |
172 EXPECT_EQ("-certs.p7c-\n", result3.GetBodyAsString()); | 182 EXPECT_EQ("-certs.p7c-\n", result3.GetBodyAsString()); |
| 183 |
| 184 EXPECT_EQ(3, network_delegate_.created_requests()); |
173 } | 185 } |
174 | 186 |
175 // Fetch a caIssuers URL which has an unexpected extension and Content-Type. | 187 // Fetch a caIssuers URL which has an unexpected extension and Content-Type. |
176 // The extension is .txt and the Content-Type is text/plain. Despite being | 188 // The extension is .txt and the Content-Type is text/plain. Despite being |
177 // unusual this succeeds as the extension and Content-Type are not required to | 189 // unusual this succeeds as the extension and Content-Type are not required to |
178 // be meaningful. | 190 // be meaningful. |
179 TEST_F(CertNetFetcherTest, ContentTypeDoesntMatter) { | 191 TEST_F(CertNetFetcherTest, ContentTypeDoesntMatter) { |
180 ASSERT_TRUE(test_server_.Start()); | 192 ASSERT_TRUE(test_server_.Start()); |
181 | 193 |
182 CertNetFetcher fetcher(&context_); | 194 CertNetFetcher fetcher(&context_); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 // Fetch a URL whose HTTP headers make it cacheable for 1 hour. | 253 // Fetch a URL whose HTTP headers make it cacheable for 1 hour. |
242 GURL url(test_server_.GetURL("files/cacheable_1hr.crt")); | 254 GURL url(test_server_.GetURL("files/cacheable_1hr.crt")); |
243 { | 255 { |
244 TestFetchCallback callback; | 256 TestFetchCallback callback; |
245 StartRequest(url, callback, &fetcher); | 257 StartRequest(url, callback, &fetcher); |
246 FetchResult result = callback.WaitForResult(); | 258 FetchResult result = callback.WaitForResult(); |
247 EXPECT_EQ(OK, result.net_error); | 259 EXPECT_EQ(OK, result.net_error); |
248 EXPECT_EQ("-cacheable_1hr.crt-\n", result.GetBodyAsString()); | 260 EXPECT_EQ("-cacheable_1hr.crt-\n", result.GetBodyAsString()); |
249 } | 261 } |
250 | 262 |
| 263 EXPECT_EQ(1, network_delegate_.created_requests()); |
| 264 |
251 // Kill the HTTP server. | 265 // Kill the HTTP server. |
252 ASSERT_TRUE(test_server_.Stop()); | 266 ASSERT_TRUE(test_server_.Stop()); |
253 | 267 |
254 // Fetch again -- will fail unless served from cache. | 268 // Fetch again -- will fail unless served from cache. |
255 { | 269 { |
256 TestFetchCallback callback; | 270 TestFetchCallback callback; |
257 StartRequest(url, callback, &fetcher); | 271 StartRequest(url, callback, &fetcher); |
258 FetchResult result = callback.WaitForResult(); | 272 FetchResult result = callback.WaitForResult(); |
259 EXPECT_EQ(OK, result.net_error); | 273 EXPECT_EQ(OK, result.net_error); |
260 EXPECT_EQ("-cacheable_1hr.crt-\n", result.GetBodyAsString()); | 274 EXPECT_EQ("-cacheable_1hr.crt-\n", result.GetBodyAsString()); |
261 } | 275 } |
| 276 |
| 277 EXPECT_EQ(2, network_delegate_.created_requests()); |
262 } | 278 } |
263 | 279 |
264 // Verify that the maximum response body constraints are enforced by fetching a | 280 // Verify that the maximum response body constraints are enforced by fetching a |
265 // resource that is larger than the limit. | 281 // resource that is larger than the limit. |
266 TEST_F(CertNetFetcherTest, TooLarge) { | 282 TEST_F(CertNetFetcherTest, TooLarge) { |
267 ASSERT_TRUE(test_server_.Start()); | 283 ASSERT_TRUE(test_server_.Start()); |
268 | 284 |
269 CertNetFetcher fetcher(&context_); | 285 CertNetFetcher fetcher(&context_); |
270 | 286 |
271 // This file has a response body 12 bytes long. So setting the maximum to 11 | 287 // This file has a response body 12 bytes long. So setting the maximum to 11 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 | 333 |
318 GURL url("https://foopy/foo.crt"); | 334 GURL url("https://foopy/foo.crt"); |
319 TestFetchCallback callback; | 335 TestFetchCallback callback; |
320 StartRequest(url, callback, &fetcher); | 336 StartRequest(url, callback, &fetcher); |
321 // Should NOT complete synchronously despite being a test that could be done | 337 // Should NOT complete synchronously despite being a test that could be done |
322 // immediately. | 338 // immediately. |
323 EXPECT_FALSE(callback.HasResult()); | 339 EXPECT_FALSE(callback.HasResult()); |
324 FetchResult result = callback.WaitForResult(); | 340 FetchResult result = callback.WaitForResult(); |
325 EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, result.net_error); | 341 EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, result.net_error); |
326 EXPECT_TRUE(result.response_body.empty()); | 342 EXPECT_TRUE(result.response_body.empty()); |
| 343 |
| 344 // No request was created because the URL scheme was unsupported. |
| 345 EXPECT_EQ(0, network_delegate_.created_requests()); |
327 } | 346 } |
328 | 347 |
329 // Try fetching a URL which redirects to https. | 348 // Try fetching a URL which redirects to https. |
330 TEST_F(CertNetFetcherTest, RedirectToHttpsNotAllowed) { | 349 TEST_F(CertNetFetcherTest, RedirectToHttpsNotAllowed) { |
331 ASSERT_TRUE(test_server_.Start()); | 350 ASSERT_TRUE(test_server_.Start()); |
332 | 351 |
333 CertNetFetcher fetcher(&context_); | 352 CertNetFetcher fetcher(&context_); |
334 | 353 |
335 GURL url(test_server_.GetURL("files/redirect_https")); | 354 GURL url(test_server_.GetURL("files/redirect_https")); |
336 TestFetchCallback callback; | 355 TestFetchCallback callback; |
337 StartRequest(url, callback, &fetcher); | 356 StartRequest(url, callback, &fetcher); |
338 FetchResult result = callback.WaitForResult(); | 357 FetchResult result = callback.WaitForResult(); |
339 EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, result.net_error); | 358 EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, result.net_error); |
340 EXPECT_TRUE(result.response_body.empty()); | 359 EXPECT_TRUE(result.response_body.empty()); |
| 360 |
| 361 EXPECT_EQ(1, network_delegate_.created_requests()); |
341 } | 362 } |
342 | 363 |
343 // Try fetching an unsupported URL scheme (https) and then immediately | 364 // Try fetching an unsupported URL scheme (https) and then immediately |
344 // cancelling. This is a bit special because this codepath needs to post a task. | 365 // cancelling. This is a bit special because this codepath needs to post a task. |
345 TEST_F(CertNetFetcherTest, CancelHttpsNotAllowed) { | 366 TEST_F(CertNetFetcherTest, CancelHttpsNotAllowed) { |
346 ASSERT_TRUE(test_server_.Start()); | 367 ASSERT_TRUE(test_server_.Start()); |
347 | 368 |
348 CertNetFetcher fetcher(&context_); | 369 CertNetFetcher fetcher(&context_); |
349 | 370 |
350 GURL url("https://foopy/foo.crt"); | 371 GURL url("https://foopy/foo.crt"); |
351 TestFetchCallback callback; | 372 TestFetchCallback callback; |
352 CertNetFetcher::RequestId id = StartRequest(url, callback, &fetcher); | 373 CertNetFetcher::RequestId id = StartRequest(url, callback, &fetcher); |
353 | 374 |
354 // Should NOT complete synchronously despite being a test that could be done | 375 // Should NOT complete synchronously despite being a test that could be done |
355 // immediately. | 376 // immediately. |
356 EXPECT_FALSE(callback.HasResult()); | 377 EXPECT_FALSE(callback.HasResult()); |
357 | 378 |
| 379 EXPECT_EQ(0, network_delegate_.created_requests()); |
| 380 |
358 fetcher.CancelRequest(id); | 381 fetcher.CancelRequest(id); |
359 } | 382 } |
360 | 383 |
361 // Start a few requests, and cancel one of them before running the message loop | 384 // Start a few requests, and cancel one of them before running the message loop |
362 // again. | 385 // again. |
363 TEST_F(CertNetFetcherTest, CancelBeforeRunningMessageLoop) { | 386 TEST_F(CertNetFetcherTest, CancelBeforeRunningMessageLoop) { |
364 ASSERT_TRUE(test_server_.Start()); | 387 ASSERT_TRUE(test_server_.Start()); |
365 | 388 |
366 CertNetFetcher fetcher(&context_); | 389 CertNetFetcher fetcher(&context_); |
367 TestFetchCallback callback1; | 390 TestFetchCallback callback1; |
368 TestFetchCallback callback2; | 391 TestFetchCallback callback2; |
369 TestFetchCallback callback3; | 392 TestFetchCallback callback3; |
370 | 393 |
371 // Request a URL with Content-Type "application/pkix-cert" | 394 // Request a URL with Content-Type "application/pkix-cert" |
372 GURL url1 = test_server_.GetURL("files/cert.crt"); | 395 GURL url1 = test_server_.GetURL("files/cert.crt"); |
373 StartRequest(url1, callback1, &fetcher); | 396 StartRequest(url1, callback1, &fetcher); |
374 | 397 |
| 398 EXPECT_EQ(1, network_delegate_.created_requests()); |
| 399 |
375 // Request a URL with Content-Type "application/pkix-crl" | 400 // Request a URL with Content-Type "application/pkix-crl" |
376 GURL url2 = test_server_.GetURL("files/root.crl"); | 401 GURL url2 = test_server_.GetURL("files/root.crl"); |
377 CertNetFetcher::RequestId id2 = StartRequest(url2, callback2, &fetcher); | 402 CertNetFetcher::RequestId id2 = StartRequest(url2, callback2, &fetcher); |
378 | 403 |
| 404 EXPECT_EQ(2, network_delegate_.created_requests()); |
| 405 |
379 // Request a URL with Content-Type "application/pkcs7-mime" | 406 // Request a URL with Content-Type "application/pkcs7-mime" |
380 GURL url3 = test_server_.GetURL("files/certs.p7c"); | 407 GURL url3 = test_server_.GetURL("files/certs.p7c"); |
381 StartRequest(url3, callback3, &fetcher); | 408 StartRequest(url3, callback3, &fetcher); |
382 | 409 |
| 410 EXPECT_EQ(3, network_delegate_.created_requests()); |
| 411 |
383 EXPECT_FALSE(callback1.HasResult()); | 412 EXPECT_FALSE(callback1.HasResult()); |
384 EXPECT_FALSE(callback2.HasResult()); | 413 EXPECT_FALSE(callback2.HasResult()); |
385 EXPECT_FALSE(callback3.HasResult()); | 414 EXPECT_FALSE(callback3.HasResult()); |
386 | 415 |
387 // Cancel the second request. | 416 // Cancel the second request. |
388 fetcher.CancelRequest(id2); | 417 fetcher.CancelRequest(id2); |
389 | 418 |
390 // Wait for the non-cancelled requests to complete. | 419 // Wait for the non-cancelled requests to complete. |
391 FetchResult result1 = callback1.WaitForResult(); | 420 FetchResult result1 = callback1.WaitForResult(); |
392 FetchResult result3 = callback3.WaitForResult(); | 421 FetchResult result3 = callback3.WaitForResult(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 487 |
459 CertNetFetcher fetcher(&context_); | 488 CertNetFetcher fetcher(&context_); |
460 | 489 |
461 GURL url(test_server_.GetURL("slow/certs.p7c?20.1")); | 490 GURL url(test_server_.GetURL("slow/certs.p7c?20.1")); |
462 TestFetchCallback callback; | 491 TestFetchCallback callback; |
463 StartRequest(url, callback, &fetcher); | 492 StartRequest(url, callback, &fetcher); |
464 | 493 |
465 // Note that the request is never completed, nor cancelled. | 494 // Note that the request is never completed, nor cancelled. |
466 } | 495 } |
467 | 496 |
| 497 // Fetch the same URLs in parallel and verify that only 1 request is made per |
| 498 // URL. |
| 499 TEST_F(CertNetFetcherTest, ParallelFetchDupes) { |
| 500 ASSERT_TRUE(test_server_.Start()); |
| 501 |
| 502 CertNetFetcher fetcher(&context_); |
| 503 |
| 504 // Requests for url1. |
| 505 GURL url1 = test_server_.GetURL("files/cert.crt"); |
| 506 TestFetchCallback callback1[3]; |
| 507 CertNetFetcher::RequestId request1[3]; |
| 508 |
| 509 // Requests for url2. |
| 510 GURL url2 = test_server_.GetURL("files/root.crl"); |
| 511 TestFetchCallback callback2[3]; |
| 512 CertNetFetcher::RequestId request2[3]; |
| 513 |
| 514 // Interleave requests for URLs 1 and 2. |
| 515 request1[0] = StartRequest(url1, callback1[0], &fetcher); |
| 516 request2[0] = StartRequest(url2, callback2[0], &fetcher); |
| 517 request1[1] = StartRequest(url1, callback1[1], &fetcher); |
| 518 request2[1] = StartRequest(url2, callback2[1], &fetcher); |
| 519 request2[2] = StartRequest(url2, callback2[2], &fetcher); |
| 520 request1[2] = StartRequest(url1, callback1[2], &fetcher); |
| 521 |
| 522 // Cancel all but one of the callback1[]. |
| 523 for (size_t i = 0; i < arraysize(callback1) - 1; ++i) { |
| 524 fetcher.CancelRequest(request1[i]); |
| 525 request1[i] = NULL; |
| 526 } |
| 527 |
| 528 FetchResult result1; |
| 529 FetchResult result2[3]; |
| 530 |
| 531 // Wait for the remaining requests to finish. |
| 532 result1 = callback1[2].WaitForResult(); |
| 533 for (size_t i = 0; i < arraysize(callback2); ++i) |
| 534 result2[i] = callback2[i].WaitForResult(); |
| 535 |
| 536 // Verify that none of the other requests for url1 completed (since they were |
| 537 // cancelled). |
| 538 for (size_t i = 0; i < arraysize(request1) - 1; ++i) |
| 539 EXPECT_FALSE(callback1[i].HasResult()); |
| 540 |
| 541 // Verify the fetch results. |
| 542 EXPECT_EQ(OK, result1.net_error); |
| 543 EXPECT_EQ("-cert.crt-\n", result1.GetBodyAsString()); |
| 544 |
| 545 for (size_t i = 0; i < arraysize(callback2); ++i) { |
| 546 EXPECT_EQ(OK, result2[i].net_error); |
| 547 EXPECT_EQ("-root.crl-\n", result2[i].GetBodyAsString()); |
| 548 } |
| 549 |
| 550 // Verify that only 2 URLRequests were started even though 6 requests were |
| 551 // issued. |
| 552 EXPECT_EQ(2, network_delegate_.created_requests()); |
| 553 } |
| 554 |
| 555 // Cancel a request and then start another one for the same URL. |
| 556 TEST_F(CertNetFetcherTest, CancelThenStart) { |
| 557 ASSERT_TRUE(test_server_.Start()); |
| 558 |
| 559 CertNetFetcher fetcher(&context_); |
| 560 TestFetchCallback callback1; |
| 561 CertNetFetcher::RequestId request1; |
| 562 |
| 563 TestFetchCallback callback2; |
| 564 CertNetFetcher::RequestId request2; |
| 565 |
| 566 TestFetchCallback callback3; |
| 567 CertNetFetcher::RequestId request3; |
| 568 |
| 569 GURL url = test_server_.GetURL("files/cert.crt"); |
| 570 |
| 571 request1 = StartRequest(url, callback1, &fetcher); |
| 572 fetcher.CancelRequest(request1); |
| 573 |
| 574 request2 = StartRequest(url, callback2, &fetcher); |
| 575 |
| 576 request3 = StartRequest(url, callback3, &fetcher); |
| 577 fetcher.CancelRequest(request3); |
| 578 |
| 579 // All but |request2| were canceled. |
| 580 FetchResult result = callback2.WaitForResult(); |
| 581 |
| 582 EXPECT_EQ(OK, result.net_error); |
| 583 EXPECT_EQ("-cert.crt-\n", result.GetBodyAsString()); |
| 584 |
| 585 EXPECT_FALSE(callback1.HasResult()); |
| 586 EXPECT_FALSE(callback3.HasResult()); |
| 587 |
| 588 // One URLRequest that was cancelled, then another right afterwards. |
| 589 EXPECT_EQ(2, network_delegate_.created_requests()); |
| 590 } |
| 591 |
| 592 // Start duplicate requests and then cancel all of them. |
| 593 TEST_F(CertNetFetcherTest, CancelAll) { |
| 594 ASSERT_TRUE(test_server_.Start()); |
| 595 |
| 596 CertNetFetcher fetcher(&context_); |
| 597 TestFetchCallback callback[3]; |
| 598 CertNetFetcher::RequestId request[3]; |
| 599 |
| 600 GURL url = test_server_.GetURL("files/cert.crt"); |
| 601 |
| 602 for (size_t i = 0; i < arraysize(callback); ++i) { |
| 603 request[i] = StartRequest(url, callback[i], &fetcher); |
| 604 } |
| 605 |
| 606 for (size_t i = 0; i < arraysize(request); ++i) |
| 607 fetcher.CancelRequest(request[i]); |
| 608 |
| 609 EXPECT_EQ(1, network_delegate_.created_requests()); |
| 610 |
| 611 for (size_t i = 0; i < arraysize(request); ++i) |
| 612 EXPECT_FALSE(callback[i].HasResult()); |
| 613 } |
| 614 |
| 615 void DeleteCertNetFetcher(CertNetFetcher* fetcher) { |
| 616 delete fetcher; |
| 617 } |
| 618 |
| 619 // Delete the CertNetFetcher within a request callback. |
| 620 TEST_F(CertNetFetcherTest, DeleteWithinCallback) { |
| 621 ASSERT_TRUE(test_server_.Start()); |
| 622 |
| 623 // Deleted by callback2. |
| 624 CertNetFetcher* fetcher = new CertNetFetcher(&context_); |
| 625 |
| 626 GURL url = test_server_.GetURL("files/cert.crt"); |
| 627 |
| 628 TestFetchCallback callback[4]; |
| 629 callback[1].set_extra_closure(base::Bind(DeleteCertNetFetcher, fetcher)); |
| 630 |
| 631 for (size_t i = 0; i < arraysize(callback); ++i) |
| 632 StartRequest(url, callback[i], fetcher); |
| 633 |
| 634 EXPECT_EQ(1, network_delegate_.created_requests()); |
| 635 |
| 636 callback[1].WaitForResult(); |
| 637 |
| 638 // Assume requests for the same URL are executed in FIFO order. |
| 639 EXPECT_TRUE(callback[0].HasResult()); |
| 640 EXPECT_FALSE(callback[2].HasResult()); |
| 641 EXPECT_FALSE(callback[3].HasResult()); |
| 642 } |
| 643 |
| 644 void FetchRequest(CertNetFetcher* fetcher, |
| 645 const GURL& url, |
| 646 TestFetchCallback* callback) { |
| 647 StartRequest(url, *callback, fetcher); |
| 648 } |
| 649 |
| 650 // Make a request during callback for the same URL. |
| 651 TEST_F(CertNetFetcherTest, FetchWithinCallback) { |
| 652 ASSERT_TRUE(test_server_.Start()); |
| 653 |
| 654 CertNetFetcher fetcher(&context_); |
| 655 |
| 656 GURL url = test_server_.GetURL("files/cert.crt"); |
| 657 |
| 658 TestFetchCallback callback[5]; |
| 659 callback[1].set_extra_closure( |
| 660 base::Bind(FetchRequest, &fetcher, url, &callback[4])); |
| 661 |
| 662 for (size_t i = 0; i < arraysize(callback) - 1; ++i) |
| 663 StartRequest(url, callback[i], &fetcher); |
| 664 |
| 665 EXPECT_EQ(1, network_delegate_.created_requests()); |
| 666 |
| 667 for (size_t i = 0; i < arraysize(callback); ++i) { |
| 668 FetchResult result = callback[i].WaitForResult(); |
| 669 EXPECT_EQ(OK, result.net_error); |
| 670 EXPECT_EQ("-cert.crt-\n", result.GetBodyAsString()); |
| 671 } |
| 672 |
| 673 // The fetch started within a callback should have started a new request |
| 674 // rather than attaching to the current job. |
| 675 EXPECT_EQ(2, network_delegate_.created_requests()); |
| 676 } |
| 677 |
| 678 void CancelRequest(CertNetFetcher* fetcher, CertNetFetcher::RequestId request) { |
| 679 fetcher->CancelRequest(request); |
| 680 } |
| 681 |
| 682 // Cancel a request while executing a callback for the same job. |
| 683 TEST_F(CertNetFetcherTest, CancelWithinCallback) { |
| 684 ASSERT_TRUE(test_server_.Start()); |
| 685 |
| 686 CertNetFetcher fetcher(&context_); |
| 687 |
| 688 GURL url = test_server_.GetURL("files/cert.crt"); |
| 689 |
| 690 TestFetchCallback callback[4]; |
| 691 CertNetFetcher::RequestId request[4]; |
| 692 |
| 693 for (size_t i = 0; i < arraysize(callback); ++i) { |
| 694 request[i] = StartRequest(url, callback[i], &fetcher); |
| 695 } |
| 696 |
| 697 // Cancel request[2] when the callback for request[1] runs. |
| 698 callback[1].set_extra_closure( |
| 699 base::Bind(CancelRequest, &fetcher, request[2])); |
| 700 |
| 701 EXPECT_EQ(1, network_delegate_.created_requests()); |
| 702 |
| 703 for (size_t i = 0; i < arraysize(request); ++i) { |
| 704 if (i == 2) |
| 705 continue; |
| 706 |
| 707 FetchResult result = callback[i].WaitForResult(); |
| 708 EXPECT_EQ(OK, result.net_error); |
| 709 EXPECT_EQ("-cert.crt-\n", result.GetBodyAsString()); |
| 710 } |
| 711 |
| 712 // request[2] was cancelled. |
| 713 EXPECT_FALSE(callback[2].HasResult()); |
| 714 } |
| 715 |
468 } // namespace net | 716 } // namespace net |
OLD | NEW |