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

#include "components/cronet/cronet_url_request.h"

#include <limits>
#include <utility>

#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "components/cronet/cronet_context.h"
#include "net/base/idempotency.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/load_states.h"
#include "net/base/net_error_details.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/base/upload_data_stream.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/x509_certificate.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "net/ssl/ssl_info.h"
#include "net/ssl/ssl_private_key.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_types.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/referrer_policy.h"
#include "net/url_request/url_request_context.h"

namespace cronet {

namespace {

// Returns the string representation of the HostPortPair of the proxy server
// that was used to fetch the response.
std::string GetProxy(const net::HttpResponseInfo& info) {
  if (!info.proxy_chain.IsValid() || info.proxy_chain.is_direct()) {
    return net::HostPortPair().ToString();
  }
  CHECK(info.proxy_chain.is_single_proxy());
  return info.proxy_chain.First().host_port_pair().ToString();
}

int CalculateLoadFlags(int load_flags,
                       bool disable_cache,
                       bool disable_connection_migration) {
  if (disable_cache)
    load_flags |= net::LOAD_DISABLE_CACHE;
  if (disable_connection_migration)
    load_flags |= net::LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
  return load_flags;
}

}  // namespace

CronetURLRequest::CronetURLRequest(
    CronetContext* context,
    std::unique_ptr<Callback> callback,
    const GURL& url,
    net::RequestPriority priority,
    bool disable_cache,
    bool disable_connection_migration,
    bool traffic_stats_tag_set,
    int32_t traffic_stats_tag,
    bool traffic_stats_uid_set,
    int32_t traffic_stats_uid,
    net::Idempotency idempotency,
    scoped_refptr<net::SharedDictionary> shared_dictionary,
    net::handles::NetworkHandle network)
    : context_(context),
      network_tasks_(std::move(callback),
                     url,
                     priority,
                     CalculateLoadFlags(context->default_load_flags(),
                                        disable_cache,
                                        disable_connection_migration),
                     traffic_stats_tag_set,
                     traffic_stats_tag,
                     traffic_stats_uid_set,
                     traffic_stats_uid,
                     idempotency,
                     shared_dictionary,
                     network),
      initial_method_("GET"),
      initial_request_headers_(std::make_unique<net::HttpRequestHeaders>()) {
  DCHECK(!context_->IsOnNetworkThread());
}

CronetURLRequest::~CronetURLRequest() {
  DCHECK(context_->IsOnNetworkThread());
}

bool CronetURLRequest::SetHttpMethod(const std::string& method) {
  DCHECK(!context_->IsOnNetworkThread());
  // Http method is a token, just as header name.
  if (!net::HttpUtil::IsValidHeaderName(method))
    return false;
  initial_method_ = method;
  return true;
}

bool CronetURLRequest::AddRequestHeader(const std::string& name,
                                        const std::string& value) {
  DCHECK(!context_->IsOnNetworkThread());
  DCHECK(initial_request_headers_);
  if (!net::HttpUtil::IsValidHeaderName(name) ||
      !net::HttpUtil::IsValidHeaderValue(value)) {
    return false;
  }
  initial_request_headers_->SetHeader(name, value);
  return true;
}

void CronetURLRequest::SetUpload(
    std::unique_ptr<net::UploadDataStream> upload) {
  DCHECK(!context_->IsOnNetworkThread());
  DCHECK(!upload_);
  upload_ = std::move(upload);
}

void CronetURLRequest::Start() {
  DCHECK(!context_->IsOnNetworkThread());
  context_->PostTaskToNetworkThread(
      FROM_HERE,
      base::BindOnce(&CronetURLRequest::NetworkTasks::Start,
                     base::Unretained(&network_tasks_),
                     base::Unretained(context_), initial_method_,
                     std::move(initial_request_headers_), std::move(upload_)));
}

void CronetURLRequest::GetStatus(OnStatusCallback callback) const {
  context_->PostTaskToNetworkThread(
      FROM_HERE,
      base::BindOnce(&CronetURLRequest::NetworkTasks::GetStatus,
                     base::Unretained(&network_tasks_), std::move(callback)));
}

void CronetURLRequest::FollowDeferredRedirect() {
  context_->PostTaskToNetworkThread(
      FROM_HERE,
      base::BindOnce(&CronetURLRequest::NetworkTasks::FollowDeferredRedirect,
                     base::Unretained(&network_tasks_)));
}

bool CronetURLRequest::ReadData(net::IOBuffer* raw_read_buffer, int max_size) {
  // TODO(crbug.com/40847077): Change to DCHECK() or remove after bug
  // is fixed.
  CHECK(max_size == 0 || (raw_read_buffer && raw_read_buffer->data()));

  scoped_refptr<net::IOBuffer> read_buffer(raw_read_buffer);
  context_->PostTaskToNetworkThread(
      FROM_HERE,
      base::BindOnce(&CronetURLRequest::NetworkTasks::ReadData,
                     base::Unretained(&network_tasks_), read_buffer, max_size));
  return true;
}

void CronetURLRequest::Destroy(bool send_on_canceled) {
  // Destroy could be called from any thread, including network thread (if
  // posting task to executor throws an exception), but is posted, so |this|
  // is valid until calling task is complete. Destroy() must be called from
  // within a synchronized block that guarantees no future posts to the
  // network thread with the request pointer.
  context_->PostTaskToNetworkThread(
      FROM_HERE, base::BindOnce(&CronetURLRequest::NetworkTasks::Destroy,
                                base::Unretained(&network_tasks_),
                                base::Unretained(this), send_on_canceled));
}

void CronetURLRequest::MaybeReportMetricsAndRunCallback(
    base::OnceClosure callback) {
  context_->PostTaskToNetworkThread(
      FROM_HERE,
      base::BindOnce(
          &CronetURLRequest::NetworkTasks::MaybeReportMetricsAndRunCallback,
          base::Unretained(&network_tasks_), std::move(callback)));
}

CronetURLRequest::NetworkTasks::NetworkTasks(
    std::unique_ptr<Callback> callback,
    const GURL& url,
    net::RequestPriority priority,
    int load_flags,
    bool traffic_stats_tag_set,
    int32_t traffic_stats_tag,
    bool traffic_stats_uid_set,
    int32_t traffic_stats_uid,
    net::Idempotency idempotency,
    scoped_refptr<net::SharedDictionary> shared_dictionary,
    net::handles::NetworkHandle network)
    : callback_(std::move(callback)),
      initial_url_(url),
      initial_priority_(priority),
      initial_load_flags_(load_flags),
      received_byte_count_from_redirects_(0l),
      error_reported_(false),
      metrics_reported_(false),
      traffic_stats_tag_set_(traffic_stats_tag_set),
      traffic_stats_tag_(traffic_stats_tag),
      traffic_stats_uid_set_(traffic_stats_uid_set),
      traffic_stats_uid_(traffic_stats_uid),
      idempotency_(idempotency),
      shared_dictionary_(shared_dictionary),
      network_(network) {
  DETACH_FROM_THREAD(network_thread_checker_);
}

CronetURLRequest::NetworkTasks::~NetworkTasks() {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
}

void CronetURLRequest::NetworkTasks::OnReceivedRedirect(
    net::URLRequest* request,
    const net::RedirectInfo& redirect_info,
    bool* defer_redirect) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  received_byte_count_from_redirects_ += request->GetTotalReceivedBytes();
  callback_->OnReceivedRedirect(
      redirect_info.new_url.spec(), redirect_info.status_code,
      request->response_headers()->GetStatusText(), request->response_headers(),
      request->response_info().was_cached,
      request->response_info().alpn_negotiated_protocol,
      GetProxy(request->response_info()), received_byte_count_from_redirects_);
  *defer_redirect = true;
}

void CronetURLRequest::NetworkTasks::OnCertificateRequested(
    net::URLRequest* request,
    net::SSLCertRequestInfo* cert_request_info) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  // Cronet does not support client certificates.
  request->ContinueWithCertificate(nullptr, nullptr);
}

void CronetURLRequest::NetworkTasks::OnSSLCertificateError(
    net::URLRequest* request,
    int net_error,
    const net::SSLInfo& ssl_info,
    bool fatal) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  ReportError(request, net_error);
  request->Cancel();
}

void CronetURLRequest::NetworkTasks::OnResponseStarted(net::URLRequest* request,
                                                       int net_error) {
  DCHECK_NE(net::ERR_IO_PENDING, net_error);
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);

  if (net_error != net::OK) {
    ReportError(request, net_error);
    return;
  }
  callback_->OnResponseStarted(
      request->GetResponseCode(), request->response_headers()->GetStatusText(),
      request->response_headers(), request->response_info().was_cached,
      request->response_info().alpn_negotiated_protocol,
      GetProxy(request->response_info()),
      received_byte_count_from_redirects_ + request->GetTotalReceivedBytes());
}

void CronetURLRequest::NetworkTasks::OnReadCompleted(net::URLRequest* request,
                                                     int bytes_read) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);

  if (bytes_read < 0) {
    ReportError(request, bytes_read);
    return;
  }

  if (bytes_read == 0) {
    DCHECK(!error_reported_);
    MaybeReportMetrics();
    callback_->OnSucceeded(received_byte_count_from_redirects_ +
                           request->GetTotalReceivedBytes());
  } else {
    callback_->OnReadCompleted(
        read_buffer_, bytes_read,
        received_byte_count_from_redirects_ + request->GetTotalReceivedBytes());
  }
  // Free the read buffer.
  read_buffer_ = nullptr;
}

void CronetURLRequest::NetworkTasks::Start(
    CronetContext* context,
    const std::string& method,
    std::unique_ptr<net::HttpRequestHeaders> request_headers,
    std::unique_ptr<net::UploadDataStream> upload) {
  DCHECK(context->IsOnNetworkThread());
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  VLOG(1) << "Starting chromium request: "
          << initial_url_.possibly_invalid_spec().c_str()
          << " priority: " << RequestPriorityToString(initial_priority_);
  url_request_ = context->GetURLRequestContext(network_)->CreateRequest(
      initial_url_, net::DEFAULT_PRIORITY, this, MISSING_TRAFFIC_ANNOTATION);
  url_request_->SetLoadFlags(initial_load_flags_);
  url_request_->set_method(method);
  url_request_->SetExtraRequestHeaders(*request_headers);
  url_request_->SetPriority(initial_priority_);
  url_request_->SetIdempotency(idempotency_);
  url_request_->SetReferrer(
      request_headers->GetHeader(net::HttpRequestHeaders::kReferer)
          .value_or(url_request_->referrer()));
  url_request_->set_referrer_policy(net::ReferrerPolicy::NEVER_CLEAR);
  if (shared_dictionary_) {
    if (!context->GetURLRequestContext(network_)->enable_brotli()) {
      // Ideally this would be impossible. Unfortunately, due to Cronet's API
      // structure, it is impossible to know within UrlRequest.Builder's API
      // code whether the associated CronetEngine has Brotli enabled or not.
      // So, since we cannot throw there, the best we can do is log error here.
      LOG(WARNING) << "Compression dictionary will be ignored: the "
                      "CronetEngine being used disables Brotli, which is a "
                      "requirement for compression dictionaries.";
    } else {
      url_request_->SetSharedDictionaryGetter(base::BindRepeating(
          [](scoped_refptr<net::SharedDictionary> dict,
             const std::optional<net::SharedDictionaryIsolationKey>&
                 isolation_key,
             const GURL& request_url) {
            // Cronet currently does not implement the retrieval of compression
            // dictionaries, it instead relies on the embedder to provide them
            // for a specific URLRequest. As such, Cronet doesn't handle
            // matching dictionaries with isolation keys & URLs, but relies on
            // the embedder to do the right thing.
            return dict;
          },
          shared_dictionary_));
      url_request_->SetIsSharedDictionaryReadAllowedCallback(
          base::BindRepeating([] { return true; }));
    }
  }
  if (upload)
    url_request_->set_upload(std::move(upload));
  if (traffic_stats_tag_set_ || traffic_stats_uid_set_) {
#if BUILDFLAG(IS_ANDROID)
    url_request_->set_socket_tag(net::SocketTag(
        traffic_stats_uid_set_ ? traffic_stats_uid_ : net::SocketTag::UNSET_UID,
        traffic_stats_tag_set_ ? traffic_stats_tag_
                               : net::SocketTag::UNSET_TAG));
#else
    NOTREACHED();
#endif
  }
  url_request_->Start();
}

void CronetURLRequest::NetworkTasks::GetStatus(
    OnStatusCallback callback) const {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  net::LoadState status = net::LOAD_STATE_IDLE;
  // |url_request_| is initialized in StartOnNetworkThread, and it is
  // never nulled. If it is null, it must be that StartOnNetworkThread
  // has not been called, pretend that we are in LOAD_STATE_IDLE.
  // See https://crbug.com/606872.
  if (url_request_)
    status = url_request_->GetLoadState().state;
  std::move(callback).Run(status);
}

void CronetURLRequest::NetworkTasks::FollowDeferredRedirect() {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  url_request_->FollowDeferredRedirect(
      std::nullopt /* removed_request_headers */,
      std::nullopt /* modified_request_headers */);
}

void CronetURLRequest::NetworkTasks::ReadData(
    scoped_refptr<net::IOBuffer> read_buffer,
    int buffer_size) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  DCHECK(read_buffer);
  DCHECK(!read_buffer_);

  read_buffer_ = read_buffer;

  int result = url_request_->Read(read_buffer_.get(), buffer_size);
  // If IO is pending, wait for the URLRequest to call OnReadCompleted.
  if (result == net::ERR_IO_PENDING)
    return;

  OnReadCompleted(url_request_.get(), result);
}

void CronetURLRequest::NetworkTasks::Destroy(CronetURLRequest* request,
                                             bool send_on_canceled) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  MaybeReportMetrics();
  if (send_on_canceled)
    callback_->OnCanceled();
  callback_->OnDestroyed();
  // Check if the URLRequestContext associated to `network_` has become eligible
  // for destruction. To simplify MaybeDestroyURLRequestContext's logic: destroy
  // the underlying URLRequest in advance, so that it has already deregistered
  // from its URLRequestContext by the time MaybeDestroyURLRequestContext is
  // called.
  url_request_.reset();
  request->context_->MaybeDestroyURLRequestContext(network_);
  // Deleting owner request also deletes `this`.
  delete request;
}

void CronetURLRequest::NetworkTasks::ReportError(net::URLRequest* request,
                                                 int net_error) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  DCHECK_NE(net::ERR_IO_PENDING, net_error);
  DCHECK_LT(net_error, 0);
  DCHECK_EQ(request, url_request_.get());
  // Error may have already been reported.
  if (error_reported_)
    return;
  error_reported_ = true;
  net::NetErrorDetails net_error_details;
  url_request_->PopulateNetErrorDetails(&net_error_details);
  VLOG(1) << "Error " << net::ErrorToString(net_error)
          << " on chromium request: " << initial_url_.possibly_invalid_spec();
  MaybeReportMetrics();
  callback_->OnError(
      net_error, net_error_details.quic_connection_error,
      net_error_details.source, net::ErrorToString(net_error),
      received_byte_count_from_redirects_ + request->GetTotalReceivedBytes());
}

void CronetURLRequest::NetworkTasks::MaybeReportMetrics() {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  // If there was an exception while starting the CronetUrlRequest, there won't
  // be a native URLRequest. In this case, the caller gets the exception
  // immediately, and the onFailed callback isn't called, so don't report
  // metrics either.
  if (metrics_reported_ || !url_request_) {
    return;
  }
  metrics_reported_ = true;
  net::LoadTimingInfo metrics;
  url_request_->GetLoadTimingInfo(&metrics);
  net::NetErrorDetails net_error_details;
  url_request_->PopulateNetErrorDetails(&net_error_details);
  callback_->OnMetricsCollected(
      metrics.request_start_time, metrics.request_start,
      metrics.connect_timing.domain_lookup_start,
      metrics.connect_timing.domain_lookup_end,
      metrics.connect_timing.connect_start, metrics.connect_timing.connect_end,
      metrics.connect_timing.ssl_start, metrics.connect_timing.ssl_end,
      metrics.send_start, metrics.send_end, metrics.push_start,
      metrics.push_end, metrics.receive_headers_end, base::TimeTicks::Now(),
      metrics.socket_reused, url_request_->GetTotalSentBytes(),
      received_byte_count_from_redirects_ +
          url_request_->GetTotalReceivedBytes(),
      net_error_details.quic_connection_migration_attempted,
      net_error_details.quic_connection_migration_successful);
}

void CronetURLRequest::NetworkTasks::MaybeReportMetricsAndRunCallback(
    base::OnceClosure callback) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  MaybeReportMetrics();
  std::move(callback).Run();
}

}  // namespace cronet
