reporting_service.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/reporting/reporting_service.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/feature_list.h"
  8. #include "base/json/json_reader.h"
  9. #include "base/logging.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/time/tick_clock.h"
  12. #include "base/time/time.h"
  13. #include "base/values.h"
  14. #include "net/base/features.h"
  15. #include "net/base/isolation_info.h"
  16. #include "net/http/structured_headers.h"
  17. #include "net/reporting/reporting_browsing_data_remover.h"
  18. #include "net/reporting/reporting_cache.h"
  19. #include "net/reporting/reporting_context.h"
  20. #include "net/reporting/reporting_delegate.h"
  21. #include "net/reporting/reporting_delivery_agent.h"
  22. #include "net/reporting/reporting_header_parser.h"
  23. #include "net/reporting/reporting_uploader.h"
  24. #include "third_party/abseil-cpp/absl/types/optional.h"
  25. #include "url/gurl.h"
  26. #include "url/origin.h"
  27. namespace net {
  28. namespace {
  29. constexpr int kMaxJsonSize = 16 * 1024;
  30. constexpr int kMaxJsonDepth = 5;
  31. // If constructed with a PersistentReportingStore, the first call to any of
  32. // QueueReport(), ProcessHeader(), RemoveBrowsingData(), or
  33. // RemoveAllBrowsingData() on a valid input will trigger a load from the store.
  34. // Tasks are queued pending completion of loading from the store.
  35. class ReportingServiceImpl : public ReportingService {
  36. public:
  37. explicit ReportingServiceImpl(std::unique_ptr<ReportingContext> context)
  38. : context_(std::move(context)) {
  39. if (!context_->IsClientDataPersisted())
  40. initialized_ = true;
  41. }
  42. ReportingServiceImpl(const ReportingServiceImpl&) = delete;
  43. ReportingServiceImpl& operator=(const ReportingServiceImpl&) = delete;
  44. // ReportingService implementation:
  45. ~ReportingServiceImpl() override {
  46. if (initialized_)
  47. context_->cache()->Flush();
  48. }
  49. void SetDocumentReportingEndpoints(
  50. const base::UnguessableToken& reporting_source,
  51. const url::Origin& origin,
  52. const IsolationInfo& isolation_info,
  53. const base::flat_map<std::string, std::string>& endpoints) override {
  54. DCHECK(!reporting_source.is_empty());
  55. DoOrBacklogTask(base::BindOnce(
  56. &ReportingServiceImpl::DoSetDocumentReportingEndpoints,
  57. base::Unretained(this), reporting_source, isolation_info,
  58. FixupNetworkIsolationKey(isolation_info.network_isolation_key()),
  59. origin, std::move(endpoints)));
  60. }
  61. void SendReportsAndRemoveSource(
  62. const base::UnguessableToken& reporting_source) override {
  63. DCHECK(!reporting_source.is_empty());
  64. context_->delivery_agent()->SendReportsForSource(reporting_source);
  65. context_->cache()->SetExpiredSource(reporting_source);
  66. }
  67. void QueueReport(
  68. const GURL& url,
  69. const absl::optional<base::UnguessableToken>& reporting_source,
  70. const NetworkIsolationKey& network_isolation_key,
  71. const std::string& user_agent,
  72. const std::string& group,
  73. const std::string& type,
  74. base::Value::Dict body,
  75. int depth) override {
  76. DCHECK(context_);
  77. DCHECK(context_->delegate());
  78. // If |reporting_source| is provided, it must not be empty.
  79. DCHECK(!(reporting_source.has_value() && reporting_source->is_empty()));
  80. if (!context_->delegate()->CanQueueReport(url::Origin::Create(url)))
  81. return;
  82. // Strip username, password, and ref fragment from the URL.
  83. GURL sanitized_url = url.GetAsReferrer();
  84. if (!sanitized_url.is_valid())
  85. return;
  86. base::TimeTicks queued_ticks = context_->tick_clock().NowTicks();
  87. // base::Unretained is safe because the callback is stored in
  88. // |task_backlog_| which will not outlive |this|.
  89. DoOrBacklogTask(base::BindOnce(
  90. &ReportingServiceImpl::DoQueueReport, base::Unretained(this),
  91. reporting_source, FixupNetworkIsolationKey(network_isolation_key),
  92. std::move(sanitized_url), user_agent, group, type, std::move(body),
  93. depth, queued_ticks));
  94. }
  95. void ProcessReportToHeader(const url::Origin& origin,
  96. const NetworkIsolationKey& network_isolation_key,
  97. const std::string& header_string) override {
  98. if (header_string.size() > kMaxJsonSize)
  99. return;
  100. absl::optional<base::Value> header_value = base::JSONReader::Read(
  101. "[" + header_string + "]", base::JSON_PARSE_RFC, kMaxJsonDepth);
  102. if (!header_value)
  103. return;
  104. DVLOG(1) << "Received Reporting policy for " << origin;
  105. DoOrBacklogTask(base::BindOnce(
  106. &ReportingServiceImpl::DoProcessReportToHeader, base::Unretained(this),
  107. FixupNetworkIsolationKey(network_isolation_key), origin,
  108. std::move(header_value).value()));
  109. }
  110. void RemoveBrowsingData(
  111. uint64_t data_type_mask,
  112. const base::RepeatingCallback<bool(const url::Origin&)>& origin_filter)
  113. override {
  114. DoOrBacklogTask(base::BindOnce(&ReportingServiceImpl::DoRemoveBrowsingData,
  115. base::Unretained(this), data_type_mask,
  116. origin_filter));
  117. }
  118. void RemoveAllBrowsingData(uint64_t data_type_mask) override {
  119. DoOrBacklogTask(
  120. base::BindOnce(&ReportingServiceImpl::DoRemoveAllBrowsingData,
  121. base::Unretained(this), data_type_mask));
  122. }
  123. void OnShutdown() override {
  124. shut_down_ = true;
  125. context_->OnShutdown();
  126. }
  127. const ReportingPolicy& GetPolicy() const override {
  128. return context_->policy();
  129. }
  130. base::Value StatusAsValue() const override {
  131. base::Value::Dict dict;
  132. dict.Set("reportingEnabled", true);
  133. dict.Set("clients", context_->cache()->GetClientsAsValue());
  134. dict.Set("reports", context_->cache()->GetReportsAsValue());
  135. return base::Value(std::move(dict));
  136. }
  137. std::vector<const ReportingReport*> GetReports() const override {
  138. std::vector<const net::ReportingReport*> reports;
  139. context_->cache()->GetReports(&reports);
  140. return reports;
  141. }
  142. base::flat_map<url::Origin, std::vector<ReportingEndpoint>>
  143. GetV1ReportingEndpointsByOrigin() const override {
  144. return context_->cache()->GetV1ReportingEndpointsByOrigin();
  145. }
  146. void AddReportingCacheObserver(ReportingCacheObserver* observer) override {
  147. context_->AddCacheObserver(observer);
  148. }
  149. void RemoveReportingCacheObserver(ReportingCacheObserver* observer) override {
  150. context_->RemoveCacheObserver(observer);
  151. }
  152. ReportingContext* GetContextForTesting() const override {
  153. return context_.get();
  154. }
  155. private:
  156. void DoOrBacklogTask(base::OnceClosure task) {
  157. if (shut_down_)
  158. return;
  159. FetchAllClientsFromStoreIfNecessary();
  160. if (!initialized_) {
  161. task_backlog_.push_back(std::move(task));
  162. return;
  163. }
  164. std::move(task).Run();
  165. }
  166. void DoQueueReport(
  167. const absl::optional<base::UnguessableToken>& reporting_source,
  168. const NetworkIsolationKey& network_isolation_key,
  169. GURL sanitized_url,
  170. const std::string& user_agent,
  171. const std::string& group,
  172. const std::string& type,
  173. base::Value::Dict body,
  174. int depth,
  175. base::TimeTicks queued_ticks) {
  176. DCHECK(initialized_);
  177. context_->cache()->AddReport(
  178. reporting_source, network_isolation_key, sanitized_url, user_agent,
  179. group, type, std::move(body), depth, queued_ticks, 0 /* attempts */);
  180. }
  181. void DoProcessReportToHeader(const NetworkIsolationKey& network_isolation_key,
  182. const url::Origin& origin,
  183. const base::Value& header_value) {
  184. DCHECK(initialized_);
  185. DCHECK(header_value.is_list());
  186. ReportingHeaderParser::ParseReportToHeader(
  187. context_.get(), network_isolation_key, origin, header_value.GetList());
  188. }
  189. void DoSetDocumentReportingEndpoints(
  190. const base::UnguessableToken& reporting_source,
  191. const IsolationInfo& isolation_info,
  192. const NetworkIsolationKey& network_isolation_key,
  193. const url::Origin& origin,
  194. base::flat_map<std::string, std::string> header_value) {
  195. DCHECK(initialized_);
  196. ReportingHeaderParser::ProcessParsedReportingEndpointsHeader(
  197. context_.get(), reporting_source, isolation_info, network_isolation_key,
  198. origin, std::move(header_value));
  199. }
  200. void DoRemoveBrowsingData(
  201. uint64_t data_type_mask,
  202. const base::RepeatingCallback<bool(const url::Origin&)>& origin_filter) {
  203. DCHECK(initialized_);
  204. ReportingBrowsingDataRemover::RemoveBrowsingData(
  205. context_->cache(), data_type_mask, origin_filter);
  206. }
  207. void DoRemoveAllBrowsingData(uint64_t data_type_mask) {
  208. DCHECK(initialized_);
  209. ReportingBrowsingDataRemover::RemoveAllBrowsingData(context_->cache(),
  210. data_type_mask);
  211. }
  212. void ExecuteBacklog() {
  213. DCHECK(initialized_);
  214. DCHECK(context_);
  215. if (shut_down_)
  216. return;
  217. for (base::OnceClosure& task : task_backlog_) {
  218. std::move(task).Run();
  219. }
  220. task_backlog_.clear();
  221. }
  222. void FetchAllClientsFromStoreIfNecessary() {
  223. if (!context_->IsClientDataPersisted() || started_loading_from_store_)
  224. return;
  225. started_loading_from_store_ = true;
  226. FetchAllClientsFromStore();
  227. }
  228. void FetchAllClientsFromStore() {
  229. DCHECK(context_->IsClientDataPersisted());
  230. DCHECK(!initialized_);
  231. context_->store()->LoadReportingClients(base::BindOnce(
  232. &ReportingServiceImpl::OnClientsLoaded, weak_factory_.GetWeakPtr()));
  233. }
  234. void OnClientsLoaded(
  235. std::vector<ReportingEndpoint> loaded_endpoints,
  236. std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups) {
  237. initialized_ = true;
  238. context_->cache()->AddClientsLoadedFromStore(
  239. std::move(loaded_endpoints), std::move(loaded_endpoint_groups));
  240. ExecuteBacklog();
  241. }
  242. // Returns either |network_isolation_key| or an empty NetworkIsolationKey,
  243. // based on |respect_network_isolation_key_|. Should be used on all
  244. // NetworkIsolationKeys passed in through public API calls.
  245. const NetworkIsolationKey& FixupNetworkIsolationKey(
  246. const NetworkIsolationKey& network_isolation_key) {
  247. if (respect_network_isolation_key_)
  248. return network_isolation_key;
  249. return empty_nik_;
  250. }
  251. std::unique_ptr<ReportingContext> context_;
  252. bool shut_down_ = false;
  253. bool started_loading_from_store_ = false;
  254. bool initialized_ = false;
  255. std::vector<base::OnceClosure> task_backlog_;
  256. bool respect_network_isolation_key_ = base::FeatureList::IsEnabled(
  257. features::kPartitionNelAndReportingByNetworkIsolationKey);
  258. // Allows returning a NetworkIsolationKey by reference when
  259. // |respect_network_isolation_key_| is false.
  260. NetworkIsolationKey empty_nik_;
  261. base::WeakPtrFactory<ReportingServiceImpl> weak_factory_{this};
  262. };
  263. } // namespace
  264. ReportingService::~ReportingService() = default;
  265. // static
  266. std::unique_ptr<ReportingService> ReportingService::Create(
  267. const ReportingPolicy& policy,
  268. URLRequestContext* request_context,
  269. ReportingCache::PersistentReportingStore* store) {
  270. return std::make_unique<ReportingServiceImpl>(
  271. ReportingContext::Create(policy, request_context, store));
  272. }
  273. // static
  274. std::unique_ptr<ReportingService> ReportingService::CreateForTesting(
  275. std::unique_ptr<ReportingContext> reporting_context) {
  276. return std::make_unique<ReportingServiceImpl>(std::move(reporting_context));
  277. }
  278. base::Value ReportingService::StatusAsValue() const {
  279. NOTIMPLEMENTED();
  280. return base::Value();
  281. }
  282. } // namespace net