#include "services/network/url_loader.h"
#include <algorithm>
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/containers/fixed_flat_set.h"
#include "base/files/file.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/sequence_checker.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/isolation_info.h"
#include "net/base/load_flags.h"
#include "net/base/load_timing_info.h"
#include "net/base/mime_sniffer.h"
#include "net/base/proxy_chain.h"
#include "net/base/schemeful_site.h"
#include "net/base/transport_info.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_file_element_reader.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_setting_override.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/site_for_cookies.h"
#include "net/cookies/static_cookie_policy.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/http_connection_info.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_util.h"
#include "net/log/net_log_source_type.h"
#include "net/log/net_log_with_source.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/ssl/ssl_private_key.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 "net/url_request/url_request_context_getter.h"
#include "services/network/ad_heuristic_cookie_overrides.h"
#include "services/network/attribution/attribution_request_helper.h"
#include "services/network/chunked_data_pipe_upload_data_stream.h"
#include "services/network/data_pipe_element_reader.h"
#include "services/network/orb/orb_impl.h"
#include "services/network/public/cpp/client_hints.h"
#include "services/network/public/cpp/constants.h"
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/cpp/cross_origin_resource_policy.h"
#include "services/network/public/cpp/empty_url_loader_client.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/header_util.h"
#include "services/network/public/cpp/ip_address_space_util.h"
#include "services/network/public/cpp/net_adapters.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/parsed_headers.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/client_security_state.mojom-forward.h"
#include "services/network/public/mojom/cookie_access_observer.mojom-forward.h"
#include "services/network/public/mojom/cookie_access_observer.mojom.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/public/mojom/devtools_observer.mojom.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/http_raw_headers.mojom.h"
#include "services/network/public/mojom/network_context_client.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/resource_scheduler/resource_scheduler_client.h"
#include "services/network/sec_header_helpers.h"
#include "services/network/shared_dictionary/shared_dictionary_access_checker.h"
#include "services/network/shared_dictionary/shared_dictionary_manager.h"
#include "services/network/shared_dictionary/shared_dictionary_storage.h"
#include "services/network/shared_storage/shared_storage_request_helper.h"
#include "services/network/slop_bucket.h"
#include "services/network/throttling/scoped_throttling_token.h"
#include "services/network/trust_tokens/trust_token_request_helper.h"
#include "services/network/url_loader_factory.h"
#include "url/origin.h"
namespace network {
namespace {
constexpr size_t kBlockedBodyAllocationSize = …;
constexpr size_t kDiscardBufferSize = …;
class BytesElementReader : public net::UploadBytesElementReader { … };
class FileElementReader : public net::UploadFileElementReader { … };
std::unique_ptr<net::UploadDataStream> CreateUploadDataStream(
ResourceRequestBody* body,
std::vector<base::File>& opened_files,
base::SequencedTaskRunner* file_task_runner) { … }
class SSLPrivateKeyInternal : public net::SSLPrivateKey { … };
bool ShouldNotifyAboutCookie(net::CookieInclusionStatus status) { … }
std::vector<mojom::WebClientHintsType> ComputeAcceptCHFrameHints(
const std::string& accept_ch_frame,
const net::HttpRequestHeaders& headers) { … }
bool ShouldAllowCredentials(mojom::CredentialsMode credentials_mode) { … }
bool ShouldSendClientCertificates(mojom::CredentialsMode credentials_mode) { … }
template <typename T>
T* PtrOrFallback(const mojo::Remote<T>& remote, T* fallback) { … }
std::string GetCookiesFromHeaders(
const net::HttpRequestHeaders& headers,
const net::HttpRequestHeaders& cors_exempt_headers) { … }
net::HttpRequestHeaders AttachCookies(const net::HttpRequestHeaders& headers,
const std::string& cookies_from_browser) { … }
const char* GetDestinationTypePartString(
network::mojom::RequestDestination destination) { … }
const char* GetCertStatePartString(const net::SSLInfo& ssl_info) { … }
void MaybeRecordSharedDictionaryUsedResponseMetrics(
int error_code,
network::mojom::RequestDestination destination,
const net::HttpResponseInfo& response_info,
bool shared_dictionary_allowed_check_passed) { … }
std::vector<network::mojom::HttpRawHeaderPairPtr>
ResponseHeaderToRawHeaderPairs(
const net::HttpResponseHeaders& response_headers) { … }
}
URLLoader::MaybeSyncURLLoaderClient::MaybeSyncURLLoaderClient(
mojo::PendingRemote<mojom::URLLoaderClient> mojo_client,
base::WeakPtr<mojom::URLLoaderClient> sync_client)
: … { … }
URLLoader::MaybeSyncURLLoaderClient::~MaybeSyncURLLoaderClient() = default;
void URLLoader::MaybeSyncURLLoaderClient::Reset() { … }
mojo::PendingReceiver<mojom::URLLoaderClient>
URLLoader::MaybeSyncURLLoaderClient::BindNewPipeAndPassReceiver() { … }
mojom::URLLoaderClient* URLLoader::MaybeSyncURLLoaderClient::Get() { … }
URLLoader::PartialLoadInfo::PartialLoadInfo(net::LoadStateWithParam load_state,
net::UploadProgress upload_progress)
: … { … }
URLLoader::URLLoader(
URLLoaderContext& context,
DeleteCallback delete_callback,
mojo::PendingReceiver<mojom::URLLoader> url_loader_receiver,
int32_t options,
const ResourceRequest& request,
mojo::PendingRemote<mojom::URLLoaderClient> url_loader_client,
base::WeakPtr<mojom::URLLoaderClient> sync_url_loader_client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
base::StrictNumeric<int32_t> request_id,
int keepalive_request_size,
base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder,
std::unique_ptr<TrustTokenRequestHelperFactory> trust_token_helper_factory,
SharedDictionaryManager* shared_dictionary_manager,
std::unique_ptr<SharedDictionaryAccessChecker> shared_dictionary_checker,
mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer,
mojo::PendingRemote<mojom::TrustTokenAccessObserver> trust_token_observer,
mojo::PendingRemote<mojom::URLLoaderNetworkServiceObserver>
url_loader_network_observer,
mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer,
mojo::PendingRemote<mojom::AcceptCHFrameObserver> accept_ch_frame_observer,
net::CookieSettingOverrides cookie_setting_overrides,
std::unique_ptr<AttributionRequestHelper> attribution_request_helper,
bool shared_storage_writable_eligible)
: … { … }
class URLLoader::FileOpenerForUpload { … };
void URLLoader::OpenFilesForUpload(const ResourceRequest& request) { … }
void URLLoader::SetUpUpload(const ResourceRequest& request,
int error_code,
std::vector<base::File> opened_files) { … }
void URLLoader::ProcessOutboundSharedStorageInterceptor() { … }
void URLLoader::ProcessOutboundAttributionInterceptor() { … }
void URLLoader::ProcessOutboundTrustTokenInterceptor(
const ResourceRequest& request) { … }
void URLLoader::OnDoneConstructingTrustTokenHelper(
mojom::TrustTokenOperationType operation,
TrustTokenStatusOrRequestHelper status_or_helper) { … }
void URLLoader::OnDoneBeginningTrustTokenOperation(
std::optional<net::HttpRequestHeaders> headers,
mojom::TrustTokenOperationStatus status) { … }
void URLLoader::ScheduleStart() { … }
URLLoader::~URLLoader() { … }
const void* const URLLoader::kUserDataKey = …;
void URLLoader::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 URLLoader::SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) { … }
void URLLoader::PauseReadingBodyFromNet() { … }
void URLLoader::ResumeReadingBodyFromNet() { … }
PrivateNetworkAccessCheckResult URLLoader::PrivateNetworkAccessCheck(
const net::TransportInfo& transport_info) { … }
int URLLoader::OnConnected(net::URLRequest* url_request,
const net::TransportInfo& info,
net::CompletionOnceCallback callback) { … }
mojom::URLResponseHeadPtr URLLoader::BuildResponseHead() const { … }
void URLLoader::OnReceivedRedirect(net::URLRequest* url_request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) { … }
void URLLoader::ProcessInboundSharedStorageInterceptorOnReceivedRedirect(
const ::net::RedirectInfo& redirect_info,
mojom::URLResponseHeadPtr response) { … }
void URLLoader::ProcessInboundAttributionInterceptorOnReceivedRedirect(
const net::RedirectInfo& redirect_info,
mojom::URLResponseHeadPtr response) { … }
void URLLoader::ContinueOnReceiveRedirect(
const net::RedirectInfo& redirect_info,
uint64_t response_index) { … }
bool URLLoader::HasFetchStreamingUploadBody(const ResourceRequest* request) { … }
std::optional<net::IsolationInfo> URLLoader::GetIsolationInfo(
const net::IsolationInfo& factory_isolation_info,
bool automatically_assign_isolation_info,
const ResourceRequest& request) { … }
void URLLoader::OnAuthRequired(net::URLRequest* url_request,
const net::AuthChallengeInfo& auth_info) { … }
void URLLoader::OnCertificateRequested(net::URLRequest* unused,
net::SSLCertRequestInfo* cert_info) { … }
void URLLoader::OnSSLCertificateError(net::URLRequest* request,
int net_error,
const net::SSLInfo& ssl_info,
bool fatal) { … }
void URLLoader::ProcessInboundSharedStorageInterceptorOnResponseStarted() { … }
void URLLoader::ProcessInboundAttributionInterceptorOnResponseStarted() { … }
void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) { … }
void URLLoader::OnDoneFinalizingTrustTokenOperation(
mojom::TrustTokenOperationStatus status) { … }
void URLLoader::MaybeSendTrustTokenOperationResultToDevTools() { … }
void URLLoader::ContinueOnResponseStarted() { … }
void URLLoader::ReadMore() { … }
void URLLoader::DidRead(int num_bytes,
bool completed_synchronously,
bool into_slop_bucket) { … }
void URLLoader::OnReadCompleted(net::URLRequest* url_request, int bytes_read) { … }
int URLLoader::OnBeforeStartTransaction(
const net::HttpRequestHeaders& headers,
net::NetworkDelegate::OnBeforeStartTransactionCallback callback) { … }
int URLLoader::OnHeadersReceived(
net::CompletionOnceCallback callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
const net::IPEndPoint& endpoint,
std::optional<GURL>* preserve_fragment_on_redirect_url) { … }
URLLoader::PartialLoadInfo URLLoader::GetPartialLoadInfo() const { … }
mojom::LoadInfoPtr URLLoader::CreateLoadInfo(
const PartialLoadInfo& partial_load_info) { … }
net::LoadState URLLoader::GetLoadState() const { … }
net::UploadProgress URLLoader::GetUploadProgress() const { … }
int32_t URLLoader::GetProcessId() const { … }
void URLLoader::SetEnableReportingRawHeaders(bool allow) { … }
uint32_t URLLoader::GetResourceType() const { … }
bool URLLoader::CookiesDisabled() const { … }
bool URLLoader::AllowCookie(const net::CanonicalCookie& cookie,
const GURL& url,
const net::SiteForCookies& site_for_cookies) const { … }
bool URLLoader::AllowFullCookies(
const GURL& url,
const net::SiteForCookies& site_for_cookies) const { … }
URLLoader* URLLoader::ForRequest(const net::URLRequest& request) { … }
void URLLoader::OnAuthCredentials(
const std::optional<net::AuthCredentials>& credentials) { … }
void URLLoader::ContinueWithCertificate(
const scoped_refptr<net::X509Certificate>& x509_certificate,
const std::string& provider_name,
const std::vector<uint16_t>& algorithm_preferences,
mojo::PendingRemote<mojom::SSLPrivateKey> ssl_private_key) { … }
void URLLoader::ContinueWithoutCertificate() { … }
void URLLoader::CancelRequest() { … }
void URLLoader::CancelRequestIfNonceMatchesAndUrlNotExempted(
const base::UnguessableToken& nonce,
const std::set<GURL>& exemptions) { … }
void URLLoader::NotifyCompleted(int error_code) { … }
void URLLoader::OnMojoDisconnect() { … }
void URLLoader::OnResponseBodyStreamConsumerClosed(MojoResult result) { … }
void URLLoader::OnResponseBodyStreamReady(MojoResult result) { … }
void URLLoader::DeleteSelf() { … }
void URLLoader::SendResponseToClient() { … }
void URLLoader::CompletePendingWrite(bool success) { … }
void URLLoader::SetRawResponseHeaders(
scoped_refptr<const net::HttpResponseHeaders> headers) { … }
void URLLoader::NotifyEarlyResponse(
scoped_refptr<const net::HttpResponseHeaders> headers) { … }
void URLLoader::MaybeNotifyEarlyResponseToDevtools(
const net::HttpResponseHeaders& headers) { … }
void URLLoader::SetRawRequestHeadersAndNotify(
net::HttpRawRequestHeaders headers) { … }
bool URLLoader::IsSharedDictionaryReadAllowed() { … }
void URLLoader::DispatchOnRawRequest(
std::vector<network::mojom::HttpRawHeaderPairPtr> headers) { … }
bool URLLoader::DispatchOnRawResponse() { … }
void URLLoader::SendUploadProgress(const net::UploadProgress& progress) { … }
void URLLoader::OnUploadProgressACK() { … }
void URLLoader::OnSSLCertificateErrorResponse(const net::SSLInfo& ssl_info,
int net_error) { … }
bool URLLoader::HasDataPipe() const { … }
void URLLoader::ResumeStart() { … }
void URLLoader::OnBeforeSendHeadersComplete(
net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
int result,
const std::optional<net::HttpRequestHeaders>& headers) { … }
void URLLoader::OnHeadersReceivedComplete(
net::CompletionOnceCallback callback,
scoped_refptr<net::HttpResponseHeaders>* out_headers,
std::optional<GURL>* out_preserve_fragment_on_redirect_url,
int result,
const std::optional<std::string>& headers,
const std::optional<GURL>& preserve_fragment_on_redirect_url) { … }
void URLLoader::CompleteBlockedResponse(
int error_code,
bool should_report_orb_blocking,
std::optional<mojom::BlockedByResponseReason> reason) { … }
URLLoader::BlockResponseForOrbResult URLLoader::BlockResponseForOrb() { … }
bool URLLoader::MaybeBlockResponseForOrb(
orb::ResponseAnalyzer::Decision orb_decision) { … }
void URLLoader::ReportFlaggedResponseCookies(bool call_cookie_observer) { … }
void URLLoader::StartReading() { … }
bool URLLoader::ShouldForceIgnoreSiteForCookies(
const ResourceRequest& request) { … }
void URLLoader::SetRequestCredentials(const GURL& url) { … }
bool URLLoader::CoepAllowCredentials(const GURL& url) { … }
bool URLLoader::ShouldSendTransferSizeUpdated() const { … }
}