| Index: net/cert/cert_net_fetcher_unittest.cc
|
| diff --git a/net/cert/cert_net_fetcher_unittest.cc b/net/cert/cert_net_fetcher_unittest.cc
|
| index 95c670ff60cc2a0c1be4a756909e3586f2ae1899..cf10082eed07c1c851a8ff17f826f1a80cefcfbf 100644
|
| --- a/net/cert/cert_net_fetcher_unittest.cc
|
| +++ b/net/cert/cert_net_fetcher_unittest.cc
|
| @@ -17,10 +17,6 @@
|
| #include "testing/platform_test.h"
|
|
|
| // TODO(eroman): Test that cookies aren't sent.
|
| -// TODO(eroman): Request de-duplication
|
| -// TODO(eroman): Cancel duplicated requests within a callback
|
| -// TODO(eroman): Start requests for the same job within a callback
|
| -// TODO(eroman): Delete the CertNetFetcher within callback
|
|
|
| using base::ASCIIToUTF16;
|
|
|
| @@ -99,12 +95,22 @@ class TestFetchCallback {
|
|
|
| bool HasResult() const { return have_result_; }
|
|
|
| + // Sets an extra action (in addition to recording the result) that is run when
|
| + // the FetchCallback is invoked.
|
| + void set_extra_closure(const base::Closure& closure) {
|
| + extra_closure_ = closure;
|
| + }
|
| +
|
| private:
|
| void OnCallback(int net_error, const std::vector<uint8_t>& response_body) {
|
| DCHECK(!have_result_);
|
| have_result_ = true;
|
| result_.net_error = net_error;
|
| result_.response_body = response_body;
|
| +
|
| + if (!extra_closure_.is_null())
|
| + extra_closure_.Run();
|
| +
|
| if (waiting_for_result_)
|
| base::MessageLoop::current()->Quit();
|
| }
|
| @@ -113,6 +119,7 @@ class TestFetchCallback {
|
| FetchResult result_;
|
| bool have_result_;
|
| bool waiting_for_result_;
|
| + base::Closure extra_closure_;
|
| };
|
|
|
| } // namespace
|
| @@ -122,10 +129,13 @@ class CertNetFetcherTest : public PlatformTest {
|
| CertNetFetcherTest()
|
| : test_server_(SpawnedTestServer::TYPE_HTTP,
|
| net::SpawnedTestServer::kLocalhost,
|
| - base::FilePath(kDocRoot)) {}
|
| + base::FilePath(kDocRoot)) {
|
| + context_.set_network_delegate(&network_delegate_);
|
| + }
|
|
|
| protected:
|
| SpawnedTestServer test_server_;
|
| + TestNetworkDelegate network_delegate_;
|
| RequestContext context_;
|
| };
|
|
|
| @@ -170,6 +180,8 @@ TEST_F(CertNetFetcherTest, ParallelFetchNoDupes) {
|
| EXPECT_EQ("-root.crl-\n", result2.GetBodyAsString());
|
| EXPECT_EQ(OK, result3.net_error);
|
| EXPECT_EQ("-certs.p7c-\n", result3.GetBodyAsString());
|
| +
|
| + EXPECT_EQ(3, network_delegate_.created_requests());
|
| }
|
|
|
| // Fetch a caIssuers URL which has an unexpected extension and Content-Type.
|
| @@ -248,6 +260,8 @@ TEST_F(CertNetFetcherTest, Cache) {
|
| EXPECT_EQ("-cacheable_1hr.crt-\n", result.GetBodyAsString());
|
| }
|
|
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| +
|
| // Kill the HTTP server.
|
| ASSERT_TRUE(test_server_.Stop());
|
|
|
| @@ -259,6 +273,8 @@ TEST_F(CertNetFetcherTest, Cache) {
|
| EXPECT_EQ(OK, result.net_error);
|
| EXPECT_EQ("-cacheable_1hr.crt-\n", result.GetBodyAsString());
|
| }
|
| +
|
| + EXPECT_EQ(2, network_delegate_.created_requests());
|
| }
|
|
|
| // Verify that the maximum response body constraints are enforced by fetching a
|
| @@ -324,6 +340,9 @@ TEST_F(CertNetFetcherTest, HttpsNotAllowed) {
|
| FetchResult result = callback.WaitForResult();
|
| EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, result.net_error);
|
| EXPECT_TRUE(result.response_body.empty());
|
| +
|
| + // No request was created because the URL scheme was unsupported.
|
| + EXPECT_EQ(0, network_delegate_.created_requests());
|
| }
|
|
|
| // Try fetching a URL which redirects to https.
|
| @@ -338,6 +357,8 @@ TEST_F(CertNetFetcherTest, RedirectToHttpsNotAllowed) {
|
| FetchResult result = callback.WaitForResult();
|
| EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, result.net_error);
|
| EXPECT_TRUE(result.response_body.empty());
|
| +
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| }
|
|
|
| // Try fetching an unsupported URL scheme (https) and then immediately
|
| @@ -355,6 +376,8 @@ TEST_F(CertNetFetcherTest, CancelHttpsNotAllowed) {
|
| // immediately.
|
| EXPECT_FALSE(callback.HasResult());
|
|
|
| + EXPECT_EQ(0, network_delegate_.created_requests());
|
| +
|
| fetcher.CancelRequest(id);
|
| }
|
|
|
| @@ -372,14 +395,20 @@ TEST_F(CertNetFetcherTest, CancelBeforeRunningMessageLoop) {
|
| GURL url1 = test_server_.GetURL("files/cert.crt");
|
| StartRequest(url1, callback1, &fetcher);
|
|
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| +
|
| // Request a URL with Content-Type "application/pkix-crl"
|
| GURL url2 = test_server_.GetURL("files/root.crl");
|
| CertNetFetcher::RequestId id2 = StartRequest(url2, callback2, &fetcher);
|
|
|
| + EXPECT_EQ(2, network_delegate_.created_requests());
|
| +
|
| // Request a URL with Content-Type "application/pkcs7-mime"
|
| GURL url3 = test_server_.GetURL("files/certs.p7c");
|
| StartRequest(url3, callback3, &fetcher);
|
|
|
| + EXPECT_EQ(3, network_delegate_.created_requests());
|
| +
|
| EXPECT_FALSE(callback1.HasResult());
|
| EXPECT_FALSE(callback2.HasResult());
|
| EXPECT_FALSE(callback3.HasResult());
|
| @@ -465,4 +494,223 @@ TEST_F(CertNetFetcherTest, DeleteCancels) {
|
| // Note that the request is never completed, nor cancelled.
|
| }
|
|
|
| +// Fetch the same URLs in parallel and verify that only 1 request is made per
|
| +// URL.
|
| +TEST_F(CertNetFetcherTest, ParallelFetchDupes) {
|
| + ASSERT_TRUE(test_server_.Start());
|
| +
|
| + CertNetFetcher fetcher(&context_);
|
| +
|
| + // Requests for url1.
|
| + GURL url1 = test_server_.GetURL("files/cert.crt");
|
| + TestFetchCallback callback1[3];
|
| + CertNetFetcher::RequestId request1[3];
|
| +
|
| + // Requests for url2.
|
| + GURL url2 = test_server_.GetURL("files/root.crl");
|
| + TestFetchCallback callback2[3];
|
| + CertNetFetcher::RequestId request2[3];
|
| +
|
| + // Interleave requests for URLs 1 and 2.
|
| + request1[0] = StartRequest(url1, callback1[0], &fetcher);
|
| + request2[0] = StartRequest(url2, callback2[0], &fetcher);
|
| + request1[1] = StartRequest(url1, callback1[1], &fetcher);
|
| + request2[1] = StartRequest(url2, callback2[1], &fetcher);
|
| + request2[2] = StartRequest(url2, callback2[2], &fetcher);
|
| + request1[2] = StartRequest(url1, callback1[2], &fetcher);
|
| +
|
| + // Cancel all but one of the callback1[].
|
| + for (size_t i = 0; i < arraysize(callback1) - 1; ++i) {
|
| + fetcher.CancelRequest(request1[i]);
|
| + request1[i] = NULL;
|
| + }
|
| +
|
| + FetchResult result1;
|
| + FetchResult result2[3];
|
| +
|
| + // Wait for the remaining requests to finish.
|
| + result1 = callback1[2].WaitForResult();
|
| + for (size_t i = 0; i < arraysize(callback2); ++i)
|
| + result2[i] = callback2[i].WaitForResult();
|
| +
|
| + // Verify that none of the other requests for url1 completed (since they were
|
| + // cancelled).
|
| + for (size_t i = 0; i < arraysize(request1) - 1; ++i)
|
| + EXPECT_FALSE(callback1[i].HasResult());
|
| +
|
| + // Verify the fetch results.
|
| + EXPECT_EQ(OK, result1.net_error);
|
| + EXPECT_EQ("-cert.crt-\n", result1.GetBodyAsString());
|
| +
|
| + for (size_t i = 0; i < arraysize(callback2); ++i) {
|
| + EXPECT_EQ(OK, result2[i].net_error);
|
| + EXPECT_EQ("-root.crl-\n", result2[i].GetBodyAsString());
|
| + }
|
| +
|
| + // Verify that only 2 URLRequests were started even though 6 requests were
|
| + // issued.
|
| + EXPECT_EQ(2, network_delegate_.created_requests());
|
| +}
|
| +
|
| +// Cancel a request and then start another one for the same URL.
|
| +TEST_F(CertNetFetcherTest, CancelThenStart) {
|
| + ASSERT_TRUE(test_server_.Start());
|
| +
|
| + CertNetFetcher fetcher(&context_);
|
| + TestFetchCallback callback1;
|
| + CertNetFetcher::RequestId request1;
|
| +
|
| + TestFetchCallback callback2;
|
| + CertNetFetcher::RequestId request2;
|
| +
|
| + TestFetchCallback callback3;
|
| + CertNetFetcher::RequestId request3;
|
| +
|
| + GURL url = test_server_.GetURL("files/cert.crt");
|
| +
|
| + request1 = StartRequest(url, callback1, &fetcher);
|
| + fetcher.CancelRequest(request1);
|
| +
|
| + request2 = StartRequest(url, callback2, &fetcher);
|
| +
|
| + request3 = StartRequest(url, callback3, &fetcher);
|
| + fetcher.CancelRequest(request3);
|
| +
|
| + // All but |request2| were canceled.
|
| + FetchResult result = callback2.WaitForResult();
|
| +
|
| + EXPECT_EQ(OK, result.net_error);
|
| + EXPECT_EQ("-cert.crt-\n", result.GetBodyAsString());
|
| +
|
| + EXPECT_FALSE(callback1.HasResult());
|
| + EXPECT_FALSE(callback3.HasResult());
|
| +
|
| + // One URLRequest that was cancelled, then another right afterwards.
|
| + EXPECT_EQ(2, network_delegate_.created_requests());
|
| +}
|
| +
|
| +// Start duplicate requests and then cancel all of them.
|
| +TEST_F(CertNetFetcherTest, CancelAll) {
|
| + ASSERT_TRUE(test_server_.Start());
|
| +
|
| + CertNetFetcher fetcher(&context_);
|
| + TestFetchCallback callback[3];
|
| + CertNetFetcher::RequestId request[3];
|
| +
|
| + GURL url = test_server_.GetURL("files/cert.crt");
|
| +
|
| + for (size_t i = 0; i < arraysize(callback); ++i) {
|
| + request[i] = StartRequest(url, callback[i], &fetcher);
|
| + }
|
| +
|
| + for (size_t i = 0; i < arraysize(request); ++i)
|
| + fetcher.CancelRequest(request[i]);
|
| +
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| +
|
| + for (size_t i = 0; i < arraysize(request); ++i)
|
| + EXPECT_FALSE(callback[i].HasResult());
|
| +}
|
| +
|
| +void DeleteCertNetFetcher(CertNetFetcher* fetcher) {
|
| + delete fetcher;
|
| +}
|
| +
|
| +// Delete the CertNetFetcher within a request callback.
|
| +TEST_F(CertNetFetcherTest, DeleteWithinCallback) {
|
| + ASSERT_TRUE(test_server_.Start());
|
| +
|
| + // Deleted by callback2.
|
| + CertNetFetcher* fetcher = new CertNetFetcher(&context_);
|
| +
|
| + GURL url = test_server_.GetURL("files/cert.crt");
|
| +
|
| + TestFetchCallback callback[4];
|
| + callback[1].set_extra_closure(base::Bind(DeleteCertNetFetcher, fetcher));
|
| +
|
| + for (size_t i = 0; i < arraysize(callback); ++i)
|
| + StartRequest(url, callback[i], fetcher);
|
| +
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| +
|
| + callback[1].WaitForResult();
|
| +
|
| + // Assume requests for the same URL are executed in FIFO order.
|
| + EXPECT_TRUE(callback[0].HasResult());
|
| + EXPECT_FALSE(callback[2].HasResult());
|
| + EXPECT_FALSE(callback[3].HasResult());
|
| +}
|
| +
|
| +void FetchRequest(CertNetFetcher* fetcher,
|
| + const GURL& url,
|
| + TestFetchCallback* callback) {
|
| + StartRequest(url, *callback, fetcher);
|
| +}
|
| +
|
| +// Make a request during callback for the same URL.
|
| +TEST_F(CertNetFetcherTest, FetchWithinCallback) {
|
| + ASSERT_TRUE(test_server_.Start());
|
| +
|
| + CertNetFetcher fetcher(&context_);
|
| +
|
| + GURL url = test_server_.GetURL("files/cert.crt");
|
| +
|
| + TestFetchCallback callback[5];
|
| + callback[1].set_extra_closure(
|
| + base::Bind(FetchRequest, &fetcher, url, &callback[4]));
|
| +
|
| + for (size_t i = 0; i < arraysize(callback) - 1; ++i)
|
| + StartRequest(url, callback[i], &fetcher);
|
| +
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| +
|
| + for (size_t i = 0; i < arraysize(callback); ++i) {
|
| + FetchResult result = callback[i].WaitForResult();
|
| + EXPECT_EQ(OK, result.net_error);
|
| + EXPECT_EQ("-cert.crt-\n", result.GetBodyAsString());
|
| + }
|
| +
|
| + // The fetch started within a callback should have started a new request
|
| + // rather than attaching to the current job.
|
| + EXPECT_EQ(2, network_delegate_.created_requests());
|
| +}
|
| +
|
| +void CancelRequest(CertNetFetcher* fetcher, CertNetFetcher::RequestId request) {
|
| + fetcher->CancelRequest(request);
|
| +}
|
| +
|
| +// Cancel a request while executing a callback for the same job.
|
| +TEST_F(CertNetFetcherTest, CancelWithinCallback) {
|
| + ASSERT_TRUE(test_server_.Start());
|
| +
|
| + CertNetFetcher fetcher(&context_);
|
| +
|
| + GURL url = test_server_.GetURL("files/cert.crt");
|
| +
|
| + TestFetchCallback callback[4];
|
| + CertNetFetcher::RequestId request[4];
|
| +
|
| + for (size_t i = 0; i < arraysize(callback); ++i) {
|
| + request[i] = StartRequest(url, callback[i], &fetcher);
|
| + }
|
| +
|
| + // Cancel request[2] when the callback for request[1] runs.
|
| + callback[1].set_extra_closure(
|
| + base::Bind(CancelRequest, &fetcher, request[2]));
|
| +
|
| + EXPECT_EQ(1, network_delegate_.created_requests());
|
| +
|
| + for (size_t i = 0; i < arraysize(request); ++i) {
|
| + if (i == 2)
|
| + continue;
|
| +
|
| + FetchResult result = callback[i].WaitForResult();
|
| + EXPECT_EQ(OK, result.net_error);
|
| + EXPECT_EQ("-cert.crt-\n", result.GetBodyAsString());
|
| + }
|
| +
|
| + // request[2] was cancelled.
|
| + EXPECT_FALSE(callback[2].HasResult());
|
| +}
|
| +
|
| } // namespace net
|
|
|