#include "services/network/cors/cors_url_loader.h"
#include <optional>
#include <sstream>
#include <utility>
#include "base/containers/contains.h"
#include "base/containers/flat_set.h"
#include "base/dcheck_is_on.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "net/base/load_flags.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/http/http_status_code.h"
#include "net/log/net_log_values.h"
#include "net/shared_dictionary/shared_dictionary.h"
#include "services/network/cors/cors_url_loader_factory.h"
#include "services/network/cors/cors_util.h"
#include "services/network/cors/preflight_controller.h"
#include "services/network/network_context.h"
#include "services/network/private_network_access_checker.h"
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/header_util.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "services/network/public/cpp/record_ontransfersizeupdate_utils.h"
#include "services/network/public/cpp/request_mode.h"
#include "services/network/public/cpp/timing_allow_origin_parser.h"
#include "services/network/public/mojom/devtools_observer.mojom.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/ip_address_space.mojom.h"
#include "services/network/public/mojom/shared_dictionary_error.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/shared_dictionary/shared_dictionary_access_checker.h"
#include "services/network/shared_dictionary/shared_dictionary_constants.h"
#include "services/network/shared_dictionary/shared_dictionary_data_pipe_writer.h"
#include "services/network/shared_dictionary/shared_dictionary_manager.h"
#include "services/network/shared_dictionary/shared_dictionary_storage.h"
#include "services/network/shared_dictionary/shared_dictionary_writer.h"
#include "services/network/shared_storage/shared_storage_header_utils.h"
#include "services/network/trust_tokens/trust_token_operation_metrics_recorder.h"
#include "services/network/url_loader.h"
#include "services/network/url_loader_factory.h"
#include "url/scheme_host_port.h"
#include "url/url_util.h"
namespace network::cors {
namespace {
enum class PreflightRequiredReason { … };
std::optional<PreflightRequiredReason> NeedsPrivateNetworkAccessPreflight(
const ResourceRequest& request) { … }
std::optional<PreflightRequiredReason> NeedsCorsPreflight(
const ResourceRequest& request) { … }
std::optional<PreflightRequiredReason> NeedsPreflight(
const ResourceRequest& request) { … }
base::Value::Dict NetLogCorsURLLoaderStartParams(
const ResourceRequest& request) { … }
base::Value::Dict NetLogPreflightRequiredParams(
std::optional<PreflightRequiredReason> preflight_required_reason) { … }
base::Value::Dict NetLogPreflightErrorParams(
int net_error,
const std::optional<CorsErrorStatus>& status) { … }
mojom::FetchResponseType CalculateResponseTainting(
const GURL& url,
mojom::RequestMode request_mode,
const std::optional<url::Origin>& origin,
const std::optional<url::Origin>& isolated_world_origin,
bool cors_flag,
bool tainted_origin,
const OriginAccessList& origin_access_list) { … }
std::optional<CorsErrorStatus> CheckRedirectLocation(
const GURL& url,
mojom::RequestMode request_mode,
const std::optional<url::Origin>& origin,
bool cors_flag,
bool tainted) { … }
void RecordNetworkLoaderCompletionTime(const char* suffix,
base::TimeDelta elapsed) { … }
constexpr const char kTimingAllowOrigin[] = …;
}
CorsURLLoader::CorsURLLoader(
mojo::PendingReceiver<mojom::URLLoader> loader_receiver,
int32_t process_id,
int32_t request_id,
uint32_t options,
DeleteCallback delete_callback,
ResourceRequest resource_request,
bool ignore_isolated_world_origin,
bool skip_cors_enabled_scheme_check,
mojo::PendingRemote<mojom::URLLoaderClient> client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::URLLoaderFactory* network_loader_factory,
URLLoaderFactory* sync_network_loader_factory,
const OriginAccessList* origin_access_list,
bool allow_any_cors_exempt_header,
HasFactoryOverride has_factory_override,
const net::IsolationInfo& isolation_info,
mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer,
const mojom::ClientSecurityState* factory_client_security_state,
mojo::Remote<mojom::URLLoaderNetworkServiceObserver>*
url_loader_network_service_observer,
const CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
scoped_refptr<SharedDictionaryStorage> shared_dictionary_storage,
raw_ptr<mojom::SharedDictionaryAccessObserver> shared_dictionary_observer,
NetworkContext* context)
: … { … }
CorsURLLoader::~CorsURLLoader() { … }
void CorsURLLoader::Start() { … }
void CorsURLLoader::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 CorsURLLoader::SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) { … }
void CorsURLLoader::PauseReadingBodyFromNet() { … }
void CorsURLLoader::ResumeReadingBodyFromNet() { … }
void CorsURLLoader::OnReceiveEarlyHints(mojom::EarlyHintsPtr early_hints) { … }
void CorsURLLoader::OnReceiveResponse(
mojom::URLResponseHeadPtr response_head,
mojo::ScopedDataPipeConsumerHandle body,
std::optional<mojo_base::BigBuffer> cached_metadata) { … }
void CorsURLLoader::CheckTainted(const net::RedirectInfo& redirect_info) { … }
void CorsURLLoader::OnReceiveRedirect(const net::RedirectInfo& redirect_info,
mojom::URLResponseHeadPtr response_head) { … }
void CorsURLLoader::OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) { … }
void CorsURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) { … }
void CorsURLLoader::OnComplete(const URLLoaderCompletionStatus& status) { … }
void CorsURLLoader::CancelRequestIfNonceMatchesAndUrlNotExempted(
const base::UnguessableToken& nonce,
const std::set<GURL>& exemptions) { … }
void CorsURLLoader::StartRequest() { … }
void CorsURLLoader::ReportCorsErrorToDevTools(const CorsErrorStatus& status,
bool is_warning) { … }
void CorsURLLoader::ReportOrbErrorToDevTools() { … }
void CorsURLLoader::MaybeReportSharedDictionaryErrorToDevTools(
mojom::SharedDictionaryError error) { … }
std::optional<URLLoaderCompletionStatus> CorsURLLoader::ConvertPreflightResult(
int net_error,
std::optional<CorsErrorStatus> status) { … }
void CorsURLLoader::OnPreflightRequestComplete(
int net_error,
std::optional<CorsErrorStatus> status,
bool has_authorization_covered_by_wildcard) { … }
void CorsURLLoader::StartNetworkRequest() { … }
void CorsURLLoader::HandleComplete(URLLoaderCompletionStatus status) { … }
void CorsURLLoader::OnMojoDisconnect() { … }
void CorsURLLoader::OnNetworkClientMojoDisconnect() { … }
void CorsURLLoader::SetCorsFlagIfNeeded() { … }
bool CorsURLLoader::HasSpecialAccessToDestination() const { … }
mojom::FetchResponseType CorsURLLoader::CalculateResponseTaintingForTesting(
const GURL& url,
mojom::RequestMode request_mode,
const std::optional<url::Origin>& origin,
const std::optional<url::Origin>& isolated_world_origin,
bool cors_flag,
bool tainted_origin,
const OriginAccessList& origin_access_list) { … }
std::optional<CorsErrorStatus> CorsURLLoader::CheckRedirectLocationForTesting(
const GURL& url,
mojom::RequestMode request_mode,
const std::optional<url::Origin>& origin,
bool cors_flag,
bool tainted) { … }
bool CorsURLLoader::PassesTimingAllowOriginCheck(
const mojom::URLResponseHead& response) const { … }
const mojom::ClientSecurityState* CorsURLLoader::GetClientSecurityState()
const { … }
mojom::ClientSecurityStatePtr CorsURLLoader::CloneClientSecurityState() const { … }
bool CorsURLLoader::ShouldIgnorePrivateNetworkAccessErrors(
mojom::IPAddressSpace target_address_space) const { … }
PrivateNetworkAccessPreflightBehavior
CorsURLLoader::GetPrivateNetworkAccessPreflightBehavior(
mojom::IPAddressSpace target_address_space) const { … }
void CorsURLLoader::OnSharedDictionaryWritten(bool success) { … }
mojom::PrivateNetworkAccessPreflightResult
CorsURLLoader::TakePrivateNetworkAccessPreflightResult() { … }
std::optional<std::string> CorsURLLoader::GetHeaderString(
const mojom::URLResponseHead& response,
const std::string& header_name) { … }
bool CorsURLLoader::
CheckSharedStorageCrossOriginWorkletAllowedResponseHeaderIfNeeded(
const mojom::URLResponseHead& response) { … }
}