// 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.
//
// Overview
//
// The main entry point is CertNetFetcherImpl. This is an implementation of
// CertNetFetcher that provides a service for fetching network requests.
//
// The interface for CertNetFetcher is synchronous, however allows
// overlapping requests. When starting a request CertNetFetcherImpl
// returns a CertNetFetcher::Request (CertNetFetcherImpl) that the
// caller can use to cancel the fetch, or wait for it to complete
// (blocking).
//
// The CertNetFetcherImpl is shared between a network thread and a
// caller thread that waits for fetches to happen on the network thread.
//
// The classes are mainly organized based on their thread affinity:
//
// ---------------
// Straddles caller thread and network thread
// ---------------
//
// CertNetFetcherImpl (implements CertNetFetcher)
//   * Main entry point. Must be created and shutdown from the network thread.
//   * Provides a service to start/cancel/wait for URL fetches, to be
//     used on the caller thread.
//   * Returns callers a CertNetFetcher::Request as a handle
//   * Requests can run in parallel, however will block the current thread when
//     reading results.
//   * Posts tasks to network thread to coordinate actual work
//
// RequestCore
//   * Reference-counted bridge between CertNetFetcherRequestImpl and the
//     dependencies on the network thread
//   * Holds the result of the request, a WaitableEvent for signaling
//     completion, and pointers for canceling work on network thread.
//
// ---------------
// Lives on caller thread
// ---------------
//
// CertNetFetcherRequestImpl (implements CertNetFetcher::Request)
//   * Wrapper for cancelling events, or waiting for a request to complete
//   * Waits on a WaitableEvent to complete requests.
//
// ---------------
// Lives on network thread
// ---------------
//
// AsyncCertNetFetcherImpl
//   * Asyncronous manager for outstanding requests. Handles de-duplication,
//     timeouts, and actual integration with network stack. This is where the
//     majority of the logic lives.
//   * Signals completion of requests through RequestCore's WaitableEvent.
//   * Attaches requests to Jobs for the purpose of de-duplication

#include "net/cert_net/cert_net_fetcher_impl.h"

#include <tuple>
#include <utility>

#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/safe_math.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
#include "net/base/load_flags.h"
#include "net/cert/cert_net_fetcher.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request_context.h"

// TODO(eroman): Add support for POST parameters.
// TODO(eroman): Add controls for bypassing the cache.
// TODO(eroman): Add a maximum number of in-flight jobs/requests.
// TODO(eroman): Add NetLog integration.

namespace net {

namespace {

// The size of the buffer used for reading the response body of the URLRequest.
const int kReadBufferSizeInBytes = 4096;

// The maximum size in bytes for the response body when fetching a CRL.
const int kMaxResponseSizeInBytesForCrl = 5 * 1024 * 1024;

// The maximum size in bytes for the response body when fetching an AIA URL
// (caIssuers/OCSP).
const int kMaxResponseSizeInBytesForAia = 64 * 1024;

// The default timeout in seconds for fetch requests.
const int kTimeoutSeconds = 15;

class RequestCore;
struct RequestParams;
class Job;

struct JobToRequestParamsComparator;

struct JobComparator {
  bool operator()(const Job* job1, const Job* job2) const;
};

// Would be a set<unique_ptr> but extraction of owned objects from a set of
// owned types doesn't come until C++17.
using JobSet = std::map<Job*, std::unique_ptr<Job>, JobComparator>;

// AsyncCertNetFetcherImpl manages URLRequests in an async fashion on the
// URLRequestContexts's task runner thread.
//
//  * Schedules
//  * De-duplicates requests
//  * Handles timeouts
class AsyncCertNetFetcherImpl {
 public:
  // Initializes AsyncCertNetFetcherImpl using the specified URLRequestContext
  // for issuing requests. |context| must remain valid until Shutdown() is
  // called or the AsyncCertNetFetcherImpl is destroyed.
  explicit AsyncCertNetFetcherImpl(URLRequestContext* context);

  // The AsyncCertNetFetcherImpl is expected to be kept alive until all
  // requests have completed or Shutdown() is called.
  ~AsyncCertNetFetcherImpl();

  // Starts an asynchronous request to fetch the given URL. On completion
  // request->OnJobCompleted() will be invoked.
  void Fetch(std::unique_ptr<RequestParams> request_params,
             scoped_refptr<RequestCore> request);

  // Cancels outstanding jobs, which stops network requests and signals the
  // corresponding RequestCores that the requests have completed.
  void Shutdown();

 private:
  friend class Job;

  // Finds a job with a matching RequestPararms or returns nullptr if there was
  // no match.
  Job* FindJob(const RequestParams& params);

  // Removes |job| from the in progress jobs and transfers ownership to the
  // caller.
  std::unique_ptr<Job> RemoveJob(Job* job);

  // The in-progress jobs. This set does not contain the job which is actively
  // invoking callbacks (OnJobCompleted).
  JobSet jobs_;

  // Not owned. |context_| must outlive the AsyncCertNetFetcherImpl.
  URLRequestContext* context_ = nullptr;

  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(AsyncCertNetFetcherImpl);
};

// Policy for which URLs are allowed to be fetched. This is called both for the
// initial URL and for each redirect. Returns OK on success or a net error
// code on failure.
Error CanFetchUrl(const GURL& url) {
  if (!url.SchemeIs("http"))
    return ERR_DISALLOWED_URL_SCHEME;
  return OK;
}

base::TimeDelta GetTimeout(int timeout_milliseconds) {
  if (timeout_milliseconds == CertNetFetcher::DEFAULT)
    return base::TimeDelta::FromSeconds(kTimeoutSeconds);
  return base::TimeDelta::FromMilliseconds(timeout_milliseconds);
}

size_t GetMaxResponseBytes(int max_response_bytes,
                           size_t default_max_response_bytes) {
  if (max_response_bytes == CertNetFetcher::DEFAULT)
    return default_max_response_bytes;

  // Ensure that the specified limit is not negative, and cannot result in an
  // overflow while reading.
  base::CheckedNumeric<size_t> check(max_response_bytes);
  check += kReadBufferSizeInBytes;
  DCHECK(check.IsValid());

  return max_response_bytes;
}

enum HttpMethod {
  HTTP_METHOD_GET,
  HTTP_METHOD_POST,
};

// RequestCore tracks an outstanding call to Fetch(). It is
// reference-counted for ease of sharing between threads.
class RequestCore : public base::RefCountedThreadSafe<RequestCore> {
 public:
  explicit RequestCore(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
      : completion_event_(base::WaitableEvent::ResetPolicy::MANUAL,
                          base::WaitableEvent::InitialState::NOT_SIGNALED),
        task_runner_(std::move(task_runner)) {}

  void AttachedToJob(Job* job) {
    DCHECK(task_runner_->RunsTasksInCurrentSequence());
    DCHECK(!job_);
    // Requests should not be attached to jobs after they have been signalled
    // with a cancellation error (which happens via either Cancel() or
    // SignalImmediateError()).
    DCHECK_NE(error_, ERR_ABORTED);
    job_ = job;
  }

  void OnJobCompleted(Job* job,
                      Error error,
                      const std::vector<uint8_t>& response_body) {
    DCHECK(task_runner_->RunsTasksInCurrentSequence());

    DCHECK_EQ(job_, job);
    job_ = nullptr;

    error_ = error;
    bytes_ = response_body;
    completion_event_.Signal();
  }

  // Detaches this request from its job (if it is attached to any) and
  // signals completion with ERR_ABORTED. Can be called from any thread.
  void CancelJob();

  // Can be used to signal that an error was encountered before the request was
  // attached to a job. Can be called from any thread.
  void SignalImmediateError();

  // Should only be called once.
  void WaitForResult(Error* error, std::vector<uint8_t>* bytes) {
    DCHECK(!task_runner_->RunsTasksInCurrentSequence());

    completion_event_.Wait();
    *bytes = std::move(bytes_);
    *error = error_;

    error_ = ERR_UNEXPECTED;
  }

 private:
  friend class base::RefCountedThreadSafe<RequestCore>;

  ~RequestCore() {
    // Requests should have been cancelled prior to destruction.
    DCHECK(!job_);
  }

  // A non-owned pointer to the job that is executing the request.
  Job* job_ = nullptr;

  // May be written to from network thread, or from the caller thread only when
  // there is no work that will be done on the network thread (e.g. when the
  // network thread has been shutdown before the request begins). See comment in
  // SignalImmediateError.
  Error error_ = OK;
  std::vector<uint8_t> bytes_;

  // Indicates when |error_| and |bytes_| have been written to.
  base::WaitableEvent completion_event_;

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;

  DISALLOW_COPY_AND_ASSIGN(RequestCore);
};

struct RequestParams {
  RequestParams();

  bool operator<(const RequestParams& other) const;

  GURL url;
  HttpMethod http_method;
  size_t max_response_bytes;

  // If set to a value <= 0 then means "no timeout".
  base::TimeDelta timeout;

  // IMPORTANT: When adding fields to this structure, update operator<().

 private:
  DISALLOW_COPY_AND_ASSIGN(RequestParams);
};

RequestParams::RequestParams()
    : http_method(HTTP_METHOD_GET), max_response_bytes(0) {}

bool RequestParams::operator<(const RequestParams& other) const {
  return std::tie(url, http_method, max_response_bytes, timeout) <
         std::tie(other.url, other.http_method, other.max_response_bytes,
                  other.timeout);
}

// Job tracks an outstanding URLRequest as well as all of the pending requests
// for it.
class Job : public URLRequest::Delegate {
 public:
  Job(std::unique_ptr<RequestParams> request_params,
      AsyncCertNetFetcherImpl* parent);
  ~Job() override;

  const RequestParams& request_params() const { return *request_params_; }

  // Creates a request and attaches it to the job. When the job completes it
  // will notify the request of completion through OnJobCompleted.
  void AttachRequest(scoped_refptr<RequestCore> request);

  // Removes |request| from the job.
  void DetachRequest(RequestCore* request);

  // Creates and starts a URLRequest for the job. After the URLRequest has
  // completed, OnJobCompleted() will be invoked and all the registered requests
  // notified of completion.
  void StartURLRequest(URLRequestContext* context);

  // Cancels the request with an ERR_ABORTED error and invokes
  // RequestCore::OnJobCompleted() to notify the registered requests of the
  // cancellation. The job is *not* removed from the AsyncCertNetFetcherImpl.
  void Cancel();

 private:
  // Implementation of URLRequest::Delegate
  void OnReceivedRedirect(URLRequest* request,
                          const RedirectInfo& redirect_info,
                          bool* defer_redirect) override;
  void OnResponseStarted(URLRequest* request, int net_error) override;
  void OnReadCompleted(URLRequest* request, int bytes_read) override;

  // Clears the URLRequest and timer. Helper for doing work common to
  // cancellation and job completion.
  void Stop();

  // Reads as much data as available from |request|.
  void ReadBody(URLRequest* request);

  // Helper to copy the partial bytes read from the read IOBuffer to an
  // aggregated buffer.
  bool ConsumeBytesRead(URLRequest* request, int num_bytes);

  // Called when the URLRequest has completed (either success or failure).
  void OnUrlRequestCompleted(int net_error);

  // Called when the Job has completed. The job may finish in response to a
  // timeout, an invalid URL, or the URLRequest completing. By the time this
  // method is called, the |response_body_| variable have been assigned.
  void OnJobCompleted(Error error);

  // Calls r->OnJobCompleted() for each RequestCore |r| currently attached
  // to this job, and then clears |requests_|.
  void CompleteAndClearRequests(Error error);

  // Cancels a request with a specified error code and calls
  // OnUrlRequestCompleted().
  void FailRequest(Error error);

  // The requests attached to this job.
  std::vector<scoped_refptr<RequestCore>> requests_;

  // The input parameters for starting a URLRequest.
  std::unique_ptr<RequestParams> request_params_;

  // The URLRequest response information.
  std::vector<uint8_t> response_body_;

  std::unique_ptr<URLRequest> url_request_;
  scoped_refptr<IOBuffer> read_buffer_;

  // Used to timeout the job when the URLRequest takes too long. This timer is
  // also used for notifying a failure to start the URLRequest.
  base::OneShotTimer timer_;

  // Non-owned pointer to the AsyncCertNetFetcherImpl that created this job.
  AsyncCertNetFetcherImpl* parent_;

  DISALLOW_COPY_AND_ASSIGN(Job);
};

void RequestCore::CancelJob() {
  if (!task_runner_->RunsTasksInCurrentSequence()) {
    task_runner_->PostTask(FROM_HERE,
                           base::Bind(&RequestCore::CancelJob, this));
    return;
  }

  if (job_) {
    auto* job = job_;
    job_ = nullptr;
    job->DetachRequest(this);
  }

  SignalImmediateError();
}

void RequestCore::SignalImmediateError() {
  // These data members are normally only written on the network thread, but it
  // is safe to write here from either thread. This is because
  // SignalImmediateError is only to be called before this request is attached
  // to a job. In particular, if called from the caller thread, no work will be
  // done on the network thread for this request, so these variables will only
  // be written and read on the caller thread. If called from the network
  // thread, they will only be written to on the network thread and will not be
  // read on the caller thread until |completion_event_| is signalled (after
  // which it will be not be written on the network thread again).
  DCHECK(!job_);
  error_ = ERR_ABORTED;
  bytes_.clear();
  completion_event_.Signal();
}

Job::Job(std::unique_ptr<RequestParams> request_params,
         AsyncCertNetFetcherImpl* parent)
    : request_params_(std::move(request_params)), parent_(parent) {}

Job::~Job() {
  DCHECK(requests_.empty());
  Stop();
}

void Job::AttachRequest(scoped_refptr<RequestCore> request) {
  request->AttachedToJob(this);
  requests_.push_back(std::move(request));
}

void Job::DetachRequest(RequestCore* request) {
  std::unique_ptr<Job> delete_this;

  auto it = std::find(requests_.begin(), requests_.end(), request);
  DCHECK(it != requests_.end());
  requests_.erase(it);

  // If there are no longer any requests attached to the job then
  // cancel and delete it.
  if (requests_.empty())
    delete_this = parent_->RemoveJob(this);
}

void Job::StartURLRequest(URLRequestContext* context) {
  Error error = CanFetchUrl(request_params_->url);
  if (error != OK) {
    OnJobCompleted(error);
    return;
  }

  // Start the URLRequest.
  read_buffer_ = new IOBuffer(kReadBufferSizeInBytes);
  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("certificate_verifier", R"(
        semantics {
          sender: "Certificate Verifier"
          description:
            "When verifying certificates, the browser may need to fetch "
            "additional URLs that are encoded in the server-provided "
            "certificate chain. This may be part of revocation checking ("
            "Online Certificate Status Protocol, Certificate Revocation List), "
            "or path building (Authority Information Access fetches). Please "
            "refer to the following for more on above protocols: "
            "https://tools.ietf.org/html/rfc6960, "
            "https://tools.ietf.org/html/rfc5280#section-4.2.1.13, and"
            "https://tools.ietf.org/html/rfc5280#section-5.2.7."
          trigger:
            "Verifying a certificate (likely in response to navigating to an "
            "'https://' website)."
          data:
            "In the case of OCSP this may divulge the website being viewed. No "
            "user data in other cases."
          destination: OTHER
        }
        policy {
          cookies_allowed: NO
          setting: "This feature cannot be disabled by settings."
          policy_exception_justification: "Not implemented."
        })");
  url_request_ = context->CreateRequest(request_params_->url, DEFAULT_PRIORITY,
                                        this, traffic_annotation);
  if (request_params_->http_method == HTTP_METHOD_POST)
    url_request_->set_method("POST");
  url_request_->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES |
                             LOAD_DO_NOT_SEND_COOKIES);
  url_request_->Start();

  // Start a timer to limit how long the job runs for.
  if (request_params_->timeout > base::TimeDelta())
    timer_.Start(
        FROM_HERE, request_params_->timeout,
        base::Bind(&Job::FailRequest, base::Unretained(this), ERR_TIMED_OUT));
}

void Job::Cancel() {
  // Stop the timer and clear the URLRequest.
  Stop();
  // Signal attached requests that they've been completed.
  CompleteAndClearRequests(static_cast<Error>(ERR_ABORTED));
}

void Job::OnReceivedRedirect(URLRequest* request,
                             const RedirectInfo& redirect_info,
                             bool* defer_redirect) {
  DCHECK_EQ(url_request_.get(), request);

  // Ensure that the new URL matches the policy.
  Error error = CanFetchUrl(redirect_info.new_url);
  if (error != OK) {
    FailRequest(error);
    return;
  }
}

void Job::OnResponseStarted(URLRequest* request, int net_error) {
  DCHECK_EQ(url_request_.get(), request);
  DCHECK_NE(ERR_IO_PENDING, net_error);

  if (net_error != OK) {
    OnUrlRequestCompleted(net_error);
    return;
  }

  if (request->GetResponseCode() != 200) {
    // TODO(eroman): Use a more specific error code.
    FailRequest(ERR_FAILED);
    return;
  }

  ReadBody(request);
}

void Job::OnReadCompleted(URLRequest* request, int bytes_read) {
  DCHECK_EQ(url_request_.get(), request);
  DCHECK_NE(ERR_IO_PENDING, bytes_read);

  // Keep reading the response body.
  if (ConsumeBytesRead(request, bytes_read))
    ReadBody(request);
}

void Job::Stop() {
  timer_.Stop();
  url_request_.reset();
}

void Job::ReadBody(URLRequest* request) {
  // Read as many bytes as are available synchronously.
  int num_bytes = 0;
  while (num_bytes >= 0) {
    num_bytes = request->Read(read_buffer_.get(), kReadBufferSizeInBytes);
    if (num_bytes == ERR_IO_PENDING)
      return;
    if (!ConsumeBytesRead(request, num_bytes))
      return;
  }

  OnUrlRequestCompleted(num_bytes);
}

bool Job::ConsumeBytesRead(URLRequest* request, int num_bytes) {
  DCHECK_NE(ERR_IO_PENDING, num_bytes);
  if (num_bytes <= 0) {
    // Error while reading, or EOF.
    OnUrlRequestCompleted(num_bytes);
    return false;
  }

  // Enforce maximum size bound.
  if (num_bytes + response_body_.size() > request_params_->max_response_bytes) {
    FailRequest(ERR_FILE_TOO_BIG);
    return false;
  }

  // Append the data to |response_body_|.
  response_body_.reserve(num_bytes);
  response_body_.insert(response_body_.end(), read_buffer_->data(),
                        read_buffer_->data() + num_bytes);
  return true;
}

void Job::OnUrlRequestCompleted(int net_error) {
  DCHECK_NE(ERR_IO_PENDING, net_error);
  Error result = static_cast<Error>(net_error);
  OnJobCompleted(result);
}

void Job::OnJobCompleted(Error error) {
  DCHECK_NE(ERR_IO_PENDING, error);
  // Stop the timer and clear the URLRequest.
  Stop();

  std::unique_ptr<Job> delete_this = parent_->RemoveJob(this);
  CompleteAndClearRequests(error);
}

void Job::CompleteAndClearRequests(Error error) {
  for (const auto& request : requests_) {
    request->OnJobCompleted(this, error, response_body_);
  }

  requests_.clear();
}

void Job::FailRequest(Error error) {
  DCHECK_NE(ERR_IO_PENDING, error);
  int result = url_request_->CancelWithError(error);
  OnUrlRequestCompleted(result);
}

AsyncCertNetFetcherImpl::AsyncCertNetFetcherImpl(URLRequestContext* context)
    : context_(context) {
  // Allow creation to happen from another thread.
  thread_checker_.DetachFromThread();
}

AsyncCertNetFetcherImpl::~AsyncCertNetFetcherImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
  jobs_.clear();
}

bool JobComparator::operator()(const Job* job1, const Job* job2) const {
  return job1->request_params() < job2->request_params();
}

void AsyncCertNetFetcherImpl::Fetch(
    std::unique_ptr<RequestParams> request_params,
    scoped_refptr<RequestCore> request) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // If there is an in-progress job that matches the request parameters use it.
  // Otherwise start a new job.
  Job* job = FindJob(*request_params);
  if (job) {
    job->AttachRequest(std::move(request));
    return;
  }

  job = new Job(std::move(request_params), this);
  jobs_[job] = base::WrapUnique(job);
  // Attach the request before calling StartURLRequest; this ensures that the
  // request will get signalled if StartURLRequest completes the job
  // synchronously.
  job->AttachRequest(std::move(request));
  job->StartURLRequest(context_);
}

void AsyncCertNetFetcherImpl::Shutdown() {
  DCHECK(thread_checker_.CalledOnValidThread());
  for (const auto& job : jobs_) {
    job.first->Cancel();
  }
  jobs_.clear();
}

struct JobToRequestParamsComparator {
  bool operator()(const JobSet::value_type& job,
                  const RequestParams& value) const {
    return job.first->request_params() < value;
  }
};

Job* AsyncCertNetFetcherImpl::FindJob(const RequestParams& params) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // The JobSet is kept in sorted order so items can be found using binary
  // search.
  JobSet::iterator it = std::lower_bound(jobs_.begin(), jobs_.end(), params,
                                         JobToRequestParamsComparator());
  if (it != jobs_.end() && !(params < (*it).first->request_params()))
    return (*it).first;
  return nullptr;
}

std::unique_ptr<Job> AsyncCertNetFetcherImpl::RemoveJob(Job* job) {
  DCHECK(thread_checker_.CalledOnValidThread());
  auto it = jobs_.find(job);
  CHECK(it != jobs_.end());
  std::unique_ptr<Job> owned_job = std::move(it->second);
  jobs_.erase(it);
  return owned_job;
}

class CertNetFetcherRequestImpl : public CertNetFetcher::Request {
 public:
  explicit CertNetFetcherRequestImpl(scoped_refptr<RequestCore> core)
      : core_(std::move(core)) {
    DCHECK(core_);
  }

  void WaitForResult(Error* error, std::vector<uint8_t>* bytes) override {
    // Should only be called a single time.
    DCHECK(core_);
    core_->WaitForResult(error, bytes);
    core_ = nullptr;
  }

  ~CertNetFetcherRequestImpl() override {
    if (core_)
      core_->CancelJob();
  }

 private:
  scoped_refptr<RequestCore> core_;
};

class CertNetFetcherImpl : public CertNetFetcher {
 public:
  explicit CertNetFetcherImpl(URLRequestContext* context)
      : task_runner_(base::ThreadTaskRunnerHandle::Get()), context_(context) {}

  void Shutdown() override {
    DCHECK(task_runner_->RunsTasksInCurrentSequence());
    if (impl_) {
      impl_->Shutdown();
      impl_.reset();
    }
    context_ = nullptr;
  }

  std::unique_ptr<Request> FetchCaIssuers(const GURL& url,
                                          int timeout_milliseconds,
                                          int max_response_bytes) override {
    std::unique_ptr<RequestParams> request_params(new RequestParams);

    request_params->url = url;
    request_params->http_method = HTTP_METHOD_GET;
    request_params->timeout = GetTimeout(timeout_milliseconds);
    request_params->max_response_bytes =
        GetMaxResponseBytes(max_response_bytes, kMaxResponseSizeInBytesForAia);

    return DoFetch(std::move(request_params));
  }

  std::unique_ptr<Request> FetchCrl(const GURL& url,
                                    int timeout_milliseconds,
                                    int max_response_bytes) override {
    std::unique_ptr<RequestParams> request_params(new RequestParams);

    request_params->url = url;
    request_params->http_method = HTTP_METHOD_GET;
    request_params->timeout = GetTimeout(timeout_milliseconds);
    request_params->max_response_bytes =
        GetMaxResponseBytes(max_response_bytes, kMaxResponseSizeInBytesForCrl);

    return DoFetch(std::move(request_params));
  }

  WARN_UNUSED_RESULT std::unique_ptr<Request> FetchOcsp(
      const GURL& url,
      int timeout_milliseconds,
      int max_response_bytes) override {
    std::unique_ptr<RequestParams> request_params(new RequestParams);

    request_params->url = url;
    request_params->http_method = HTTP_METHOD_GET;
    request_params->timeout = GetTimeout(timeout_milliseconds);
    request_params->max_response_bytes =
        GetMaxResponseBytes(max_response_bytes, kMaxResponseSizeInBytesForAia);

    return DoFetch(std::move(request_params));
  }

 private:
  ~CertNetFetcherImpl() override {
    // The fetcher must be shutdown (at which point |context_| will be set to
    // null) before destruction.
    DCHECK(!context_);
  }

  void DoFetchOnNetworkSequence(std::unique_ptr<RequestParams> request_params,
                                scoped_refptr<RequestCore> request) {
    DCHECK(task_runner_->RunsTasksInCurrentSequence());

    if (!context_) {
      // The fetcher might have been shutdown between when this task was posted
      // and when it is running. In this case, signal the request and do not
      // start a network request.
      request->SignalImmediateError();
      return;
    }

    if (!impl_) {
      impl_.reset(new AsyncCertNetFetcherImpl(context_));
    }

    impl_->Fetch(std::move(request_params), request);
  }

  std::unique_ptr<Request> DoFetch(
      std::unique_ptr<RequestParams> request_params) {
    scoped_refptr<RequestCore> request_core = new RequestCore(task_runner_);

    // If the fetcher has already been shutdown, DoFetchOnNetworkSequence will
    // signal the request with an error. However, if the fetcher shuts down
    // before DoFetchOnNetworkSequence runs and PostTask still returns true,
    // then the request will hang (that is, WaitForResult will not return).
    if (!task_runner_->PostTask(
            FROM_HERE,
            base::Bind(&CertNetFetcherImpl::DoFetchOnNetworkSequence, this,
                       base::Passed(&request_params), request_core))) {
      request_core->SignalImmediateError();
    }

    return std::make_unique<CertNetFetcherRequestImpl>(std::move(request_core));
  }

 private:
  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  // Not owned. |context_| must stay valid until Shutdown() is called.
  URLRequestContext* context_ = nullptr;
  std::unique_ptr<AsyncCertNetFetcherImpl> impl_;
};

}  // namespace

scoped_refptr<CertNetFetcher> CreateCertNetFetcher(URLRequestContext* context) {
  return base::MakeRefCounted<CertNetFetcherImpl>(context);
}

}  // namespace net
