Reporting: Wrap context in service.
Reporting is a spec for delivering out-of-band reports from various
other parts of the browser. See http://wicg.github.io/reporting/ for
the spec, or https://goo.gl/pygX5I for details of the planned
implementation in Chromium.
This wraps the context in a service that keeps the implementation
details of Reporting private while implementing and exposing the
high-level operations that other components require from it.
BUG=704259
Review-Url: https://codereview.chromium.org/2770443002
Cr-Commit-Position: refs/heads/master@{#462943}
diff --git a/net/BUILD.gn b/net/BUILD.gn
index ab6d8e64..29528af 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1415,6 +1415,8 @@
"reporting/reporting_policy.h",
"reporting/reporting_report.cc",
"reporting/reporting_report.h",
+ "reporting/reporting_service.cc",
+ "reporting/reporting_service.h",
"reporting/reporting_uploader.cc",
"reporting/reporting_uploader.h",
"sdch/sdch_owner.cc",
@@ -4634,6 +4636,7 @@
"reporting/reporting_delivery_agent_unittest.cc",
"reporting/reporting_endpoint_manager_unittest.cc",
"reporting/reporting_header_parser_unittest.cc",
+ "reporting/reporting_service_unittest.cc",
"reporting/reporting_test_util.cc",
"reporting/reporting_test_util.h",
"reporting/reporting_uploader_unittest.cc",
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc
new file mode 100644
index 0000000..128c510
--- /dev/null
+++ b/net/reporting/reporting_service.cc
@@ -0,0 +1,70 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/reporting/reporting_service.h"
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/time/tick_clock.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "net/reporting/reporting_cache.h"
+#include "net/reporting/reporting_context.h"
+#include "net/reporting/reporting_delegate.h"
+#include "net/reporting/reporting_header_parser.h"
+#include "url/gurl.h"
+
+namespace net {
+
+namespace {
+
+class ReportingServiceImpl : public ReportingService {
+ public:
+ ReportingServiceImpl(std::unique_ptr<ReportingContext> context)
+ : context_(std::move(context)) {}
+
+ ~ReportingServiceImpl() override {}
+
+ void QueueReport(const GURL& url,
+ const std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body) override {
+ context_->cache()->AddReport(url, group, type, std::move(body),
+ context_->tick_clock()->NowTicks(), 0);
+ }
+
+ void ProcessHeader(const GURL& url,
+ const std::string& header_value) override {
+ ReportingHeaderParser::ParseHeader(context_.get(), url, header_value);
+ }
+
+ private:
+ std::unique_ptr<ReportingContext> context_;
+
+ DISALLOW_COPY_AND_ASSIGN(ReportingServiceImpl);
+};
+
+} // namespace
+
+ReportingService::~ReportingService() {}
+
+// static
+std::unique_ptr<ReportingService> ReportingService::Create(
+ const ReportingPolicy& policy,
+ URLRequestContext* request_context,
+ std::unique_ptr<ReportingDelegate> delegate) {
+ return base::MakeUnique<ReportingServiceImpl>(
+ ReportingContext::Create(policy, std::move(delegate), request_context));
+}
+
+// static
+std::unique_ptr<ReportingService> ReportingService::CreateForTesting(
+ std::unique_ptr<ReportingContext> reporting_context) {
+ return base::MakeUnique<ReportingServiceImpl>(std::move(reporting_context));
+}
+
+} // namespace net
diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h
new file mode 100644
index 0000000..c305410
--- /dev/null
+++ b/net/reporting/reporting_service.h
@@ -0,0 +1,74 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_REPORTING_REPORTING_SERVICE_H_
+#define NET_REPORTING_REPORTING_SERVICE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "net/base/net_export.h"
+
+class GURL;
+
+namespace base {
+class Value;
+} // namespace
+
+namespace net {
+
+class ReportingContext;
+class ReportingDelegate;
+struct ReportingPolicy;
+class URLRequestContext;
+
+// The external interface to the Reporting system, used by the embedder of //net
+// and also other parts of //net.
+class NET_EXPORT ReportingService {
+ public:
+ virtual ~ReportingService();
+
+ // Creates a ReportingService. |policy| will be copied. |request_context| must
+ // outlive the ReportingService. The ReportingService will take ownership of
+ // |delegate| and destroy it when the service is destroyed.
+ static std::unique_ptr<ReportingService> Create(
+ const ReportingPolicy& policy,
+ URLRequestContext* request_context,
+ std::unique_ptr<ReportingDelegate> delegate);
+
+ // Creates a ReportingService for testing purposes using an
+ // already-constructed ReportingContext. The ReportingService will take
+ // ownership of |reporting_context| and destroy it when the service is
+ // destroyed.
+ static std::unique_ptr<ReportingService> CreateForTesting(
+ std::unique_ptr<ReportingContext> reporting_context);
+
+ // Queues a report for delivery. |url| is the URL that originated the report.
+ // |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 std::string& group,
+ const std::string& type,
+ std::unique_ptr<const base::Value> body) = 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.
+ virtual void ProcessHeader(const GURL& url,
+ const std::string& header_value) = 0;
+
+ protected:
+ ReportingService() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ReportingService);
+};
+
+} // namespace net
+
+#endif // NET_REPORTING_REPORTING_SERVICE_H_
diff --git a/net/reporting/reporting_service_unittest.cc b/net/reporting/reporting_service_unittest.cc
new file mode 100644
index 0000000..20c8656
--- /dev/null
+++ b/net/reporting/reporting_service_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/reporting/reporting_service.h"
+
+#include <memory>
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "base/time/tick_clock.h"
+#include "base/values.h"
+#include "net/reporting/reporting_cache.h"
+#include "net/reporting/reporting_context.h"
+#include "net/reporting/reporting_delegate.h"
+#include "net/reporting/reporting_policy.h"
+#include "net/reporting/reporting_report.h"
+#include "net/reporting/reporting_service.h"
+#include "net/reporting/reporting_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+class ReportingServiceTest : public ::testing::Test {
+ protected:
+ const GURL kUrl_ = GURL("https://origin/path");
+ const url::Origin kOrigin_ = url::Origin(kUrl_);
+ const GURL kEndpoint_ = GURL("https://endpoint/");
+ const std::string kGroup_ = "group";
+ const std::string kType_ = "type";
+
+ ReportingServiceTest()
+ : context_(new TestReportingContext(ReportingPolicy())),
+ service_(
+ ReportingService::CreateForTesting(base::WrapUnique(context_))) {}
+
+ TestReportingContext* context() { return context_; }
+ ReportingService* service() { return service_.get(); }
+
+ private:
+ TestReportingContext* context_;
+ std::unique_ptr<ReportingService> service_;
+};
+
+TEST_F(ReportingServiceTest, QueueReport) {
+ service()->QueueReport(kUrl_, kGroup_, kType_,
+ base::MakeUnique<base::DictionaryValue>());
+
+ std::vector<const ReportingReport*> reports;
+ context()->cache()->GetReports(&reports);
+ ASSERT_EQ(1u, reports.size());
+ EXPECT_EQ(kUrl_, reports[0]->url);
+ EXPECT_EQ(kGroup_, reports[0]->group);
+ EXPECT_EQ(kType_, reports[0]->type);
+}
+
+TEST_F(ReportingServiceTest, ProcessHeader) {
+ service()->ProcessHeader(kUrl_, "{\"url\":\"" + kEndpoint_.spec() +
+ "\","
+ "\"group\":\"" +
+ kGroup_ +
+ "\","
+ "\"max-age\":86400}");
+
+ const ReportingClient* client =
+ FindClientInCache(context()->cache(), kOrigin_, kEndpoint_);
+ ASSERT_TRUE(client != nullptr);
+ EXPECT_EQ(kOrigin_, client->origin);
+ EXPECT_EQ(kEndpoint_, client->endpoint);
+ EXPECT_EQ(ReportingClient::Subdomains::EXCLUDE, client->subdomains);
+ EXPECT_EQ(kGroup_, client->group);
+ EXPECT_EQ(context()->tick_clock()->NowTicks() + base::TimeDelta::FromDays(1),
+ client->expires);
+}
+
+} // namespace
+} // namespace net