chromium/services/network/public/cpp/simple_url_loader.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "services/network/public/cpp/simple_url_loader.h"

#include <stdint.h>

#include <algorithm>
#include <string_view>
#include <utility>

#include "base/check_op.h"
#include "base/containers/span.h"
#include "base/debug/alias.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/interned_args_helper.h"
#include "base/trace_event/typed_macros.h"
#include "base/types/optional_ref.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_request_headers.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/data_element.h"
#include "services/network/public/cpp/record_ontransfersizeupdate_utils.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
#include "services/network/public/mojom/data_pipe_getter.mojom.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"

namespace network {

constexpr size_t SimpleURLLoader::kMaxBoundedStringDownloadSize;
constexpr size_t SimpleURLLoader::kMaxUploadStringSizeToCopy;

BASE_FEATURE();

namespace {

constexpr int64_t kReceivedBodySizeUnknown =;

// Used by tests to override the tick clock for the timeout timer.
const base::TickClock* timeout_tick_clock_ =;

// A temporary util adapter to wrap the download callback with the response
// body, and to hop the string content from a unique_ptr<string> into a
// optional<string>.
void GetFromUniquePtrToOptional(
    SimpleURLLoader::BodyAsStringCallback body_as_string_callback,
    std::unique_ptr<std::string> response_body) {}

// This file contains SimpleURLLoaderImpl, several BodyHandler implementations,
// BodyReader, and StringUploadDataPipeGetter.
//
// SimpleURLLoaderImpl implements URLLoaderClient and drives the URLLoader.
//
// Each SimpleURLLoaderImpl creates a BodyHandler when the request is started.
// The BodyHandler drives the body pipe, handles body data as needed (writes it
// to a string, file, etc), and handles passing that data to the consumer's
// callback.
//
// BodyReader is a utility class that BodyHandler implementations use to drive
// the BodyPipe. This isn't handled by the SimpleURLLoader as some BodyHandlers
// consume data off thread, so having it as a separate class allows the data
// pipe to be used off thread, reducing use of the main thread.
//
// StringUploadDataPipeGetter is a class to stream a string upload body to the
// network service, rather than to copy it all at once.

class StringUploadDataPipeGetter : public mojom::DataPipeGetter {};

class BodyHandler;

class SimpleURLLoaderImpl : public SimpleURLLoader,
                            public mojom::URLLoaderClient {};

// Utility class to drive the pipe reading a response body. Can be created on
// one thread and then used to read data on another. A BodyReader may only be
// used once. If a request is retried, a new one must be created.
class BodyReader {};

// Class to drive the pipe for reading the body, handle the results of the body
// read as appropriate, and invoke the consumer's callback to notify it of
// request completion. Implementations typically use a BodyReader to to manage
// reads from the body data pipe.
class BodyHandler {};

// BodyHandler implementation for consuming the response as a string.
class SaveToStringBodyHandler : public BodyHandler,
                                public BodyReader::Delegate {};

// BodyHandler that discards the response body.
class HeadersOnlyBodyHandler : public BodyHandler, public BodyReader::Delegate {};

// BodyHandler implementation for saving the response to a file
class SaveToFileBodyHandler : public BodyHandler {};

// Class to handle streaming data to the consumer as it arrives
class DownloadAsStreamBodyHandler : public BodyHandler,
                                    public BodyReader::Delegate {};

SimpleURLLoaderImpl::SimpleURLLoaderImpl(
    std::unique_ptr<ResourceRequest> resource_request,
    const net::NetworkTrafficAnnotationTag& annotation_tag,
    const base::Location& created_from)
    :{}

SimpleURLLoaderImpl::~SimpleURLLoaderImpl() {}

void SimpleURLLoaderImpl::DownloadToString(
    mojom::URLLoaderFactory* url_loader_factory,
    BodyAsStringCallbackDeprecated body_as_string_callback,
    size_t max_body_size) {}

void SimpleURLLoaderImpl::DownloadToString(
    mojom::URLLoaderFactory* url_loader_factory,
    BodyAsStringCallback body_as_string_callback,
    size_t max_body_size) {}

void SimpleURLLoaderImpl::DownloadToStringOfUnboundedSizeUntilCrashAndDie(
    mojom::URLLoaderFactory* url_loader_factory,
    BodyAsStringCallbackDeprecated body_as_string_callback) {}

void SimpleURLLoaderImpl::DownloadToStringOfUnboundedSizeUntilCrashAndDie(
    mojom::URLLoaderFactory* url_loader_factory,
    BodyAsStringCallback body_as_string_callback) {}

void SimpleURLLoaderImpl::DownloadHeadersOnly(
    mojom::URLLoaderFactory* url_loader_factory,
    HeadersOnlyCallback headers_only_callback) {}

void SimpleURLLoaderImpl::DownloadToFile(
    mojom::URLLoaderFactory* url_loader_factory,
    DownloadToFileCompleteCallback download_to_file_complete_callback,
    const base::FilePath& file_path,
    int64_t max_body_size) {}

void SimpleURLLoaderImpl::DownloadToTempFile(
    mojom::URLLoaderFactory* url_loader_factory,
    DownloadToFileCompleteCallback download_to_file_complete_callback,
    int64_t max_body_size) {}

void SimpleURLLoaderImpl::DownloadAsStream(
    mojom::URLLoaderFactory* url_loader_factory,
    SimpleURLLoaderStreamConsumer* stream_consumer) {}

void SimpleURLLoaderImpl::SetOnRedirectCallback(
    const OnRedirectCallback& on_redirect_callback) {}

void SimpleURLLoaderImpl::SetOnResponseStartedCallback(
    OnResponseStartedCallback on_response_started_callback) {}

void SimpleURLLoaderImpl::SetOnUploadProgressCallback(
    UploadProgressCallback on_upload_progress_callback) {}

void SimpleURLLoaderImpl::SetOnDownloadProgressCallback(
    DownloadProgressCallback on_download_progress_callback) {}

void SimpleURLLoaderImpl::SetAllowPartialResults(bool allow_partial_results) {}

void SimpleURLLoaderImpl::SetAllowHttpErrorResults(
    bool allow_http_error_results) {}

void SimpleURLLoaderImpl::AttachStringForUploadInternal(
    std::string_view upload_data,
    base::optional_ref<std::string_view> upload_content_type) {}

void SimpleURLLoaderImpl::AttachStringForUploadInternal(
    std::string&& upload_data,
    base::optional_ref<std::string_view> upload_content_type) {}
void SimpleURLLoaderImpl::AttachStringForUpload(
    std::string_view upload_data,
    std::string_view upload_content_type) {}

void SimpleURLLoaderImpl::AttachStringForUpload(std::string_view upload_data) {}

void SimpleURLLoaderImpl::AttachStringForUpload(
    const char* upload_data,
    std::string_view upload_content_type) {}

void SimpleURLLoaderImpl::AttachStringForUpload(const char* upload_data) {}

void SimpleURLLoaderImpl::AttachStringForUpload(
    std::string&& upload_data,
    std::string_view upload_content_type) {}

void SimpleURLLoaderImpl::AttachStringForUpload(std::string&& upload_data) {}

void SimpleURLLoaderImpl::AttachFileForUpload(
    const base::FilePath& upload_file_path,
    const std::string* const upload_content_type,
    uint64_t offset,
    uint64_t length) {}

void SimpleURLLoaderImpl::AttachFileForUpload(
    const base::FilePath& upload_file_path,
    const std::string& upload_content_type,
    uint64_t offset,
    uint64_t length) {}

void SimpleURLLoaderImpl::AttachFileForUpload(
    const base::FilePath& upload_file_path,
    uint64_t offset,
    uint64_t length) {}

void SimpleURLLoaderImpl::SetRetryOptions(int max_retries, int retry_mode) {}

void SimpleURLLoaderImpl::SetURLLoaderFactoryOptions(uint32_t options) {}

void SimpleURLLoaderImpl::SetRequestID(int32_t request_id) {}

void SimpleURLLoaderImpl::SetTimeoutDuration(base::TimeDelta timeout_duration) {}

int SimpleURLLoaderImpl::NetError() const {}

const GURL& SimpleURLLoaderImpl::GetFinalURL() const {}

bool SimpleURLLoaderImpl::LoadedFromCache() const {}

int64_t SimpleURLLoaderImpl::GetContentSize() const {}

int SimpleURLLoaderImpl::GetNumRetries() const {}

const mojom::URLResponseHead* SimpleURLLoaderImpl::ResponseInfo() const {}

mojom::URLResponseHeadPtr SimpleURLLoaderImpl::TakeResponseInfo() {}

const std::optional<URLLoaderCompletionStatus>&
SimpleURLLoaderImpl::CompletionStatus() const {}

void SimpleURLLoaderImpl::OnBodyHandlerDone(net::Error error,
                                            int64_t received_body_size) {}

void SimpleURLLoaderImpl::OnBodyHandlerProgress(int64_t progress) {}

void SimpleURLLoaderImpl::DispatchDownloadProgress(int64_t downloaded) {}

void SimpleURLLoaderImpl::FinishWithResult(int net_error) {}

void SimpleURLLoaderImpl::Start(mojom::URLLoaderFactory* url_loader_factory) {}

void SimpleURLLoaderImpl::OnReadyToStart() {}

void SimpleURLLoaderImpl::StartRequest(
    mojom::URLLoaderFactory* url_loader_factory) {}

void SimpleURLLoaderImpl::Retry() {}

void SimpleURLLoaderImpl::OnReceiveEarlyHints(
    network::mojom::EarlyHintsPtr early_hints) {}

void SimpleURLLoaderImpl::OnReceiveResponse(
    mojom::URLResponseHeadPtr response_head,
    mojo::ScopedDataPipeConsumerHandle body,
    std::optional<mojo_base::BigBuffer> cached_metadata) {}

void SimpleURLLoaderImpl::OnReceiveRedirect(
    const net::RedirectInfo& redirect_info,
    mojom::URLResponseHeadPtr response_head) {}

void SimpleURLLoaderImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) {}

void SimpleURLLoaderImpl::OnUploadProgress(
    int64_t current_position,
    int64_t total_size,
    OnUploadProgressCallback ack_callback) {}

void SimpleURLLoaderImpl::OnComplete(const URLLoaderCompletionStatus& status) {}

void SimpleURLLoaderImpl::OnMojoDisconnect() {}

void SimpleURLLoaderImpl::MaybeComplete() {}

}  // namespace

std::unique_ptr<SimpleURLLoader> SimpleURLLoader::Create(
    std::unique_ptr<ResourceRequest> resource_request,
    const net::NetworkTrafficAnnotationTag& annotation_tag,
    base::Location created_from) {}

void SimpleURLLoader::SetTimeoutTickClockForTest(
    const base::TickClock* timeout_tick_clock) {}

SimpleURLLoader::~SimpleURLLoader() {}

SimpleURLLoader::SimpleURLLoader() {}

}  // namespace network