#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 {
constexpr char kWebRequestProxyingURLLoaderFactoryScope[] = …;
class ShutdownNotifierFactory
: public BrowserContextKeyedServiceShutdownNotifierFactory { … };
net::RedirectInfo CreateRedirectInfo(
const network::ResourceRequest& original_request,
const GURL& new_url,
int response_code,
const std::optional<std::string>& referrer_policy_header) { … }
}
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) { … }
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() { … }
void WebRequestProxyingURLLoaderFactory::EnsureAssociatedFactoryBuilt() { … }
}