// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/cert_net/cert_net_fetcher_impl.h"

#include <string>
#include <utility>

#include "base/compiler_specific.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_server_properties_impl.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

using net::test::IsOk;

// TODO(eroman): Test that cookies aren't sent.

using base::ASCIIToUTF16;

namespace net {

namespace {

const base::FilePath::CharType kDocRoot[] =
    FILE_PATH_LITERAL("net/data/cert_net_fetcher_impl_unittest");

// A non-mock URLRequestContext which can access http:// urls.
class RequestContext : public URLRequestContext {
 public:
  RequestContext() : storage_(this) {
    ProxyConfig no_proxy;
    storage_.set_host_resolver(
        std::unique_ptr<HostResolver>(new MockHostResolver));
    storage_.set_cert_verifier(base::WrapUnique(new MockCertVerifier));
    storage_.set_transport_security_state(
        base::WrapUnique(new TransportSecurityState));
    storage_.set_cert_transparency_verifier(
        base::WrapUnique(new MultiLogCTVerifier));
    storage_.set_ct_policy_enforcer(base::WrapUnique(new CTPolicyEnforcer));
    storage_.set_proxy_service(ProxyService::CreateFixed(no_proxy));
    storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
    storage_.set_http_server_properties(
        std::unique_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));

    HttpNetworkSession::Params params;
    params.host_resolver = host_resolver();
    params.cert_verifier = cert_verifier();
    params.transport_security_state = transport_security_state();
    params.cert_transparency_verifier = cert_transparency_verifier();
    params.ct_policy_enforcer = ct_policy_enforcer();
    params.proxy_service = proxy_service();
    params.ssl_config_service = ssl_config_service();
    params.http_server_properties = http_server_properties();
    storage_.set_http_network_session(
        base::WrapUnique(new HttpNetworkSession(params)));
    storage_.set_http_transaction_factory(base::WrapUnique(new HttpCache(
        storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
        false /* set_up_quic_server_info */)));
    storage_.set_job_factory(base::WrapUnique(new URLRequestJobFactoryImpl()));
  }

  ~RequestContext() override { AssertNoURLRequests(); }

 private:
  URLRequestContextStorage storage_;
};

class FetchResult {
 public:
  FetchResult(Error net_error, const std::vector<uint8_t>& response_body)
      : net_error_(net_error), response_body_(response_body) {}

  void VerifySuccess(const std::string& expected_body) {
    EXPECT_THAT(net_error_, IsOk());
    EXPECT_EQ(expected_body,
              std::string(response_body_.begin(), response_body_.end()));
  }

  void VerifyFailure(Error expected_error) {
    EXPECT_EQ(expected_error, net_error_);
    EXPECT_EQ(0u, response_body_.size());
  }

 private:
  const Error net_error_;
  const std::vector<uint8_t> response_body_;
};

// Helper to synchronously wait for the fetch completion. This is similar to
// net's TestCompletionCallback, but built around FetchCallback.
class TestFetchCallback {
 public:
  TestFetchCallback()
      : callback_(base::Bind(&TestFetchCallback::OnCallback,
                             base::Unretained(this))) {}

  const CertNetFetcher::FetchCallback& callback() const { return callback_; }

  std::unique_ptr<FetchResult> WaitForResult() {
    DCHECK(quit_closure_.is_null());
    while (!HasResult()) {
      base::RunLoop run_loop;
      quit_closure_ = run_loop.QuitClosure();
      run_loop.Run();
      quit_closure_.Reset();
    }
    return std::move(result_);
  }

  bool HasResult() const { return result_.get(); }

  // 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(Error net_error, const std::vector<uint8_t>& response_body) {
    DCHECK(!HasResult());
    result_.reset(new FetchResult(net_error, response_body));

    if (!extra_closure_.is_null())
      extra_closure_.Run();

    if (!quit_closure_.is_null())
      quit_closure_.Run();
  }

  CertNetFetcher::FetchCallback callback_;
  std::unique_ptr<FetchResult> result_;
  base::Closure quit_closure_;
  base::Closure extra_closure_;
};

}  // namespace

class CertNetFetcherImplTest : public PlatformTest {
 public:
  CertNetFetcherImplTest() {
    test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
    context_.set_network_delegate(&network_delegate_);
  }

 protected:
  EmbeddedTestServer test_server_;
  TestNetworkDelegate network_delegate_;
  RequestContext context_;
};

// Helper to start an AIA fetch using default parameters.
WARN_UNUSED_RESULT std::unique_ptr<CertNetFetcher::Request> StartRequest(
    CertNetFetcher* fetcher,
    const GURL& url,
    const TestFetchCallback& callback) {
  return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT,
                                 CertNetFetcher::DEFAULT, callback.callback());
}

// Fetch a few unique URLs using GET in parallel. Each URL has a different body
// and Content-Type.
TEST_F(CertNetFetcherImplTest, ParallelFetchNoDuplicates) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);
  TestFetchCallback callback1;
  TestFetchCallback callback2;
  TestFetchCallback callback3;

  // Request a URL with Content-Type "application/pkix-cert"
  GURL url1 = test_server_.GetURL("/cert.crt");
  std::unique_ptr<CertNetFetcher::Request> request1 =
      StartRequest(&fetcher, url1, callback1);

  // Request a URL with Content-Type "application/pkix-crl"
  GURL url2 = test_server_.GetURL("/root.crl");
  std::unique_ptr<CertNetFetcher::Request> request2 =
      StartRequest(&fetcher, url2, callback2);

  // Request a URL with Content-Type "application/pkcs7-mime"
  GURL url3 = test_server_.GetURL("/certs.p7c");
  std::unique_ptr<CertNetFetcher::Request> request3 =
      StartRequest(&fetcher, url3, callback3);

  // Wait for all of the requests to complete.
  std::unique_ptr<FetchResult> result1 = callback1.WaitForResult();
  std::unique_ptr<FetchResult> result2 = callback2.WaitForResult();
  std::unique_ptr<FetchResult> result3 = callback3.WaitForResult();

  // Verify the fetch results.
  result1->VerifySuccess("-cert.crt-\n");
  result2->VerifySuccess("-root.crl-\n");
  result3->VerifySuccess("-certs.p7c-\n");

  EXPECT_EQ(3, network_delegate_.created_requests());
}

// Fetch a caIssuers URL which has an unexpected extension and Content-Type.
// The extension is .txt and the Content-Type is text/plain. Despite being
// unusual this succeeds as the extension and Content-Type are not required to
// be meaningful.
TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  TestFetchCallback callback;
  GURL url = test_server_.GetURL("/foo.txt");
  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(&fetcher, url, callback);
  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifySuccess("-foo.txt-\n");
}

// Fetch a URLs whose HTTP response code is not 200. These are considered
// failures.
TEST_F(CertNetFetcherImplTest, HttpStatusCode) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  // Response was HTTP status 404.
  {
    TestFetchCallback callback;
    GURL url = test_server_.GetURL("/404.html");
    std::unique_ptr<CertNetFetcher::Request> request =
        StartRequest(&fetcher, url, callback);
    std::unique_ptr<FetchResult> result = callback.WaitForResult();
    result->VerifyFailure(ERR_FAILED);
  }

  // Response was HTTP status 500.
  {
    TestFetchCallback callback;
    GURL url = test_server_.GetURL("/500.html");
    std::unique_ptr<CertNetFetcher::Request> request =
        StartRequest(&fetcher, url, callback);
    std::unique_ptr<FetchResult> result = callback.WaitForResult();
    result->VerifyFailure(ERR_FAILED);
  }
}

// Fetching a URL with a Content-Disposition header should have no effect.
TEST_F(CertNetFetcherImplTest, ContentDisposition) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  TestFetchCallback callback;
  GURL url = test_server_.GetURL("/downloadable.js");
  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(&fetcher, url, callback);
  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifySuccess("-downloadable.js-\n");
}

// Verifies that a cachable request will be served from the HTTP cache the
// second time it is requested.
TEST_F(CertNetFetcherImplTest, Cache) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  // Fetch a URL whose HTTP headers make it cacheable for 1 hour.
  GURL url(test_server_.GetURL("/cacheable_1hr.crt"));
  {
    TestFetchCallback callback;

    std::unique_ptr<CertNetFetcher::Request> request =
        StartRequest(&fetcher, url, callback);
    std::unique_ptr<FetchResult> result = callback.WaitForResult();
    result->VerifySuccess("-cacheable_1hr.crt-\n");
  }

  EXPECT_EQ(1, network_delegate_.created_requests());

  // Kill the HTTP server.
  ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());

  // Fetch again -- will fail unless served from cache.
  {
    TestFetchCallback callback;
    std::unique_ptr<CertNetFetcher::Request> request =
        StartRequest(&fetcher, url, callback);
    std::unique_ptr<FetchResult> result = callback.WaitForResult();
    result->VerifySuccess("-cacheable_1hr.crt-\n");
  }

  EXPECT_EQ(2, network_delegate_.created_requests());
}

// Verify that the maximum response body constraints are enforced by fetching a
// resource that is larger than the limit.
TEST_F(CertNetFetcherImplTest, TooLarge) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  // This file has a response body 12 bytes long. So setting the maximum to 11
  // bytes will cause it to fail.
  GURL url(test_server_.GetURL("/certs.p7c"));
  TestFetchCallback callback;
  std::unique_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers(
      url, CertNetFetcher::DEFAULT, 11, callback.callback());

  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifyFailure(ERR_FILE_TOO_BIG);
}

// Set the timeout to 10 milliseconds, and try fetching a URL that takes 5
// seconds to complete. It should fail due to a timeout.
TEST_F(CertNetFetcherImplTest, Hang) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url(test_server_.GetURL("/slow/certs.p7c?5"));
  TestFetchCallback callback;
  std::unique_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers(
      url, 10, CertNetFetcher::DEFAULT, callback.callback());
  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifyFailure(ERR_TIMED_OUT);
}

// Verify that if a response is gzip-encoded it gets inflated before being
// returned to the caller.
TEST_F(CertNetFetcherImplTest, Gzip) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url(test_server_.GetURL("/gzipped_crl"));
  TestFetchCallback callback;
  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(&fetcher, url, callback);
  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifySuccess("-gzipped_crl-\n");
}

// Try fetching an unsupported URL scheme (https).
TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url("https://foopy/foo.crt");
  TestFetchCallback callback;
  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(&fetcher, url, callback);
  // Should NOT complete synchronously despite being a test that could be done
  // immediately.
  EXPECT_FALSE(callback.HasResult());
  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);

  // 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.
TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url(test_server_.GetURL("/redirect_https"));
  TestFetchCallback callback;

  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(&fetcher, url, callback);
  std::unique_ptr<FetchResult> result = callback.WaitForResult();
  result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);

  EXPECT_EQ(1, network_delegate_.created_requests());
}

// Try fetching an unsupported URL scheme (https) and then immediately
// cancelling. This is a bit special because this codepath needs to post a task.
TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url("https://foopy/foo.crt");
  TestFetchCallback callback;
  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(&fetcher, url, callback);

  // Cancel the request.
  request.reset();

  // Spin the message loop to increase chance of catching a bug.
  base::RunLoop().RunUntilIdle();

  // Should NOT complete synchronously despite being a test that could be done
  // immediately.
  EXPECT_FALSE(callback.HasResult());

  EXPECT_EQ(0, network_delegate_.created_requests());
}

// Start a few requests, and cancel one of them before running the message loop
// again.
TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);
  TestFetchCallback callback1;
  TestFetchCallback callback2;
  TestFetchCallback callback3;

  GURL url1 = test_server_.GetURL("/cert.crt");
  std::unique_ptr<CertNetFetcher::Request> request1 =
      StartRequest(&fetcher, url1, callback1);

  GURL url2 = test_server_.GetURL("/root.crl");
  std::unique_ptr<CertNetFetcher::Request> request2 =
      StartRequest(&fetcher, url2, callback2);

  GURL url3 = test_server_.GetURL("/certs.p7c");

  std::unique_ptr<CertNetFetcher::Request> request3 =
      StartRequest(&fetcher, url3, callback3);

  EXPECT_EQ(3, network_delegate_.created_requests());
  EXPECT_FALSE(callback1.HasResult());
  EXPECT_FALSE(callback2.HasResult());
  EXPECT_FALSE(callback3.HasResult());

  // Cancel the second request.
  request2.reset();

  // Wait for the non-cancelled requests to complete.
  std::unique_ptr<FetchResult> result1 = callback1.WaitForResult();
  std::unique_ptr<FetchResult> result3 = callback3.WaitForResult();

  // Verify the fetch results.
  result1->VerifySuccess("-cert.crt-\n");
  result3->VerifySuccess("-certs.p7c-\n");

  EXPECT_FALSE(callback2.HasResult());
}

// Start several requests, and cancel one of them after the first has completed.
// NOTE: The python test server is single threaded and can only service one
// request at a time. After a socket is opened by the server it waits for it to
// be completed, and any subsequent request will hang until the first socket is
// closed.
// Cancelling the first request can therefore be problematic, since if
// cancellation is done after the socket is opened but before reading/writing,
// then the socket is re-cycled and things will be stalled until the cleanup
// timer (10 seconds) closes it.
// To work around this, the last request is cancelled, and hope that the
// requests are given opened sockets in a FIFO order.
// TODO(eroman): Make this more robust.
TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);
  TestFetchCallback callback1;
  TestFetchCallback callback2;
  TestFetchCallback callback3;

  GURL url1 = test_server_.GetURL("/cert.crt");

  std::unique_ptr<CertNetFetcher::Request> request1 =
      StartRequest(&fetcher, url1, callback1);

  GURL url2 = test_server_.GetURL("/certs.p7c");
  std::unique_ptr<CertNetFetcher::Request> request2 =
      StartRequest(&fetcher, url2, callback2);

  GURL url3("ftp://www.not.supported.com/foo");
  std::unique_ptr<CertNetFetcher::Request> request3 =
      StartRequest(&fetcher, url3, callback3);

  EXPECT_FALSE(callback1.HasResult());
  EXPECT_FALSE(callback2.HasResult());
  EXPECT_FALSE(callback3.HasResult());

  // Wait for the ftp request to complete (it should complete right away since
  // it doesn't even try to connect to the server).
  std::unique_ptr<FetchResult> result3 = callback3.WaitForResult();
  result3->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);

  // Cancel the second outstanding request.
  request2.reset();

  // Wait for the first request to complete.
  std::unique_ptr<FetchResult> result2 = callback1.WaitForResult();

  // Verify the fetch results.
  result2->VerifySuccess("-cert.crt-\n");
}

// Delete a CertNetFetcherImpl with outstanding requests on it.
TEST_F(CertNetFetcherImplTest, DeleteCancels) {
  ASSERT_TRUE(test_server_.Start());

  std::unique_ptr<CertNetFetcherImpl> fetcher(
      new CertNetFetcherImpl(&context_));

  GURL url(test_server_.GetURL("/slow/certs.p7c?20"));
  TestFetchCallback callback;
  std::unique_ptr<CertNetFetcher::Request> request =
      StartRequest(fetcher.get(), url, callback);

  // Destroy the fetcher before the outstanding request.
  fetcher.reset();
}

// Fetch the same URLs in parallel and verify that only 1 request is made per
// URL.
TEST_F(CertNetFetcherImplTest, ParallelFetchDuplicates) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url1 = test_server_.GetURL("/cert.crt");
  GURL url2 = test_server_.GetURL("/root.crl");

  // Issue 3 requests for url1, and 3 requests for url2
  TestFetchCallback callback1;
  std::unique_ptr<CertNetFetcher::Request> request1 =
      StartRequest(&fetcher, url1, callback1);

  TestFetchCallback callback2;
  std::unique_ptr<CertNetFetcher::Request> request2 =
      StartRequest(&fetcher, url2, callback2);

  TestFetchCallback callback3;
  std::unique_ptr<CertNetFetcher::Request> request3 =
      StartRequest(&fetcher, url1, callback3);

  TestFetchCallback callback4;
  std::unique_ptr<CertNetFetcher::Request> request4 =
      StartRequest(&fetcher, url2, callback4);

  TestFetchCallback callback5;
  std::unique_ptr<CertNetFetcher::Request> request5 =
      StartRequest(&fetcher, url2, callback5);

  TestFetchCallback callback6;
  std::unique_ptr<CertNetFetcher::Request> request6 =
      StartRequest(&fetcher, url1, callback6);

  // Cancel all but one of the requests for url1.
  request1.reset();
  request3.reset();

  // Wait for the remaining requests to finish.
  std::unique_ptr<FetchResult> result2 = callback2.WaitForResult();
  std::unique_ptr<FetchResult> result4 = callback4.WaitForResult();
  std::unique_ptr<FetchResult> result5 = callback5.WaitForResult();
  std::unique_ptr<FetchResult> result6 = callback6.WaitForResult();

  // Verify that none of the cancelled requests for url1 completed (since they
  // were cancelled).
  EXPECT_FALSE(callback1.HasResult());
  EXPECT_FALSE(callback3.HasResult());

  // Verify the fetch results.
  result2->VerifySuccess("-root.crl-\n");
  result4->VerifySuccess("-root.crl-\n");
  result5->VerifySuccess("-root.crl-\n");
  result6->VerifySuccess("-cert.crt-\n");

  // 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(CertNetFetcherImplTest, CancelThenStart) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);
  TestFetchCallback callback1;
  TestFetchCallback callback2;
  TestFetchCallback callback3;

  GURL url = test_server_.GetURL("/cert.crt");

  std::unique_ptr<CertNetFetcher::Request> request1 =
      StartRequest(&fetcher, url, callback1);
  request1.reset();

  std::unique_ptr<CertNetFetcher::Request> request2 =
      StartRequest(&fetcher, url, callback2);

  std::unique_ptr<CertNetFetcher::Request> request3 =
      StartRequest(&fetcher, url, callback3);
  request3.reset();

  // All but |request2| were canceled.
  std::unique_ptr<FetchResult> result = callback2.WaitForResult();

  result->VerifySuccess("-cert.crt-\n");

  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(CertNetFetcherImplTest, CancelAll) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);
  TestFetchCallback callback[3];
  std::unique_ptr<CertNetFetcher::Request> request[3];

  GURL url = test_server_.GetURL("/cert.crt");

  for (size_t i = 0; i < arraysize(callback); ++i) {
    request[i] = StartRequest(&fetcher, url, callback[i]);
  }

  // Cancel all the requests.
  for (size_t i = 0; i < arraysize(request); ++i)
    request[i].reset();

  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 CertNetFetcherImpl within a request callback.
TEST_F(CertNetFetcherImplTest, DeleteWithinCallback) {
  ASSERT_TRUE(test_server_.Start());

  // Deleted by callback2.
  CertNetFetcher* fetcher = new CertNetFetcherImpl(&context_);

  GURL url = test_server_.GetURL("/cert.crt");

  TestFetchCallback callback[4];
  std::unique_ptr<CertNetFetcher::Request> reqs[4];
  callback[1].set_extra_closure(base::Bind(DeleteCertNetFetcher, fetcher));

  for (size_t i = 0; i < arraysize(callback); ++i)
    reqs[i] = StartRequest(fetcher, url, callback[i]);

  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,
                  std::unique_ptr<CertNetFetcher::Request>* request) {
  *request = StartRequest(fetcher, url, *callback);
}

// Make a request during callback for the same URL.
TEST_F(CertNetFetcherImplTest, FetchWithinCallback) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url = test_server_.GetURL("/cert.crt");

  TestFetchCallback callback[5];
  std::unique_ptr<CertNetFetcher::Request> req[5];
  callback[1].set_extra_closure(
      base::Bind(FetchRequest, &fetcher, url, &callback[4], &req[4]));

  for (size_t i = 0; i < arraysize(callback) - 1; ++i)
    req[i] = StartRequest(&fetcher, url, callback[i]);

  EXPECT_EQ(1, network_delegate_.created_requests());

  for (size_t i = 0; i < arraysize(callback); ++i) {
    std::unique_ptr<FetchResult> result = callback[i].WaitForResult();
    result->VerifySuccess("-cert.crt-\n");
  }

  // 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(std::unique_ptr<CertNetFetcher::Request>* request) {
  request->reset();
}

// Cancel a request while executing a callback for the same job.
TEST_F(CertNetFetcherImplTest, CancelWithinCallback) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url = test_server_.GetURL("/cert.crt");

  TestFetchCallback callback[4];
  std::unique_ptr<CertNetFetcher::Request> request[4];

  for (size_t i = 0; i < arraysize(callback); ++i)
    request[i] = StartRequest(&fetcher, url, callback[i]);

  // Cancel request[2] when the callback for request[1] runs.
  callback[1].set_extra_closure(base::Bind(CancelRequest, &request[2]));

  EXPECT_EQ(1, network_delegate_.created_requests());

  for (size_t i = 0; i < arraysize(request); ++i) {
    if (i == 2)
      continue;

    std::unique_ptr<FetchResult> result = callback[i].WaitForResult();
    result->VerifySuccess("-cert.crt-\n");
  }

  // request[2] was cancelled.
  EXPECT_FALSE(callback[2].HasResult());
}

// Cancel the final request while executing a callback for the same job. Ensure
// that the job is not deleted twice.
TEST_F(CertNetFetcherImplTest, CancelLastRequestWithinCallback) {
  ASSERT_TRUE(test_server_.Start());

  CertNetFetcherImpl fetcher(&context_);

  GURL url = test_server_.GetURL("/cert.crt");

  TestFetchCallback callback1;
  std::unique_ptr<CertNetFetcher::Request> request1 =
      StartRequest(&fetcher, url, callback1);

  TestFetchCallback callback2;
  std::unique_ptr<CertNetFetcher::Request> request2 =
      StartRequest(&fetcher, url, callback1);

  // Cancel request2 when the callback for request1 runs.
  callback1.set_extra_closure(base::Bind(CancelRequest, &request2));

  EXPECT_EQ(1, network_delegate_.created_requests());

  std::unique_ptr<FetchResult> result = callback1.WaitForResult();
  result->VerifySuccess("-cert.crt-\n");

  // request2 was cancelled.
  EXPECT_FALSE(callback2.HasResult());
}

}  // namespace net
