#include "content/browser/attribution_reporting/attribution_data_host_manager_impl.h"
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <iterator>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/function_ref.h"
#include "base/functional/overloaded.h"
#include "base/memory/raw_ref.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "base/values.h"
#include "components/attribution_reporting/attribution_scopes_data.h"
#include "components/attribution_reporting/attribution_scopes_set.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/data_host.mojom.h"
#include "components/attribution_reporting/features.h"
#include "components/attribution_reporting/os_registration.h"
#include "components/attribution_reporting/os_registration_error.mojom.h"
#include "components/attribution_reporting/registrar.h"
#include "components/attribution_reporting/registrar_info.h"
#include "components/attribution_reporting/registration_eligibility.mojom.h"
#include "components/attribution_reporting/registration_header_error.h"
#include "components/attribution_reporting/registration_info.h"
#include "components/attribution_reporting/source_registration.h"
#include "components/attribution_reporting/source_registration_error.mojom.h"
#include "components/attribution_reporting/source_type.mojom.h"
#include "components/attribution_reporting/suitable_origin.h"
#include "components/attribution_reporting/trigger_registration.h"
#include "components/attribution_reporting/trigger_registration_error.mojom-shared.h"
#include "content/browser/attribution_reporting/attribution_background_registrations_id.h"
#include "content/browser/attribution_reporting/attribution_beacon_id.h"
#include "content/browser/attribution_reporting/attribution_constants.h"
#include "content/browser/attribution_reporting/attribution_input_event.h"
#include "content/browser/attribution_reporting/attribution_manager.h"
#include "content/browser/attribution_reporting/attribution_reporting.mojom-shared.h"
#include "content/browser/attribution_reporting/attribution_suitable_context.h"
#include "content/browser/attribution_reporting/attribution_trigger.h"
#include "content/browser/attribution_reporting/attribution_utils.h"
#include "content/browser/attribution_reporting/os_registration.h"
#include "content/browser/attribution_reporting/storable_source.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/http/http_response_headers.h"
#include "net/http/structured_headers.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/network/public/cpp/attribution_utils.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/attribution.mojom-forward.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
namespace {
IssueType;
Registrar;
SuitableOrigin;
OsRegistrationError;
RegistrationEligibility;
RegistrationType;
SourceRegistrationError;
SourceType;
TriggerRegistrationError;
AttributionReportingIssueType;
AttributionReportingOsRegistrar;
AttributionReportingOsRegistrars;
enum class NavigationDataHostStatus { … };
void RecordNavigationDataHostStatus(NavigationDataHostStatus event) { … }
enum class RegistrationMethod { … };
void RecordRegistrationMethod(RegistrationMethod method) { … }
enum class RegisterDataHostOutcome { … };
void RecordRegisterDataHostHostOutcome(RegisterDataHostOutcome status) { … }
enum class NavigationUnexpectedRegistration { … };
void RecordNavigationUnexpectedRegistration(
NavigationUnexpectedRegistration status) { … }
enum class BackgroundNavigationOutcome { … };
void RecordBackgroundNavigationOutcome(BackgroundNavigationOutcome outcome) { … }
void RecordSourceRegistrationWithScopesOutcome(bool allowed) { … }
bool BackgroundRegistrationsEnabled() { … }
constexpr size_t kMaxDeferredReceiversPerNavigation = …;
const base::FeatureParam<base::TimeDelta>
kWaitingOnNavigationRegistrationsTimeout{ … };
void MaybeLogAuditIssue(GlobalRenderFrameHostId render_frame_id,
const GURL& request_url,
const std::optional<std::string>& request_devtools_id,
std::optional<std::string> invalid_parameter,
AttributionReportingIssueType violation_type) { … }
void MaybeLogWebSourceIgnored(
GlobalRenderFrameHostId render_frame_id,
const GURL& request_url,
const std::optional<std::string>& request_devtools_id,
const std::optional<std::string>& web_source) { … }
void MaybeLogWebTriggerIgnored(
GlobalRenderFrameHostId render_frame_id,
const GURL& request_url,
const std::optional<std::string>& request_devtools_id,
const std::optional<std::string>& web_trigger) { … }
void MaybeLogOsSourceIgnored(
GlobalRenderFrameHostId render_frame_id,
const GURL& request_url,
const std::optional<std::string>& request_devtools_id,
const std::optional<std::string>& os_source) { … }
void MaybeLogOsTriggerIgnored(
GlobalRenderFrameHostId render_frame_id,
const GURL& request_url,
const std::optional<std::string>& request_devtools_id,
const std::optional<std::string>& os_trigger) { … }
void LogInvalidInfoHeader(GlobalRenderFrameHostId render_frame_id,
const GURL& request_url,
const std::optional<std::string>& request_devtools_id,
const std::string& info_header) { … }
Registrar ConvertToRegistrar(AttributionReportingOsRegistrar os_registrar) { … }
}
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::
SequentialTimeoutsTimer(base::TimeDelta delay)
: … { … }
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::
~SequentialTimeoutsTimer() = default;
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::Timeout::Timeout(
base::TimeTicks time,
base::OnceClosure callback)
: … { … }
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::Timeout::~Timeout() =
default;
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::Timeout::Timeout(
Timeout&&) = default;
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::Timeout&
AttributionDataHostManagerImpl::SequentialTimeoutsTimer::Timeout::Timeout::
operator=(Timeout&&) = default;
void AttributionDataHostManagerImpl::SequentialTimeoutsTimer::Start(
base::OnceClosure callback) { … }
void AttributionDataHostManagerImpl::SequentialTimeoutsTimer::
MaybeStartTimer() { … }
void AttributionDataHostManagerImpl::SequentialTimeoutsTimer::ProcessTimeout() { … }
class AttributionDataHostManagerImpl::NavigationForPendingRegistration { … };
class AttributionDataHostManagerImpl::RegistrationContext { … };
struct AttributionDataHostManagerImpl::DeferredReceiver { … };
struct AttributionDataHostManagerImpl::HeaderPendingDecode { … };
class AttributionDataHostManagerImpl::Registrations { … };
struct AttributionDataHostManagerImpl::RegistrationDataHeaders { … };
struct AttributionDataHostManagerImpl::PendingRegistrationData { … };
enum class AttributionDataHostManagerImpl::OsRegistrationsBufferFlushReason { … };
class AttributionDataHostManagerImpl::OsRegistrationsBuffer { … };
struct AttributionDataHostManagerImpl::
ScopesAndCountForReportingOriginPerNavigation { … };
AttributionDataHostManagerImpl::AttributionDataHostManagerImpl(
AttributionManager* attribution_manager)
: … { … }
AttributionDataHostManagerImpl::~AttributionDataHostManagerImpl() = default;
void AttributionDataHostManagerImpl::RegisterDataHost(
mojo::PendingReceiver<attribution_reporting::mojom::DataHost> data_host,
AttributionSuitableContext suitable_context,
RegistrationEligibility registration_eligibility,
bool is_for_background_requests) { … }
bool AttributionDataHostManagerImpl::RegisterNavigationDataHost(
mojo::PendingReceiver<attribution_reporting::mojom::DataHost> data_host,
const blink::AttributionSrcToken& attribution_src_token) { … }
void AttributionDataHostManagerImpl::ParseHeader(
base::flat_set<Registrations>::iterator it,
HeaderPendingDecode pending_decode,
Registrar registrar) { … }
void AttributionDataHostManagerImpl::HandleRegistrationData(
base::flat_set<Registrations>::iterator it,
PendingRegistrationData pending_registration_data) { … }
void AttributionDataHostManagerImpl::HandleNextRegistrationData(
base::flat_set<Registrations>::iterator it) { … }
void AttributionDataHostManagerImpl::OnInfoHeaderParsed(
RegistrationsId id,
InfoParseResult result) { … }
void AttributionDataHostManagerImpl::HandleRegistrationInfo(
base::flat_set<Registrations>::iterator it,
PendingRegistrationData pending_registration_data,
const attribution_reporting::RegistrationInfo& registration_info) { … }
void AttributionDataHostManagerImpl::HandleNextWebDecode(
const Registrations& registrations) { … }
void AttributionDataHostManagerImpl::HandleNextOsDecode(
const Registrations& registrations) { … }
bool AttributionDataHostManagerImpl::
NotifyNavigationWithBackgroundRegistrationsWillStart(
const blink::AttributionSrcToken& attribution_src_token,
size_t expected_registrations) { … }
void AttributionDataHostManagerImpl::NotifyNavigationRegistrationStarted(
AttributionSuitableContext suitable_context,
const blink::AttributionSrcToken& attribution_src_token,
int64_t navigation_id,
std::string devtools_request_id) { … }
bool AttributionDataHostManagerImpl::NotifyNavigationRegistrationData(
const blink::AttributionSrcToken& attribution_src_token,
const net::HttpResponseHeaders* headers,
GURL reporting_url) { … }
void AttributionDataHostManagerImpl::
MaybeClearBackgroundRegistrationsWaitingOnNavigation(
const blink::AttributionSrcToken& attribution_src_token,
bool due_to_timeout) { … }
void AttributionDataHostManagerImpl::NotifyNavigationRegistrationCompleted(
const blink::AttributionSrcToken& attribution_src_token) { … }
void AttributionDataHostManagerImpl::NotifyBackgroundRegistrationStarted(
BackgroundRegistrationsId id,
AttributionSuitableContext suitable_context,
attribution_reporting::mojom::RegistrationEligibility
registration_eligibility,
std::optional<blink::AttributionSrcToken> attribution_src_token,
std::optional<std::string> devtools_request_id) { … }
bool AttributionDataHostManagerImpl::NotifyBackgroundRegistrationData(
BackgroundRegistrationsId id,
const net::HttpResponseHeaders* headers,
GURL reporting_url) { … }
void AttributionDataHostManagerImpl::NotifyBackgroundRegistrationCompleted(
BackgroundRegistrationsId id) { … }
const AttributionDataHostManagerImpl::RegistrationContext*
AttributionDataHostManagerImpl::GetReceiverRegistrationContextForSource() { … }
const AttributionDataHostManagerImpl::RegistrationContext*
AttributionDataHostManagerImpl::GetReceiverRegistrationContextForTrigger() { … }
void AttributionDataHostManagerImpl::SourceDataAvailable(
SuitableOrigin reporting_origin,
attribution_reporting::SourceRegistration data,
bool was_fetched_via_service_worker) { … }
void AttributionDataHostManagerImpl::TriggerDataAvailable(
SuitableOrigin reporting_origin,
attribution_reporting::TriggerRegistration data,
bool was_fetched_via_service_worker) { … }
void AttributionDataHostManagerImpl::OsSourceDataAvailable(
attribution_reporting::SuitableOrigin reporting_origin,
std::vector<attribution_reporting::OsRegistrationItem> registration_items,
bool was_fetched_via_service_worker) { … }
void AttributionDataHostManagerImpl::OsTriggerDataAvailable(
attribution_reporting::SuitableOrigin reporting_origin,
std::vector<attribution_reporting::OsRegistrationItem> registration_items,
bool was_fetched_via_service_worker) { … }
void AttributionDataHostManagerImpl::OnReceiverDisconnected() { … }
void AttributionDataHostManagerImpl::NotifyFencedFrameReportingBeaconStarted(
BeaconId beacon_id,
AttributionSuitableContext suitable_context,
std::optional<int64_t> navigation_id,
std::string devtools_request_id) { … }
void AttributionDataHostManagerImpl::NotifyFencedFrameReportingBeaconData(
BeaconId beacon_id,
GURL reporting_url,
const net::HttpResponseHeaders* headers,
bool is_final_response) { … }
base::WeakPtr<AttributionDataHostManager>
AttributionDataHostManagerImpl::AsWeakPtr() { … }
void AttributionDataHostManagerImpl::BackgroundRegistrationsTied(
const blink::AttributionSrcToken& token,
size_t count,
bool due_to_timeout) { … }
void AttributionDataHostManagerImpl::HandleParsedWebSource(
const Registrations& registrations,
HeaderPendingDecode& pending_decode,
data_decoder::DataDecoder::ValueOrError result) { … }
void AttributionDataHostManagerImpl::HandleParsedWebTrigger(
const Registrations& registrations,
HeaderPendingDecode& pending_decode,
data_decoder::DataDecoder::ValueOrError result) { … }
void AttributionDataHostManagerImpl::OnWebHeaderParsed(
RegistrationsId id,
data_decoder::DataDecoder::ValueOrError result) { … }
void AttributionDataHostManagerImpl::MaybeBufferOsRegistrations(
int64_t navigation_id,
std::vector<attribution_reporting::OsRegistrationItem> items,
const RegistrationContext& registrations_context) { … }
void AttributionDataHostManagerImpl::OnOsHeaderParsed(RegistrationsId id,
OsParseResult result) { … }
void AttributionDataHostManagerImpl::MaybeOnRegistrationsFinished(
base::flat_set<Registrations>::const_iterator it) { … }
void AttributionDataHostManagerImpl::MaybeStartNavigation(
int64_t navigation_id) { … }
void AttributionDataHostManagerImpl::MaybeDoneWithNavigation(
int64_t navigation_id,
bool due_to_timeout) { … }
bool AttributionDataHostManagerImpl::AddNavigationSourceRegistrationToBatchMap(
int64_t navigation_id,
const SuitableOrigin& reporting_origin,
const attribution_reporting::SourceRegistration& reg,
const GlobalRenderFrameHostId& render_frame_id,
const std::optional<std::string>& devtools_request_id) { … }
void AttributionDataHostManagerImpl::ClearRegistrationsForNavigationBatch(
int64_t navigation_id) { … }
void AttributionDataHostManagerImpl::MaybeBindDeferredReceivers(
int64_t navigation_id,
bool due_to_timeout) { … }
void AttributionDataHostManagerImpl::ClearRegistrationsDeferUntilNavigation(
int64_t navigation_id) { … }
void AttributionDataHostManagerImpl::MaybeFlushOsRegistrationsBuffer(
int64_t navigation_id,
OsRegistrationsBufferFlushReason reason) { … }
void AttributionDataHostManagerImpl::SubmitOsRegistrations(
std::vector<attribution_reporting::OsRegistrationItem> items,
const RegistrationContext& registration_context,
RegistrationType type) { … }
void AttributionDataHostManagerImpl::MaybeLogAuditIssueAndReportHeaderError(
const Registrations& registrations,
const HeaderPendingDecode& pending_decode,
attribution_reporting::RegistrationHeaderErrorDetails error_details) { … }
void AttributionDataHostManagerImpl::ReportRegistrationHeaderError(
attribution_reporting::SuitableOrigin reporting_origin,
const attribution_reporting::RegistrationHeaderError& error) { … }
bool AttributionDataHostManagerImpl::CheckRegistrarSupport(
Registrar registrar,
RegistrationType registration_type,
const RegistrationContext& context,
const SuitableOrigin& reporting_origin) { … }
}