chromium/net/cert_net/cert_net_fetcher_url_request.cc

// Copyright 2015 The Chromium Authors
// 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 CertNetFetcherURLRequest. 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 CertNetFetcherURLRequest
// returns a CertNetFetcher::Request (CertNetFetcherRequestImpl) that the
// caller can use to cancel the fetch, or wait for it to complete
// (blocking).
//
// The CertNetFetcherURLRequest 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
// ---------------
//
// CertNetFetcherURLRequest (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
// ---------------
//
// AsyncCertNetFetcherURLRequest
//   * Asynchronous 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_url_request.h"

#include <memory>
#include <tuple>
#include <utility>

#include "base/check_op.h"
#include "base/containers/extend.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_math.h"
#include "base/ranges/algorithm.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/io_buffer.h"
#include "net/base/isolation_info.h"
#include "net/base/load_flags.h"
#include "net/cert/cert_net_fetcher.h"
#include "net/cookies/site_for_cookies.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request_context.h"
#include "url/origin.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 =;

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

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

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

class Job;

struct JobToRequestParamsComparator;

struct JobComparator {};

// Would be a set<unique_ptr> but extraction of owned objects from a set of
// owned types doesn't come until C++17.
JobSet;

}  // namespace

// AsyncCertNetFetcherURLRequest manages URLRequests in an async fashion on the
// URLRequestContexts's task runner thread.
//
//  * Schedules
//  * De-duplicates requests
//  * Handles timeouts
class CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest {};

namespace {

// 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) {}

base::TimeDelta GetTimeout(int timeout_milliseconds) {}

size_t GetMaxResponseBytes(int max_response_bytes,
                           size_t default_max_response_bytes) {}

enum HttpMethod {};

}  // namespace

// RequestCore tracks an outstanding call to Fetch(). It is
// reference-counted for ease of sharing between threads.
class CertNetFetcherURLRequest::RequestCore
    : public base::RefCountedThreadSafe<RequestCore> {};

struct CertNetFetcherURLRequest::RequestParams {};

CertNetFetcherURLRequest::RequestParams::RequestParams() = default;

bool CertNetFetcherURLRequest::RequestParams::operator<(
    const RequestParams& other) const {}

namespace {

// Job tracks an outstanding URLRequest as well as all of the pending requests
// for it.
class Job : public URLRequest::Delegate {};

}  // namespace

void CertNetFetcherURLRequest::RequestCore::CancelJob() {}

void CertNetFetcherURLRequest::RequestCore::SignalImmediateError() {}

namespace {

Job::Job(
    std::unique_ptr<CertNetFetcherURLRequest::RequestParams> request_params,
    CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest* parent)
    :{}

Job::~Job() {}

void Job::AttachRequest(
    scoped_refptr<CertNetFetcherURLRequest::RequestCore> request) {}

void Job::DetachRequest(CertNetFetcherURLRequest::RequestCore* request) {}

void Job::StartURLRequest(URLRequestContext* context) {}

void Job::Cancel() {}

void Job::OnReceivedRedirect(URLRequest* request,
                             const RedirectInfo& redirect_info,
                             bool* defer_redirect) {}

void Job::OnResponseStarted(URLRequest* request, int net_error) {}

void Job::OnReadCompleted(URLRequest* request, int bytes_read) {}

void Job::Stop() {}

void Job::ReadBody(URLRequest* request) {}

bool Job::ConsumeBytesRead(URLRequest* request, int num_bytes) {}

void Job::OnUrlRequestCompleted(int net_error) {}

void Job::OnJobCompleted(Error error) {}

void Job::CompleteAndClearRequests(Error error) {}

void Job::FailRequest(Error error) {}

}  // namespace

CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest::
    AsyncCertNetFetcherURLRequest(URLRequestContext* context)
    :{}

CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest::
    ~AsyncCertNetFetcherURLRequest() {}

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

void CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest::Fetch(
    std::unique_ptr<RequestParams> request_params,
    scoped_refptr<RequestCore> request) {}

void CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest::Shutdown() {}

namespace {

struct JobToRequestParamsComparator {};

}  // namespace

Job* CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest::FindJob(
    const RequestParams& params) {}

std::unique_ptr<Job>
CertNetFetcherURLRequest::AsyncCertNetFetcherURLRequest::RemoveJob(Job* job) {}

namespace {

class CertNetFetcherRequestImpl : public CertNetFetcher::Request {};

}  // namespace

CertNetFetcherURLRequest::CertNetFetcherURLRequest()
    :{}

CertNetFetcherURLRequest::~CertNetFetcherURLRequest() {}

void CertNetFetcherURLRequest::SetURLRequestContext(
    URLRequestContext* context) {}

// static
base::TimeDelta CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() {}

void CertNetFetcherURLRequest::Shutdown() {}

std::unique_ptr<CertNetFetcher::Request>
CertNetFetcherURLRequest::FetchCaIssuers(const GURL& url,
                                         int timeout_milliseconds,
                                         int max_response_bytes) {}

std::unique_ptr<CertNetFetcher::Request> CertNetFetcherURLRequest::FetchCrl(
    const GURL& url,
    int timeout_milliseconds,
    int max_response_bytes) {}

std::unique_ptr<CertNetFetcher::Request> CertNetFetcherURLRequest::FetchOcsp(
    const GURL& url,
    int timeout_milliseconds,
    int max_response_bytes) {}

void CertNetFetcherURLRequest::DoFetchOnNetworkSequence(
    std::unique_ptr<RequestParams> request_params,
    scoped_refptr<RequestCore> request) {}

std::unique_ptr<CertNetFetcherURLRequest::Request>
CertNetFetcherURLRequest::DoFetch(
    std::unique_ptr<RequestParams> request_params) {}

}  // namespace net