chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc

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

#include "extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h"

#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/check_op.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "base/types/optional_util.h"
#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/url_utils.h"
#include "extensions/browser/api/web_request/extension_web_request_event_router.h"
#include "extensions/browser/api/web_request/permission_helper.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
#include "net/base/auth.h"
#include "net/base/ip_endpoint.h"
#include "net/base/isolation_info.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/redirect_util.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/record_ontransfersizeupdate_utils.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/cpp/url_loader_factory_builder.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/parsed_headers.mojom-forward.h"
#include "third_party/blink/public/common/loader/throttling_url_loader.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_constants.h"

namespace extensions {
namespace {

// TODO(crbug.com/40768738): Consider removing traces when the cause of the
// issue is identified.
constexpr char kWebRequestProxyingURLLoaderFactoryScope[] =;

// This shutdown notifier makes sure the proxy is destroyed if an incognito
// browser context is destroyed. This is needed because WebRequestAPI only
// clears the proxies when the original browser context is destroyed.
class ShutdownNotifierFactory
    : public BrowserContextKeyedServiceShutdownNotifierFactory {};

// Creates simulated net::RedirectInfo when an extension redirects a request,
// behaving like a redirect response was actually returned by the remote server.
net::RedirectInfo CreateRedirectInfo(
    const network::ResourceRequest& original_request,
    const GURL& new_url,
    int response_code,
    const std::optional<std::string>& referrer_policy_header) {}

}  // namespace

WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
    FollowRedirectParams() = default;
WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
    ~FollowRedirectParams() = default;

WebRequestProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
    WebRequestProxyingURLLoaderFactory* factory,
    uint64_t request_id,
    int32_t network_service_request_id,
    int32_t view_routing_id,
    int32_t frame_routing_id,
    uint32_t options,
    ukm::SourceIdObj ukm_source_id,
    const network::ResourceRequest& request,
    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
    mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
    mojo::PendingRemote<network::mojom::URLLoaderClient> client,
    scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner)
    :{}

WebRequestProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
    WebRequestProxyingURLLoaderFactory* factory,
    uint64_t request_id,
    int32_t frame_routing_id,
    const network::ResourceRequest& request)
    :{}

WebRequestProxyingURLLoaderFactory::InProgressRequest::~InProgressRequest() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::Restart() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    UpdateRequestInfo() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::RestartInternal() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirect(
    const std::vector<std::string>& removed_headers,
    const net::HttpRequestHeaders& modified_headers,
    const net::HttpRequestHeaders& modified_cors_exempt_headers,
    const std::optional<GURL>& new_url) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::SetPriority(
    net::RequestPriority priority,
    int32_t intra_priority_value) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    PauseReadingBodyFromNet() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ResumeReadingBodyFromNet() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnReceiveEarlyHints(
    network::mojom::EarlyHintsPtr early_hints) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnReceiveResponse(
    network::mojom::URLResponseHeadPtr head,
    mojo::ScopedDataPipeConsumerHandle body,
    std::optional<mojo_base::BigBuffer> cached_metadata) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnReceiveRedirect(
    const net::RedirectInfo& redirect_info,
    network::mojom::URLResponseHeadPtr head) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnUploadProgress(
    int64_t current_position,
    int64_t total_size,
    OnUploadProgressCallback callback) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    OnTransferSizeUpdated(int32_t transfer_size_diff) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnComplete(
    const network::URLLoaderCompletionStatus& status) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::HandleAuthRequest(
    const net::AuthChallengeInfo& auth_info,
    scoped_refptr<net::HttpResponseHeaders> response_headers,
    WebRequestAPI::AuthRequestCallback callback) {}

bool WebRequestProxyingURLLoaderFactory::IsForServiceWorkerScript() const {}

bool WebRequestProxyingURLLoaderFactory::IsForDownload() const {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnLoaderCreated(
    mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnBeforeSendHeaders(
    const net::HttpRequestHeaders& headers,
    OnBeforeSendHeadersCallback callback) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnHeadersReceived(
    const std::string& headers,
    const net::IPEndPoint& remote_endpoint,
    OnHeadersReceivedCallback callback) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    HandleBeforeRequestRedirect() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToBeforeSendHeaders(State state_on_error, int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToBeforeSendHeadersWithOk() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToStartRequest(State state_on_error, int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToStartRequestWithOk() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToSendHeaders(State state_on_error,
                          const std::set<std::string>& removed_headers,
                          const std::set<std::string>& set_headers,
                          int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToSendHeadersWithOk(const std::set<std::string>& removed_headers,
                                const std::set<std::string>& set_headers) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::ContinueAuthRequest(
    const net::AuthChallengeInfo& auth_info,
    WebRequestAPI::AuthRequestCallback callback,
    int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    OnAuthRequestHandled(WebRequestAPI::AuthRequestCallback callback,
                         WebRequestEventRouter::AuthRequiredResponse response) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToHandleOverrideHeaders(int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    OverwriteHeadersAndContinueToResponseStarted(int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    AssignParsedHeadersAndContinueToResponseStarted(
        network::mojom::ParsedHeadersPtr parsed_headers) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToResponseStarted() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    ContinueToBeforeRedirect(const net::RedirectInfo& redirect_info,
                             int error_code) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    HandleResponseOrRedirectHeaders(net::CompletionOnceCallback continuation) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnRequestError(
    const network::URLLoaderCompletionStatus& status,
    State state) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnNetworkError(
    const network::URLLoaderCompletionStatus& status) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    OnClientDisconnected() {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    OnLoaderDisconnected(uint32_t custom_reason,
                         const std::string& description) {}

// Determines whether it is safe to redirect from |from_url| to |to_url|.
bool WebRequestProxyingURLLoaderFactory::InProgressRequest::IsRedirectSafe(
    const GURL& upstream_url,
    const GURL& target_url,
    bool is_navigation_request) {}

network::URLLoaderCompletionStatus WebRequestProxyingURLLoaderFactory::
    InProgressRequest::CreateURLLoaderCompletionStatus(
        int error_code,
        bool collapse_initiator) {}

void WebRequestProxyingURLLoaderFactory::InProgressRequest::
    EraseDNRActionsForExtension(const ExtensionId& extension_id) {}

WebRequestProxyingURLLoaderFactory::WebRequestProxyingURLLoaderFactory(
    content::BrowserContext* browser_context,
    int render_process_id,
    int frame_routing_id,
    int view_routing_id,
    WebRequestAPI::RequestIDGenerator* request_id_generator,
    std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
    std::optional<int64_t> navigation_id,
    ukm::SourceIdObj ukm_source_id,
    network::URLLoaderFactoryBuilder& factory_builder,
    mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
        header_client_receiver,
    WebRequestAPI::ProxySet* proxies,
    content::ContentBrowserClient::URLLoaderFactoryType loader_factory_type,
    scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner)
    :{}

void WebRequestProxyingURLLoaderFactory::StartProxying(
    content::BrowserContext* browser_context,
    int render_process_id,
    int frame_routing_id,
    int view_routing_id,
    WebRequestAPI::RequestIDGenerator* request_id_generator,
    std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
    std::optional<int64_t> navigation_id,
    ukm::SourceIdObj ukm_source_id,
    network::URLLoaderFactoryBuilder& factory_builder,
    mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
        header_client_receiver,
    WebRequestAPI::ProxySet* proxies,
    content::ContentBrowserClient::URLLoaderFactoryType loader_factory_type,
    scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) {}

void WebRequestProxyingURLLoaderFactory::CreateLoaderAndStart(
    mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
    int32_t request_id,
    uint32_t options,
    const network::ResourceRequest& request,
    mojo::PendingRemote<network::mojom::URLLoaderClient> client,
    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {}

void WebRequestProxyingURLLoaderFactory::Clone(
    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) {}

void WebRequestProxyingURLLoaderFactory::OnLoaderCreated(
    int32_t request_id,
    mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {}

void WebRequestProxyingURLLoaderFactory::OnLoaderForCorsPreflightCreated(
    const network::ResourceRequest& request,
    mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {}

void WebRequestProxyingURLLoaderFactory::HandleAuthRequest(
    const net::AuthChallengeInfo& auth_info,
    scoped_refptr<net::HttpResponseHeaders> response_headers,
    int32_t request_id,
    WebRequestAPI::AuthRequestCallback callback) {}

void WebRequestProxyingURLLoaderFactory::OnDNRExtensionUnloaded(
    const Extension* extension) {}

WebRequestProxyingURLLoaderFactory::~WebRequestProxyingURLLoaderFactory() =
    default;

void WebRequestProxyingURLLoaderFactory::OnTargetFactoryError() {}

void WebRequestProxyingURLLoaderFactory::OnProxyBindingError() {}

void WebRequestProxyingURLLoaderFactory::RemoveRequest(
    int32_t network_service_request_id,
    uint64_t request_id) {}

void WebRequestProxyingURLLoaderFactory::MaybeRemoveProxy() {}

// static
void WebRequestProxyingURLLoaderFactory::EnsureAssociatedFactoryBuilt() {}

}  // namespace extensions