Add reporting_source to IPC calls to reporting service.
Send the reporting source token to the network service when configuring
the per-resource endpoints with the Reporting-Endpoints header, and when
queuing reports, and pass that token into the reporting service.
This token is currently unused, but the follow-up CL will use it to
isolate reports from different sources.
This is part of a series of CLs implementing V1 reporting isolation.
A summary of the architectural changes introduced can be found at
https://docs.google.com/document/d/1RmEz17pGSUQITPoRKV4s3IBgbyHjv-HLZqtVYYZ4lMg/edit
CLs in this series:
https://crrev.com/c/2878175 Update NEL browser tests to require Report-To
https://crrev.com/c/2878376 Separate parsing from processing Reporting-Endpoints
https://crrev.com/c/2889833 Add reporting source to worker objects
https://crrev.com/c/2889975 Add reporting source to COOP/COEP reporters
https://crrev.com/c/3039579 Add source token to reports
https://crrev.com/c/3041880 (This CL) Add source token to IPC calls
https://crrev.com/c/3042463 Isolate v1 reports from each other
https://crrev.com/c/3042465 Allow document source token to change
https://crrev.com/c/3042521 Clean up when docs/workers are destroyed
Bug: 1062359
Change-Id: I080d3d9e3c81c0891e2ebb630ebe9f1718add0ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3041880
Reviewed-by: Joshua Bell <[email protected]>
Reviewed-by: Lily Chen <[email protected]>
Reviewed-by: Ken Buchanan <[email protected]>
Reviewed-by: Matt Menke <[email protected]>
Commit-Queue: Ian Clelland <[email protected]>
Cr-Commit-Position: refs/heads/main@{#914373}
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index 3df7498..8636111 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -178,10 +178,12 @@
#if BUILDFLAG(ENABLE_REPORTING)
#include "base/containers/flat_map.h"
+#include "base/unguessable_token.h"
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/reporting/reporting_browsing_data_remover.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#endif // BUILDFLAG(ENABLE_REPORTING)
using content::BrowsingDataFilterBuilder;
@@ -901,19 +903,22 @@
// net::ReportingService implementation:
void SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) override {
NOTREACHED();
}
- void QueueReport(const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth) override {
+ void QueueReport(
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const net::NetworkIsolationKey& network_isolation_key,
+ const std::string& user_agent,
+ const std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body,
+ int depth) override {
NOTREACHED();
}
diff --git a/content/browser/net/cross_origin_embedder_policy_reporter.cc b/content/browser/net/cross_origin_embedder_policy_reporter.cc
index 4efe4bc..cded18c6 100644
--- a/content/browser/net/cross_origin_embedder_policy_reporter.cc
+++ b/content/browser/net/cross_origin_embedder_policy_reporter.cc
@@ -114,7 +114,8 @@
body_to_pass.SetString("disposition", disposition);
storage_partition_->GetNetworkContext()->QueueReport(
- kType, *endpoint, context_url_, network_isolation_key_,
+ kType, *endpoint, context_url_, reporting_source_,
+ network_isolation_key_,
/*user_agent=*/absl::nullopt, std::move(body_to_pass));
}
}
diff --git a/content/browser/net/cross_origin_embedder_policy_reporter_unittest.cc b/content/browser/net/cross_origin_embedder_policy_reporter_unittest.cc
index ad409769..100cc187 100644
--- a/content/browser/net/cross_origin_embedder_policy_reporter_unittest.cc
+++ b/content/browser/net/cross_origin_embedder_policy_reporter_unittest.cc
@@ -8,6 +8,7 @@
#include "base/strings/string_piece.h"
#include "base/test/task_environment.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "content/public/test/test_storage_partition.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -15,6 +16,7 @@
#include "services/network/public/cpp/request_destination.h"
#include "services/network/test/test_network_context.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/mojom/frame/reporting_observer.mojom.h"
namespace content {
@@ -44,12 +46,14 @@
base::Value body;
};
- void QueueReport(const std::string& type,
- const std::string& group,
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- const absl::optional<std::string>& user_agent,
- base::Value body) override {
+ void QueueReport(
+ const std::string& type,
+ const std::string& group,
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const net::NetworkIsolationKey& network_isolation_key,
+ const absl::optional<std::string>& user_agent,
+ base::Value body) override {
DCHECK(!user_agent);
reports_.emplace_back(
Report(type, group, url, network_isolation_key, std::move(body)));
diff --git a/content/browser/net/cross_origin_opener_policy_reporter.cc b/content/browser/net/cross_origin_opener_policy_reporter.cc
index 454c2edf..44476756 100644
--- a/content/browser/net/cross_origin_opener_policy_reporter.cc
+++ b/content/browser/net/cross_origin_opener_policy_reporter.cc
@@ -244,8 +244,8 @@
}
storage_partition_->GetNetworkContext()->QueueReport(
- "coop", endpoint, context_url_, network_isolation_key_, absl::nullopt,
- std::move(body));
+ "coop", endpoint, context_url_, reporting_source_, network_isolation_key_,
+ absl::nullopt, std::move(body));
}
// static
@@ -395,7 +395,7 @@
kEffectivePolicy,
ToString(is_report_only ? coop_.report_only_value : coop_.value));
storage_partition_->GetNetworkContext()->QueueReport(
- "coop", endpoint, context_url_, network_isolation_key_,
+ "coop", endpoint, context_url_, reporting_source_, network_isolation_key_,
/*user_agent=*/absl::nullopt, std::move(body));
}
diff --git a/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc b/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc
index 6d4c1dc..c5bf836 100644
--- a/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc
+++ b/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc
@@ -8,12 +8,14 @@
#include <vector>
#include "base/test/task_environment.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "content/public/test/test_storage_partition.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/network_isolation_key.h"
#include "services/network/test/test_network_context.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace content {
namespace {
@@ -39,12 +41,14 @@
base::Value body;
};
- void QueueReport(const std::string& type,
- const std::string& group,
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- const absl::optional<std::string>& user_agent,
- base::Value body) override {
+ void QueueReport(
+ const std::string& type,
+ const std::string& group,
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const net::NetworkIsolationKey& network_isolation_key,
+ const absl::optional<std::string>& user_agent,
+ base::Value body) override {
DCHECK(!user_agent);
reports_.emplace_back(
Report(type, group, url, network_isolation_key, std::move(body)));
diff --git a/content/browser/net/reporting_service_proxy.cc b/content/browser/net/reporting_service_proxy.cc
index 74dd306..6e7f2a63 100644
--- a/content/browser/net/reporting_service_proxy.cc
+++ b/content/browser/net/reporting_service_proxy.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "base/memory/ref_counted.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/worker_host/dedicated_worker_host.h"
@@ -35,9 +36,13 @@
public:
ReportingServiceProxyImpl(
int render_process_id,
+ const base::UnguessableToken& reporting_source,
const net::NetworkIsolationKey& network_isolation_key)
: render_process_id_(render_process_id),
- network_isolation_key_(network_isolation_key) {}
+ reporting_source_(reporting_source),
+ network_isolation_key_(network_isolation_key) {
+ DCHECK(!reporting_source.is_empty());
+ }
ReportingServiceProxyImpl(const ReportingServiceProxyImpl&) = delete;
ReportingServiceProxyImpl& operator=(const ReportingServiceProxyImpl&) =
@@ -177,12 +182,13 @@
return;
rph->GetStoragePartition()->GetNetworkContext()->QueueReport(
- type, group, url, network_isolation_key_,
+ type, group, url, reporting_source_, network_isolation_key_,
/*user_agent=*/absl::nullopt,
base::Value::FromUniquePtrValue(std::move(body)));
}
const int render_process_id_;
+ const base::UnguessableToken reporting_source_;
const net::NetworkIsolationKey network_isolation_key_;
};
@@ -194,6 +200,7 @@
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
mojo::MakeSelfOwnedReceiver(std::make_unique<ReportingServiceProxyImpl>(
render_frame_host->GetProcess()->GetID(),
+ render_frame_host->GetFrameToken().value(),
render_frame_host->GetNetworkIsolationKey()),
std::move(receiver));
}
@@ -205,6 +212,7 @@
mojo::MakeSelfOwnedReceiver(
std::make_unique<ReportingServiceProxyImpl>(
service_worker_host->worker_process_id(),
+ service_worker_host->GetReportingSource(),
service_worker_host->GetNetworkIsolationKey()),
std::move(receiver));
}
@@ -215,6 +223,7 @@
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
mojo::MakeSelfOwnedReceiver(std::make_unique<ReportingServiceProxyImpl>(
shared_worker_host->GetProcessHost()->GetID(),
+ shared_worker_host->GetReportingSource(),
shared_worker_host->GetNetworkIsolationKey()),
std::move(receiver));
}
@@ -226,6 +235,7 @@
mojo::MakeSelfOwnedReceiver(
std::make_unique<ReportingServiceProxyImpl>(
dedicated_worker_host->GetProcessHost()->GetID(),
+ dedicated_worker_host->GetReportingSource(),
dedicated_worker_host->GetNetworkIsolationKey()),
std::move(receiver));
}
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index a173ec1..3ca740f 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -3480,8 +3480,8 @@
DCHECK(frame_token_.value());
if (!reporting_endpoints_.empty()) {
GetStoragePartition()->GetNetworkContext()->SetDocumentReportingEndpoints(
- params.origin, isolation_info_.network_isolation_key(),
- reporting_endpoints_);
+ frame_token_.value(), params.origin,
+ isolation_info_.network_isolation_key(), reporting_endpoints_);
}
// When the frame hosts a different document, its state must be replicated
@@ -10495,7 +10495,9 @@
// Send the crash report to the Reporting API.
GetProcess()->GetStoragePartition()->GetNetworkContext()->QueueReport(
/*type=*/"crash", /*group=*/"default", last_committed_url_,
- isolation_info_.network_isolation_key(), absl::nullopt, std::move(body));
+ frame_token_.value() /* reporting_source */,
+ isolation_info_.network_isolation_key(), absl::nullopt /* user_agent */,
+ std::move(body));
}
void RenderFrameHostImpl::SendCommitNavigation(
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc
index afc7869..a47ebbed 100644
--- a/net/network_error_logging/network_error_logging_service.cc
+++ b/net/network_error_logging/network_error_logging_service.cc
@@ -489,9 +489,11 @@
<< ", depth=" << details.reporting_upload_depth << ") for "
<< details.uri;
+ // A null reporting source token is used since this report is not associated
+ // with any particular document.
reporting_service_->QueueReport(
- details.uri, details.network_isolation_key, details.user_agent,
- policy->report_to, kReportType,
+ details.uri, absl::nullopt, details.network_isolation_key,
+ details.user_agent, policy->report_to, kReportType,
CreateReportBody(phase_string, type_string, sampling_fraction.value(),
details),
details.reporting_upload_depth);
@@ -537,9 +539,11 @@
return;
}
+ // A null reporting source token is used since this report is not associated
+ // with any particular document.
reporting_service_->QueueReport(
- details.outer_url, details.network_isolation_key, details.user_agent,
- policy->report_to, kReportType,
+ details.outer_url, absl::nullopt, details.network_isolation_key,
+ details.user_agent, policy->report_to, kReportType,
CreateSignedExchangeReportBody(details, sampling_fraction.value()),
0 /* depth */);
RecordSignedExchangeRequestOutcome(RequestOutcome::kQueued);
diff --git a/net/reporting/reporting_browsing_data_remover_unittest.cc b/net/reporting/reporting_browsing_data_remover_unittest.cc
index 687bf5a..a340d102 100644
--- a/net/reporting/reporting_browsing_data_remover_unittest.cc
+++ b/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -43,7 +43,8 @@
// TODO(chlily): Take NIK.
void AddReport(const GURL& url) {
- cache()->AddReport(NetworkIsolationKey(), url, kUserAgent_, kGroup_, kType_,
+ cache()->AddReport(absl::nullopt, NetworkIsolationKey(), url, kUserAgent_,
+ kGroup_, kType_,
std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
}
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h
index 6c5411e8..6e5bc17d 100644
--- a/net/reporting/reporting_cache.h
+++ b/net/reporting/reporting_cache.h
@@ -13,11 +13,13 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "net/base/net_export.h"
#include "net/reporting/reporting_endpoint.h"
#include "net/reporting/reporting_header_parser.h"
#include "net/reporting/reporting_report.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -55,17 +57,23 @@
// Adds a report to the cache.
//
- // All parameters correspond to the desired values for the relevant fields in
- // ReportingReport.
- virtual void AddReport(const NetworkIsolationKey& network_isolation_key,
- const GURL& url,
- const std::string& user_agent,
- const std::string& group_name,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth,
- base::TimeTicks queued,
- int attempts) = 0;
+ // |reporting_source| and |network_isolation_key| will be used when the
+ // report is delivered, to determine which endpoints are eligible to receive
+ // this report, and which other reports this report can be batched with.
+ //
+ // All other parameters correspond to the desired values for the relevant
+ // fields in ReportingReport.
+ virtual void AddReport(
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
+ const GURL& url,
+ const std::string& user_agent,
+ const std::string& group_name,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body,
+ int depth,
+ base::TimeTicks queued,
+ int attempts) = 0;
// Gets all reports in the cache. The returned pointers are valid as long as
// either no calls to |RemoveReports| have happened or the reports' |pending|
diff --git a/net/reporting/reporting_cache_impl.cc b/net/reporting/reporting_cache_impl.cc
index 4b0af50..ec112b88 100644
--- a/net/reporting/reporting_cache_impl.cc
+++ b/net/reporting/reporting_cache_impl.cc
@@ -27,6 +27,7 @@
ReportingCacheImpl::~ReportingCacheImpl() = default;
void ReportingCacheImpl::AddReport(
+ const absl::optional<base::UnguessableToken>& reporting_source,
const NetworkIsolationKey& network_isolation_key,
const GURL& url,
const std::string& user_agent,
@@ -36,6 +37,8 @@
int depth,
base::TimeTicks queued,
int attempts) {
+ // If |reporting_source| is present, it must not be empty.
+ DCHECK(!(reporting_source.has_value() && reporting_source->is_empty()));
auto report = std::make_unique<ReportingReport>(
absl::nullopt, network_isolation_key, url, user_agent, group_name, type,
std::move(body), depth, queued, attempts);
diff --git a/net/reporting/reporting_cache_impl.h b/net/reporting/reporting_cache_impl.h
index 83283da..d2099ac 100644
--- a/net/reporting/reporting_cache_impl.h
+++ b/net/reporting/reporting_cache_impl.h
@@ -18,6 +18,7 @@
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_context.h"
@@ -37,7 +38,8 @@
~ReportingCacheImpl() override;
// ReportingCache implementation
- void AddReport(const NetworkIsolationKey& network_isolation_key,
+ void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& url,
const std::string& user_agent,
const std::string& group_name,
diff --git a/net/reporting/reporting_cache_unittest.cc b/net/reporting/reporting_cache_unittest.cc
index 3f8515d14..e3fe083 100644
--- a/net/reporting/reporting_cache_unittest.cc
+++ b/net/reporting/reporting_cache_unittest.cc
@@ -125,8 +125,8 @@
// in test cases, so I've optimized for readability over execution speed.
std::vector<const ReportingReport*> before;
cache()->GetReports(&before);
- cache()->AddReport(network_isolation_key, url, user_agent, group, type,
- std::move(body), depth, queued, attempts);
+ cache()->AddReport(absl::nullopt, network_isolation_key, url, user_agent,
+ group, type, std::move(body), depth, queued, attempts);
std::vector<const ReportingReport*> after;
cache()->GetReports(&after);
@@ -184,6 +184,8 @@
const GURL kUrl2_ = GURL("https://origin2/path");
const url::Origin kOrigin1_ = url::Origin::Create(GURL("https://origin1/"));
const url::Origin kOrigin2_ = url::Origin::Create(GURL("https://origin2/"));
+ const absl::optional<base::UnguessableToken> kReportingSource_ =
+ absl::nullopt;
const NetworkIsolationKey kNik_;
const NetworkIsolationKey kOtherNik_ =
NetworkIsolationKey(SchemefulSite(kOrigin1_), SchemefulSite(kOrigin2_));
@@ -234,9 +236,9 @@
cache()->GetReports(&reports);
EXPECT_TRUE(reports.empty());
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0, kNowTicks_,
- 0);
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
+ kNowTicks_, 0);
EXPECT_EQ(1, observer()->cached_reports_update_count());
cache()->GetReports(&reports);
@@ -273,12 +275,12 @@
TEST_P(ReportingCacheTest, RemoveAllReports) {
LoadReportingClients();
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0, kNowTicks_,
- 0);
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0, kNowTicks_,
- 0);
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
+ kNowTicks_, 0);
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
+ kNowTicks_, 0);
EXPECT_EQ(2, observer()->cached_reports_update_count());
std::vector<const ReportingReport*> reports;
@@ -295,9 +297,9 @@
TEST_P(ReportingCacheTest, RemovePendingReports) {
LoadReportingClients();
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0, kNowTicks_,
- 0);
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
+ kNowTicks_, 0);
EXPECT_EQ(1, observer()->cached_reports_update_count());
std::vector<const ReportingReport*> reports;
@@ -333,9 +335,9 @@
TEST_P(ReportingCacheTest, RemoveAllPendingReports) {
LoadReportingClients();
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0, kNowTicks_,
- 0);
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
+ kNowTicks_, 0);
EXPECT_EQ(1, observer()->cached_reports_update_count());
std::vector<const ReportingReport*> reports;
@@ -1178,16 +1180,16 @@
// Enqueue the maximum number of reports, spaced apart in time.
for (size_t i = 0; i < max_report_count; ++i) {
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
tick_clock()->Advance(base::TimeDelta::FromMinutes(1));
}
EXPECT_EQ(max_report_count, report_count());
// Add one more report to force the cache to evict one.
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
// Make sure the cache evicted a report to make room for the new one, and make
@@ -1224,9 +1226,9 @@
// Add one more report to force the cache to evict one. Since the cache has
// only pending reports, it will be forced to evict the *new* report!
- cache()->AddReport(kNik_, kUrl1_, kUserAgent_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), 0, kNowTicks_,
- 0);
+ cache()->AddReport(kReportingSource_, kNik_, kUrl1_, kUserAgent_, kGroup1_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
+ kNowTicks_, 0);
// Make sure the cache evicted a report, and make sure the report evicted was
// the new, non-pending one.
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc
index dc63387..79f376d 100644
--- a/net/reporting/reporting_delivery_agent_unittest.cc
+++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -12,6 +12,7 @@
#include "base/test/values_test_util.h"
#include "base/time/time.h"
#include "base/timer/mock_timer.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "net/base/backoff_entry.h"
#include "net/base/features.h"
@@ -22,6 +23,7 @@
#include "net/reporting/reporting_test_util.h"
#include "net/reporting/reporting_uploader.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -49,13 +51,14 @@
report_body_.SetStringKey("key", "value");
}
- void AddReport(const NetworkIsolationKey& network_isolation_key,
+ void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& url,
const std::string& group) {
- cache()->AddReport(network_isolation_key, url, kUserAgent_, group, kType_,
- std::make_unique<base::Value>(report_body_.Clone()),
- 0 /* depth */, tick_clock()->NowTicks() /* queued */,
- 0 /* attempts */);
+ cache()->AddReport(
+ reporting_source, network_isolation_key, url, kUserAgent_, group,
+ kType_, std::make_unique<base::Value>(report_body_.Clone()),
+ 0 /* depth */, tick_clock()->NowTicks() /* queued */, 0 /* attempts */);
}
// The first report added to the cache is uploaded immediately, and a timer is
@@ -68,8 +71,8 @@
"dummy");
ASSERT_TRUE(SetEndpointInCache(
dummy_group, GURL("https://dummy.test/upload"), kExpires_));
- AddReport(dummy_group.network_isolation_key, dummy_group.origin.GetURL(),
- dummy_group.group_name);
+ AddReport(absl::nullopt, dummy_group.network_isolation_key,
+ dummy_group.origin.GetURL(), dummy_group.group_name);
ASSERT_EQ(1u, pending_uploads().size());
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
@@ -86,6 +89,8 @@
const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
const url::Origin kOtherOrigin_ =
url::Origin::Create(GURL("https://other-origin/"));
+ const absl::optional<base::UnguessableToken> kReportingSource_ =
+ absl::nullopt;
const NetworkIsolationKey kNik_ =
NetworkIsolationKey(SchemefulSite(kOrigin_), SchemefulSite(kOrigin_));
const NetworkIsolationKey kOtherNik_ =
@@ -102,7 +107,7 @@
TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
// Upload is automatically started when cache is modified.
@@ -148,7 +153,7 @@
TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
OriginSubdomains::INCLUDE));
- AddReport(kNik_, kSubdomainUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kSubdomainUrl_, kGroup_);
// Upload is automatically started when cache is modified.
@@ -195,7 +200,7 @@
SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
OriginSubdomains::INCLUDE));
- AddReport(kNik_, kSubdomainUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kSubdomainUrl_, kGroup_);
// Upload is automatically started when cache is modified.
@@ -223,11 +228,11 @@
TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
// Trigger and complete an upload to start the delivery timer.
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
// Add another report to upload after a delay.
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -273,7 +278,7 @@
TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -324,7 +329,7 @@
body.SetString("key", "value");
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis));
@@ -357,7 +362,7 @@
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -384,7 +389,7 @@
TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -418,7 +423,7 @@
context()->test_delegate()->set_pause_permissions_check(true);
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused());
@@ -464,16 +469,16 @@
// Now that the delivery timer is running, these reports won't be immediately
// uploaded.
- AddReport(kNik_, kUrl_, kGroup_);
- AddReport(kNik_, kOtherUrl_, kGroup_);
- AddReport(kNik_, kOtherUrl_, kGroup_);
- AddReport(kOtherNik_, kUrl_, kGroup_);
- AddReport(kOtherNik_, kUrl_, kGroup_);
- AddReport(kOtherNik_, kUrl_, kGroup_);
- AddReport(kOtherNik_, kOtherUrl_, kGroup_);
- AddReport(kOtherNik_, kOtherUrl_, kGroup_);
- AddReport(kOtherNik_, kOtherUrl_, kGroup_);
- AddReport(kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kOtherUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kOtherUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kReportingSource_, kOtherNik_, kOtherUrl_, kGroup_);
EXPECT_EQ(0u, pending_uploads().size());
// There should be one upload per (NIK, origin).
@@ -511,14 +516,14 @@
UploadFirstReportAndStartTimer();
// First upload causes this group key to become pending.
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
EXPECT_EQ(0u, pending_uploads().size());
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
EXPECT_EQ(1u, pending_uploads().size());
// Second upload isn't started because the group is pending.
- AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
ASSERT_EQ(1u, pending_uploads().size());
@@ -562,8 +567,8 @@
// Trigger and complete an upload to start the delivery timer.
UploadFirstReportAndStartTimer();
- AddReport(kNik_, kUrl_, kGroup_);
- AddReport(kNik_, kUrl_, kDifferentGroup);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kDifferentGroup);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -604,8 +609,8 @@
UploadFirstReportAndStartTimer();
- AddReport(kNik_, kUrl_, kGroup_);
- AddReport(kNik_, kUrl_, kDifferentGroup);
+ AddReport(kReportingSource_, kNik_, kUrl_, kGroup_);
+ AddReport(kReportingSource_, kNik_, kUrl_, kDifferentGroup);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
diff --git a/net/reporting/reporting_endpoint_manager_unittest.cc b/net/reporting/reporting_endpoint_manager_unittest.cc
index b72935f5..0d96d1e 100644
--- a/net/reporting/reporting_endpoint_manager_unittest.cc
+++ b/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -9,6 +9,7 @@
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "net/base/backoff_entry.h"
#include "net/base/network_isolation_key.h"
#include "net/base/schemeful_site.h"
@@ -17,6 +18,7 @@
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -48,7 +50,8 @@
}
// Everything below is NOTREACHED.
- void AddReport(const NetworkIsolationKey& network_isolation_key,
+ void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& url,
const std::string& user_agent,
const std::string& group_name,
diff --git a/net/reporting/reporting_garbage_collector_unittest.cc b/net/reporting/reporting_garbage_collector_unittest.cc
index 71ea1cea..4f9f89d 100644
--- a/net/reporting/reporting_garbage_collector_unittest.cc
+++ b/net/reporting/reporting_garbage_collector_unittest.cc
@@ -14,6 +14,7 @@
#include "net/reporting/reporting_report.h"
#include "net/reporting/reporting_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace net {
namespace {
@@ -26,6 +27,8 @@
return reports.size();
}
+ const absl::optional<base::UnguessableToken> kReportingSource_ =
+ absl::nullopt;
const NetworkIsolationKey kNik_;
const GURL kUrl_ = GURL("https://origin/path");
const std::string kUserAgent_ = "Mozilla/1.0";
@@ -42,8 +45,8 @@
TEST_F(ReportingGarbageCollectorTest, Timer) {
EXPECT_FALSE(garbage_collection_timer()->IsRunning());
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(garbage_collection_timer()->IsRunning());
@@ -54,8 +57,8 @@
}
TEST_F(ReportingGarbageCollectorTest, Report) {
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
garbage_collection_timer()->Fire();
@@ -63,8 +66,8 @@
}
TEST_F(ReportingGarbageCollectorTest, ExpiredReport) {
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
tick_clock()->Advance(2 * policy().max_report_age);
garbage_collection_timer()->Fire();
@@ -73,8 +76,8 @@
}
TEST_F(ReportingGarbageCollectorTest, FailedReport) {
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
std::vector<const ReportingReport*> reports;
diff --git a/net/reporting/reporting_header_parser.cc b/net/reporting/reporting_header_parser.cc
index 93ac03b..82475719 100644
--- a/net/reporting/reporting_header_parser.cc
+++ b/net/reporting/reporting_header_parser.cc
@@ -330,11 +330,13 @@
// static
void ReportingHeaderParser::ProcessParsedReportingEndpointsHeader(
ReportingContext* context,
+ const base::UnguessableToken& reporting_source,
const NetworkIsolationKey& network_isolation_key,
const url::Origin& origin,
base::flat_map<std::string, std::string> header) {
DCHECK(base::FeatureList::IsEnabled(net::features::kDocumentReporting));
DCHECK(GURL::SchemeIsCryptographic(origin.scheme()));
+ DCHECK(!reporting_source.is_empty());
ReportingDelegate* delegate = context->delegate();
ReportingCache* cache = context->cache();
diff --git a/net/reporting/reporting_header_parser.h b/net/reporting/reporting_header_parser.h
index 6a1b955e..ea981b1ff 100644
--- a/net/reporting/reporting_header_parser.h
+++ b/net/reporting/reporting_header_parser.h
@@ -49,6 +49,7 @@
static void ProcessParsedReportingEndpointsHeader(
ReportingContext* context,
+ const base::UnguessableToken& reporting_source,
const NetworkIsolationKey& network_isolation_key,
const url::Origin& origin,
base::flat_map<std::string, std::string> parsed_header);
diff --git a/net/reporting/reporting_header_parser_unittest.cc b/net/reporting/reporting_header_parser_unittest.cc
index af7eaf7..29735e3 100644
--- a/net/reporting/reporting_header_parser_unittest.cc
+++ b/net/reporting/reporting_header_parser_unittest.cc
@@ -1778,7 +1778,8 @@
if (header_map) {
ReportingHeaderParser::ProcessParsedReportingEndpointsHeader(
- context(), network_isolation_key, origin, *header_map);
+ context(), base::UnguessableToken::Create(), network_isolation_key,
+ origin, *header_map);
}
}
};
diff --git a/net/reporting/reporting_network_change_observer_unittest.cc b/net/reporting/reporting_network_change_observer_unittest.cc
index f5ae0ce..cb7edca 100644
--- a/net/reporting/reporting_network_change_observer_unittest.cc
+++ b/net/reporting/reporting_network_change_observer_unittest.cc
@@ -7,12 +7,14 @@
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/simple_test_tick_clock.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
#include "net/base/network_change_notifier.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_report.h"
#include "net/reporting/reporting_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace net {
namespace {
@@ -43,6 +45,8 @@
return reports.size();
}
+ const absl::optional<base::UnguessableToken> kReportingSource_ =
+ absl::nullopt;
const NetworkIsolationKey kNik_;
const GURL kUrl_ = GURL("https://origin/path");
const url::Origin kOrigin_ = url::Origin::Create(kUrl_);
@@ -60,8 +64,8 @@
new_policy.persist_clients_across_network_changes = true;
UsePolicy(new_policy);
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetEndpoint();
ASSERT_EQ(1u, report_count());
@@ -79,8 +83,8 @@
new_policy.persist_clients_across_network_changes = true;
UsePolicy(new_policy);
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetEndpoint();
ASSERT_EQ(1u, report_count());
@@ -98,8 +102,8 @@
new_policy.persist_clients_across_network_changes = false;
UsePolicy(new_policy);
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetEndpoint();
ASSERT_EQ(1u, report_count());
@@ -117,8 +121,8 @@
new_policy.persist_clients_across_network_changes = false;
UsePolicy(new_policy);
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetEndpoint();
ASSERT_EQ(1u, report_count());
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc
index e32908f..477997ec 100644
--- a/net/reporting/reporting_service.cc
+++ b/net/reporting/reporting_service.cc
@@ -56,24 +56,31 @@
}
void SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) override {
- DoOrBacklogTask(base::BindOnce(
- &ReportingServiceImpl::DoSetDocumentReportingEndpoints,
- base::Unretained(this), FixupNetworkIsolationKey(network_isolation_key),
- origin, endpoints));
+ DCHECK(!reporting_source.is_empty());
+ DoOrBacklogTask(
+ base::BindOnce(&ReportingServiceImpl::DoSetDocumentReportingEndpoints,
+ base::Unretained(this), reporting_source,
+ FixupNetworkIsolationKey(network_isolation_key), origin,
+ std::move(endpoints)));
}
- void QueueReport(const GURL& url,
- const NetworkIsolationKey& network_isolation_key,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth) override {
+ void QueueReport(
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
+ const std::string& user_agent,
+ const std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body,
+ int depth) override {
DCHECK(context_);
DCHECK(context_->delegate());
+ // If |reporting_source| is provided, it must not be empty.
+ DCHECK(!(reporting_source.has_value() && reporting_source->is_empty()));
if (!context_->delegate()->CanQueueReport(url::Origin::Create(url)))
return;
@@ -89,7 +96,7 @@
// |task_backlog_| which will not outlive |this|.
DoOrBacklogTask(base::BindOnce(
&ReportingServiceImpl::DoQueueReport, base::Unretained(this),
- FixupNetworkIsolationKey(network_isolation_key),
+ reporting_source, FixupNetworkIsolationKey(network_isolation_key),
std::move(sanitized_url), user_agent, group, type, std::move(body),
depth, queued_ticks));
}
@@ -177,18 +184,20 @@
std::move(task).Run();
}
- void DoQueueReport(const NetworkIsolationKey& network_isolation_key,
- GURL sanitized_url,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth,
- base::TimeTicks queued_ticks) {
+ void DoQueueReport(
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
+ GURL sanitized_url,
+ const std::string& user_agent,
+ const std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body,
+ int depth,
+ base::TimeTicks queued_ticks) {
DCHECK(initialized_);
- context_->cache()->AddReport(network_isolation_key, sanitized_url,
- user_agent, group, type, std::move(body),
- depth, queued_ticks, 0 /* attempts */);
+ context_->cache()->AddReport(
+ reporting_source, network_isolation_key, sanitized_url, user_agent,
+ group, type, std::move(body), depth, queued_ticks, 0 /* attempts */);
}
void DoProcessReportToHeader(const NetworkIsolationKey& network_isolation_key,
@@ -200,12 +209,14 @@
}
void DoSetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const NetworkIsolationKey& network_isolation_key,
const url::Origin& origin,
base::flat_map<std::string, std::string> header_value) {
DCHECK(initialized_);
ReportingHeaderParser::ProcessParsedReportingEndpointsHeader(
- context_.get(), network_isolation_key, origin, std::move(header_value));
+ context_.get(), reporting_source, network_isolation_key, origin,
+ std::move(header_value));
}
void DoRemoveBrowsingData(
diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h
index f0d52d7..d273bf5 100644
--- a/net/reporting/reporting_service.h
+++ b/net/reporting/reporting_service.h
@@ -11,9 +11,11 @@
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
+#include "base/unguessable_token.h"
#include "net/base/net_export.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_cache_observer.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
class GURL;
@@ -50,21 +52,26 @@
std::unique_ptr<ReportingContext> reporting_context);
// Queues a report for delivery. |url| is the URL that originated the report.
- // |network_isolation_key| is used to restrict what reports can be merged, and
- // for sending the report.
+ // |reporting_source| is the reporting source token for the document or
+ // worker which triggered this report, if it can be associated with one, or
+ // nullopt otherwise. If present, it may not be empty.
+ // Along with |network_isolation_key|, it is used to restrict what reports
+ // can be merged, and for sending the report.
// |user_agent| is the User-Agent header that was used for the request.
// |group| is the endpoint group to which the report should be delivered.
// |type| is the type of the report. |body| is the body of the report.
//
// The Reporting system will take ownership of |body|; all other parameters
// will be copied.
- virtual void QueueReport(const GURL& url,
- const NetworkIsolationKey& network_isolation_key,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth) = 0;
+ virtual void QueueReport(
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
+ const std::string& user_agent,
+ const std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body,
+ int depth) = 0;
// Processes a Report-To header. |url| is the URL that originated the header;
// |header_value| is the normalized value of the Report-To header.
@@ -74,9 +81,19 @@
const std::string& header_value) = 0;
// Configures reporting endpoints set by the Reporting-Endpoints header, once
- // the associated document has been committed.
+ // the associated document or worker (represented by |reporting_source|) has
+ // been committed.
+ // |reporting_source| is the unique identifier for the resource with which
+ // this header was received, and must not be empty.
// |endpoints| is a mapping of endpoint names to URLs.
+ // |origin| is the origin of the reporting source, and
+ // |network_isolation_key| is the appropriate NIK for that source.
+ // (The isolation provided by Reporting-Endpoints is stronger than that
+ // provided by Report-To, so the origin and NIK aren't strictly necessary,
+ // but are currently required here because of shared infrastructure between
+ // the two versions of the reporting API.)
virtual void SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) = 0;
diff --git a/net/reporting/reporting_service_unittest.cc b/net/reporting/reporting_service_unittest.cc
index 3ce13d2d..ddb0a29b 100644
--- a/net/reporting/reporting_service_unittest.cc
+++ b/net/reporting/reporting_service_unittest.cc
@@ -27,6 +27,7 @@
#include "net/test/test_with_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -48,6 +49,8 @@
const std::string kUserAgent_ = "Mozilla/1.0";
const std::string kGroup_ = "group";
const std::string kType_ = "type";
+ const absl::optional<base::UnguessableToken> kReportingSource_ =
+ base::UnguessableToken::Create();
const NetworkIsolationKey kNik_ =
NetworkIsolationKey(SchemefulSite(kOrigin_), SchemefulSite(kOrigin_));
const NetworkIsolationKey kNik2_ =
@@ -100,8 +103,8 @@
};
TEST_P(ReportingServiceTest, QueueReport) {
- service()->QueueReport(kUrl_, kNik_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0);
+ service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0);
FinishLoading(true /* load_success */);
std::vector<const ReportingReport*> reports;
@@ -117,8 +120,8 @@
TEST_P(ReportingServiceTest, QueueReportSanitizeUrl) {
// Same as kUrl_ but with username, password, and fragment.
GURL url = GURL("https://username:password@origin/path#fragment");
- service()->QueueReport(url, kNik_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0);
+ service()->QueueReport(url, kReportingSource_, kNik_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0);
FinishLoading(true /* load_success */);
std::vector<const ReportingReport*> reports;
@@ -135,8 +138,8 @@
GURL url = GURL("https://");
// This does not trigger an attempt to load from the store because the url
// is immediately rejected as invalid.
- service()->QueueReport(url, kNik_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0);
+ service()->QueueReport(url, kReportingSource_, kNik_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0);
std::vector<const ReportingReport*> reports;
context()->cache()->GetReports(&reports);
@@ -151,8 +154,8 @@
// Re-create the store, so it reads the new feature value.
Init();
- service()->QueueReport(kUrl_, kNik_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0);
+ service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0);
FinishLoading(true /* load_success */);
std::vector<const ReportingReport*> reports;
@@ -191,7 +194,8 @@
auto parsed_header =
ParseReportingEndpoints(kGroup_ + "=\"" + kEndpoint_.spec() + "\"");
ASSERT_TRUE(parsed_header.has_value());
- service()->SetDocumentReportingEndpoints(kOrigin_, kNik_, *parsed_header);
+ service()->SetDocumentReportingEndpoints(*kReportingSource_, kOrigin_, kNik_,
+ *parsed_header);
FinishLoading(true /* load_success */);
EXPECT_EQ(1u, context()->cache()->GetEndpointCount());
@@ -204,7 +208,8 @@
feature_list.InitAndEnableFeature(net::features::kDocumentReporting);
auto parsed_header = ParseReportingEndpoints(kGroup_ + "=\"/path-absolute\"");
ASSERT_TRUE(parsed_header.has_value());
- service()->SetDocumentReportingEndpoints(kOrigin_, kNik_, *parsed_header);
+ service()->SetDocumentReportingEndpoints(*kReportingSource_, kOrigin_, kNik_,
+ *parsed_header);
FinishLoading(true /* load_success */);
EXPECT_EQ(1u, context()->cache()->GetEndpointCount());
@@ -326,8 +331,8 @@
EXPECT_THAT(store()->GetAllCommands(),
testing::UnorderedElementsAreArray(expected_commands));
- service()->QueueReport(kUrl_, kNik_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0);
+ service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0);
expected_commands.emplace_back(
CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME, kGroupKey_);
EXPECT_THAT(store()->GetAllCommands(),
@@ -387,8 +392,8 @@
EXPECT_THAT(store()->GetAllCommands(),
testing::UnorderedElementsAreArray(expected_commands));
- service()->QueueReport(kUrl_, kNik_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0);
+ service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
+ kType_, std::make_unique<base::DictionaryValue>(), 0);
EXPECT_THAT(store()->GetAllCommands(),
testing::UnorderedElementsAreArray(expected_commands));
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc
index 04b38610..887807e 100644
--- a/net/reporting/reporting_test_util.cc
+++ b/net/reporting/reporting_test_util.cc
@@ -317,6 +317,7 @@
void TestReportingService::QueueReport(
const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
const NetworkIsolationKey& network_isolation_key,
const std::string& user_agent,
const std::string& group,
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h
index d4b0cae..700a5c3 100644
--- a/net/reporting/reporting_test_util.h
+++ b/net/reporting/reporting_test_util.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/test/simple_test_clock.h"
#include "base/test/simple_test_tick_clock.h"
+#include "base/unguessable_token.h"
#include "net/base/network_isolation_key.h"
#include "net/base/rand_callback.h"
#include "net/reporting/reporting_cache.h"
@@ -23,6 +24,7 @@
#include "net/test/test_with_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
namespace base {
@@ -314,17 +316,20 @@
~TestReportingService() override;
void SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) override {}
- void QueueReport(const GURL& url,
- const NetworkIsolationKey& network_isolation_key,
- const std::string& user_agent,
- const std::string& group,
- const std::string& type,
- std::unique_ptr<const base::Value> body,
- int depth) override;
+ void QueueReport(
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const NetworkIsolationKey& network_isolation_key,
+ const std::string& user_agent,
+ const std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body,
+ int depth) override;
void ProcessReportToHeader(const GURL& url,
const NetworkIsolationKey& network_isolation_key,
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 57b5f7a..68f7eaf 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -933,14 +933,16 @@
}
void NetworkContext::SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) {
+ DCHECK(!reporting_source.is_empty());
net::ReportingService* reporting_service =
url_request_context()->reporting_service();
if (reporting_service) {
reporting_service->SetDocumentReportingEndpoints(
- origin, network_isolation_key, endpoints);
+ reporting_source, origin, network_isolation_key, endpoints);
}
}
@@ -948,9 +950,12 @@
const std::string& type,
const std::string& group,
const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
const net::NetworkIsolationKey& network_isolation_key,
const absl::optional<std::string>& user_agent,
base::Value body) {
+ // If |reporting_source| is provided, it must not be empty.
+ DCHECK(!(reporting_source.has_value() && reporting_source->is_empty()));
if (require_network_isolation_key_)
DCHECK(!network_isolation_key.IsEmpty());
@@ -975,8 +980,8 @@
}
reporting_service->QueueReport(
- url, network_isolation_key, reported_user_agent, group, type,
- base::Value::ToUniquePtrValue(std::move(body)), 0 /* depth */);
+ url, reporting_source, network_isolation_key, reported_user_agent, group,
+ type, base::Value::ToUniquePtrValue(std::move(body)), 0 /* depth */);
}
void NetworkContext::QueueSignedExchangeReport(
@@ -1105,6 +1110,7 @@
}
void NetworkContext::SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) {
@@ -1115,6 +1121,7 @@
const std::string& type,
const std::string& group,
const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
const net::NetworkIsolationKey& network_isolation_key,
const absl::optional<std::string>& user_agent,
base::Value body) {
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 6912997..79fa191 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -21,6 +21,7 @@
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "mojo/public/cpp/base/big_buffer.h"
@@ -407,15 +408,18 @@
void CreateMdnsResponder(
mojo::PendingReceiver<mojom::MdnsResponder> responder_receiver) override;
void SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) override;
- void QueueReport(const std::string& type,
- const std::string& group,
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- const absl::optional<std::string>& user_agent,
- base::Value body) override;
+ void QueueReport(
+ const std::string& type,
+ const std::string& group,
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const net::NetworkIsolationKey& network_isolation_key,
+ const absl::optional<std::string>& user_agent,
+ base::Value body) override;
void QueueSignedExchangeReport(
mojom::SignedExchangeReportPtr report,
const net::NetworkIsolationKey& network_isolation_key) override;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index b67657d..b61b27d 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -2139,8 +2139,9 @@
reporting_service.get());
GURL domain("http://google.com");
- reporting_service->QueueReport(domain, net::NetworkIsolationKey(),
- "Mozilla/1.0", "group", "type", nullptr, 0);
+ reporting_service->QueueReport(domain, absl::nullopt,
+ net::NetworkIsolationKey(), "Mozilla/1.0",
+ "group", "type", nullptr, 0);
std::vector<const net::ReportingReport*> reports;
reporting_cache->GetReports(&reports);
@@ -2169,11 +2170,13 @@
reporting_service.get());
GURL url1("http://google.com");
- reporting_service->QueueReport(url1, net::NetworkIsolationKey(),
- "Mozilla/1.0", "group", "type", nullptr, 0);
+ reporting_service->QueueReport(url1, absl::nullopt,
+ net::NetworkIsolationKey(), "Mozilla/1.0",
+ "group", "type", nullptr, 0);
GURL url2("http://chromium.org");
- reporting_service->QueueReport(url2, net::NetworkIsolationKey(),
- "Mozilla/1.0", "group", "type", nullptr, 0);
+ reporting_service->QueueReport(url2, absl::nullopt,
+ net::NetworkIsolationKey(), "Mozilla/1.0",
+ "group", "type", nullptr, 0);
std::vector<const net::ReportingReport*> reports;
reporting_cache->GetReports(&reports);
@@ -2208,11 +2211,13 @@
reporting_service.get());
GURL url1("http://192.168.0.1");
- reporting_service->QueueReport(url1, net::NetworkIsolationKey(),
- "Mozilla/1.0", "group", "type", nullptr, 0);
+ reporting_service->QueueReport(url1, absl::nullopt,
+ net::NetworkIsolationKey(), "Mozilla/1.0",
+ "group", "type", nullptr, 0);
GURL url2("http://192.168.0.2");
- reporting_service->QueueReport(url2, net::NetworkIsolationKey(),
- "Mozilla/1.0", "group", "type", nullptr, 0);
+ reporting_service->QueueReport(url2, absl::nullopt,
+ net::NetworkIsolationKey(), "Mozilla/1.0",
+ "group", "type", nullptr, 0);
std::vector<const net::ReportingReport*> reports;
reporting_cache->GetReports(&reports);
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index b51365f..ba3d678 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -919,35 +919,50 @@
// Configures per-resource reporting endpoints set with the
// Reporting-Endpoints header.
+ // |reporting_source| is a token which identifies the document or worker with
+ // which the header was received. The endpoints configured by this method are
+ // only used to deliver reports which are queued by that same source.
// |network_isolation_key| is used when creating the endpoints in the
// ReportingCache, and will need to match the key sent when reports are queued
- // in order for these reporting endpoints to be considered for delivery.
+ // in order for these reporting endpoints to be considered for delivery,
+ // although this should always be the case when reports are queued by the
+ // same source which configured the endpoints.
// |endpoints| is a mapping of endpoint name to URL (URLs here are represented
// as strings, and will be rejected if they fail to parse or are not secure).
//
// Spec: https://w3c.github.io/reporting/#header
SetDocumentReportingEndpoints(
+ mojo_base.mojom.UnguessableToken reporting_source,
url.mojom.Origin origin, NetworkIsolationKey network_isolation_key,
map<string,string> endpoints);
// Queues a report via the Reporting API. |type| describes the type of report
// (as well as what data will contained in |body|). |group| specifies the
// endpoint group that the report will be delivered to. |url| indicates the
- // URL of the resource that the report describes; |network_isolation_key|
- // indicates the NetworkIsolationKey associated with the request, and is
- // used for both looking up the appropriately scoped reporting information
- // and for sending the report. |user_agent| may be provided, or will be
- // automatically generated if omitted; |body| holds the contents of the
- // report.
+ // URL of the resource that the report describes. |user_agent| may be
+ // provided, or will be automatically generated if omitted; |body| holds the
+ // contents of the report.
+ //
+ // |reporting_source| and |network_isolation_key| are used both for looking
+ // up the appropriately scoped reporting information and for sending the
+ // report. |network_isolation_key| indicates the NetworkIsolationKey
+ // associated with the request, while |reporting_source|, if not empty,
+ // identifies the specific document or worker instance causing the report to
+ // be queued. If |reporting_source| is not empty, then it will be used to
+ // look up reporting endpoints set with the SetDocumentReportingEndpoints
+ // method first, and if no matching endpoint is found, it will fall back to
+ // looking up a matching endpoint group configured for the origin and
+ // |network_isolation_key|.
//
// Note that this queued report will never be delivered if no reporting
- // endpoint is registered for this |url| with the provided
- // |network_isolation_key|.
+ // endpoint is registered for this |url| or |reporting_source| with the
+ // provided |network_isolation_key|.
//
// Spec: https://w3c.github.io/reporting/#concept-reports
QueueReport(string type,
string group,
url.mojom.Url url,
+ mojo_base.mojom.UnguessableToken? reporting_source,
NetworkIsolationKey network_isolation_key,
string? user_agent,
mojo_base.mojom.DictionaryValue body);
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
index 09a53756..361add9 100644
--- a/services/network/test/test_network_context.h
+++ b/services/network/test/test_network_context.h
@@ -12,6 +12,7 @@
#include "base/component_export.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "build/chromeos_buildflags.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -110,15 +111,18 @@
void GetDomainReliabilityJSON(
GetDomainReliabilityJSONCallback callback) override {}
void SetDocumentReportingEndpoints(
+ const base::UnguessableToken& reporting_source,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
const base::flat_map<std::string, std::string>& endpoints) override {}
- void QueueReport(const std::string& type,
- const std::string& group,
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- const absl::optional<std::string>& user_agent,
- base::Value body) override {}
+ void QueueReport(
+ const std::string& type,
+ const std::string& group,
+ const GURL& url,
+ const absl::optional<base::UnguessableToken>& reporting_source,
+ const net::NetworkIsolationKey& network_isolation_key,
+ const absl::optional<std::string>& user_agent,
+ base::Value body) override {}
void QueueSignedExchangeReport(
mojom::SignedExchangeReportPtr report,
const net::NetworkIsolationKey& network_isolation_key) override {}