blob: 90176c275d1a95a54222e11e1682758f73887d5d [file] [log] [blame]
juliatuttle95fe3cc52017-06-30 23:05:311// 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
5#include "content/browser/net/reporting_service_proxy.h"
6
7#include <memory>
8#include <string>
9#include <utility>
10
11#include "base/memory/ref_counted.h"
12#include "base/values.h"
13#include "content/public/browser/browser_context.h"
14#include "content/public/browser/site_instance.h"
15#include "content/public/browser/storage_partition.h"
16#include "mojo/public/cpp/bindings/strong_binding.h"
juliatuttle667c0bb2017-07-06 15:17:1317#include "net/reporting/reporting_report.h"
juliatuttle95fe3cc52017-06-30 23:05:3118#include "net/reporting/reporting_service.h"
Douglas Creagerf6cb49f72018-07-19 20:14:5319#include "net/url_request/http_user_agent_settings.h"
juliatuttle95fe3cc52017-06-30 23:05:3120#include "net/url_request/url_request_context.h"
21#include "net/url_request/url_request_context_getter.h"
Blink Reformata30d4232018-04-07 15:31:0622#include "third_party/blink/public/platform/reporting.mojom.h"
juliatuttle95fe3cc52017-06-30 23:05:3123#include "url/gurl.h"
24
25namespace content {
26
27namespace {
28
Julia Tuttle6ae4dcb2017-09-08 21:41:2629class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy {
juliatuttle95fe3cc52017-06-30 23:05:3130 public:
31 ReportingServiceProxyImpl(
32 scoped_refptr<net::URLRequestContextGetter> request_context_getter)
33 : request_context_getter_(std::move(request_context_getter)) {}
34
Julia Tuttle6ae4dcb2017-09-08 21:41:2635 // blink::mojom::ReportingServiceProxy:
36
37 void QueueInterventionReport(const GURL& url,
38 const std::string& message,
Paul Meyered85628b2018-06-14 00:33:0739 const base::Optional<std::string>& source_file,
Paul Meyer152136f2017-11-30 16:36:1740 int line_number,
41 int column_number) override {
Julia Tuttle6ae4dcb2017-09-08 21:41:2642 auto body = std::make_unique<base::DictionaryValue>();
43 body->SetString("message", message);
Paul Meyered85628b2018-06-14 00:33:0744 if (source_file)
45 body->SetString("sourceFile", *source_file);
46 if (line_number)
47 body->SetInteger("lineNumber", line_number);
48 if (column_number)
49 body->SetInteger("columnNumber", column_number);
Julia Tuttle6ae4dcb2017-09-08 21:41:2650 QueueReport(url, "default", "intervention", std::move(body));
51 }
52
53 void QueueDeprecationReport(const GURL& url,
Paul Meyere5df6cff2017-12-05 00:28:2654 const std::string& id,
Paul Meyered85628b2018-06-14 00:33:0755 base::Optional<base::Time> anticipatedRemoval,
Julia Tuttle6ae4dcb2017-09-08 21:41:2656 const std::string& message,
Paul Meyered85628b2018-06-14 00:33:0757 const base::Optional<std::string>& source_file,
Paul Meyer152136f2017-11-30 16:36:1758 int line_number,
59 int column_number) override {
Julia Tuttle6ae4dcb2017-09-08 21:41:2660 auto body = std::make_unique<base::DictionaryValue>();
Paul Meyere5df6cff2017-12-05 00:28:2661 body->SetString("id", id);
Paul Meyered85628b2018-06-14 00:33:0762 if (anticipatedRemoval)
63 body->SetDouble("anticipatedRemoval", anticipatedRemoval->ToDoubleT());
Julia Tuttle6ae4dcb2017-09-08 21:41:2664 body->SetString("message", message);
Paul Meyered85628b2018-06-14 00:33:0765 if (source_file)
66 body->SetString("sourceFile", *source_file);
67 if (line_number)
68 body->SetInteger("lineNumber", line_number);
69 if (column_number)
70 body->SetInteger("columnNumber", column_number);
Julia Tuttle6ae4dcb2017-09-08 21:41:2671 QueueReport(url, "default", "deprecation", std::move(body));
72 }
73
Andy Paicuacb9f5c2017-10-27 06:49:4074 void QueueCspViolationReport(const GURL& url,
75 const std::string& group,
76 const std::string& document_uri,
77 const std::string& referrer,
78 const std::string& violated_directive,
79 const std::string& effective_directive,
80 const std::string& original_policy,
81 const std::string& disposition,
82 const std::string& blocked_uri,
83 int line_number,
84 int column_number,
Paul Meyered85628b2018-06-14 00:33:0785 const base::Optional<std::string>& source_file,
Andy Paicuacb9f5c2017-10-27 06:49:4086 int status_code,
87 const std::string& script_sample) override {
88 auto body = std::make_unique<base::DictionaryValue>();
89 body->SetString("document-uri", document_uri);
90 body->SetString("referrer", referrer);
91 body->SetString("violated-directive", violated_directive);
92 body->SetString("effective-directive", effective_directive);
93 body->SetString("original-policy", original_policy);
94 body->SetString("disposition", disposition);
95 body->SetString("blocked-uri", blocked_uri);
96 if (line_number)
97 body->SetInteger("line-number", line_number);
98 if (column_number)
99 body->SetInteger("column-number", column_number);
Paul Meyered85628b2018-06-14 00:33:07100 if (source_file)
101 body->SetString("sourceFile", *source_file);
Andy Paicuacb9f5c2017-10-27 06:49:40102 if (status_code)
103 body->SetInteger("status-code", status_code);
104 body->SetString("script-sample", script_sample);
105 QueueReport(url, group, "csp", std::move(body));
106 }
107
Ian Clellandcda7f212018-08-13 14:04:36108 void QueueFeaturePolicyViolationReport(
109 const GURL& url,
Ian Clellandaa5ddc82018-11-22 15:55:59110 const std::string& policy_id,
Ian Clellandf482e772018-11-14 16:42:47111 const std::string& disposition,
Ian Clellandaa5ddc82018-11-22 15:55:59112 const base::Optional<std::string>& message,
Ian Clellandcda7f212018-08-13 14:04:36113 const base::Optional<std::string>& source_file,
114 int line_number,
115 int column_number) override {
116 auto body = std::make_unique<base::DictionaryValue>();
Ian Clellandaa5ddc82018-11-22 15:55:59117 body->SetString("policyId", policy_id);
Ian Clellandf482e772018-11-14 16:42:47118 body->SetString("disposition", disposition);
Ian Clellandaa5ddc82018-11-22 15:55:59119 if (message)
120 body->SetString("message", *message);
Ian Clellandcda7f212018-08-13 14:04:36121 if (source_file)
122 body->SetString("sourceFile", *source_file);
123 if (line_number)
124 body->SetInteger("lineNumber", line_number);
125 if (column_number)
126 body->SetInteger("columnNumber", column_number);
Ian Clellandaa5ddc82018-11-22 15:55:59127 QueueReport(url, "default", "feature-policy-violation", std::move(body));
Ian Clellandcda7f212018-08-13 14:04:36128 }
129
Julia Tuttle6ae4dcb2017-09-08 21:41:26130 private:
juliatuttle95fe3cc52017-06-30 23:05:31131 void QueueReport(const GURL& url,
132 const std::string& group,
133 const std::string& type,
Julia Tuttle6ae4dcb2017-09-08 21:41:26134 std::unique_ptr<base::Value> body) {
juliatuttle95fe3cc52017-06-30 23:05:31135 net::URLRequestContext* request_context =
136 request_context_getter_->GetURLRequestContext();
juliatuttle667c0bb2017-07-06 15:17:13137 if (!request_context) {
138 net::ReportingReport::RecordReportDiscardedForNoURLRequestContext();
juliatuttle95fe3cc52017-06-30 23:05:31139 return;
juliatuttle667c0bb2017-07-06 15:17:13140 }
juliatuttle95fe3cc52017-06-30 23:05:31141
142 net::ReportingService* reporting_service =
143 request_context->reporting_service();
juliatuttle667c0bb2017-07-06 15:17:13144 if (!reporting_service) {
145 net::ReportingReport::RecordReportDiscardedForNoReportingService();
juliatuttle95fe3cc52017-06-30 23:05:31146 return;
juliatuttle667c0bb2017-07-06 15:17:13147 }
juliatuttle95fe3cc52017-06-30 23:05:31148
Julia Tuttle107e30672018-03-29 18:48:42149 // Depth is only non-zero for NEL reports, and those can't come from the
150 // renderer.
Douglas Creagerf6cb49f72018-07-19 20:14:53151 std::string user_agent;
152 if (request_context->http_user_agent_settings() != nullptr)
153 user_agent = request_context->http_user_agent_settings()->GetUserAgent();
154 reporting_service->QueueReport(url, user_agent, group, type,
155 std::move(body),
Julia Tuttle107e30672018-03-29 18:48:42156 /* depth= */ 0);
juliatuttle95fe3cc52017-06-30 23:05:31157 }
158
juliatuttle95fe3cc52017-06-30 23:05:31159 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
160};
161
162void CreateReportingServiceProxyOnNetworkTaskRunner(
Julia Tuttle6ae4dcb2017-09-08 21:41:26163 blink::mojom::ReportingServiceProxyRequest request,
juliatuttle95fe3cc52017-06-30 23:05:31164 scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
Julia Tuttle6ae4dcb2017-09-08 21:41:26165 mojo::MakeStrongBinding(std::make_unique<ReportingServiceProxyImpl>(
juliatuttle95fe3cc52017-06-30 23:05:31166 std::move(request_context_getter)),
167 std::move(request));
168}
169
170} // namespace
171
172// static
173void CreateReportingServiceProxy(
174 StoragePartition* storage_partition,
Julia Tuttle6ae4dcb2017-09-08 21:41:26175 blink::mojom::ReportingServiceProxyRequest request) {
juliatuttle95fe3cc52017-06-30 23:05:31176 scoped_refptr<net::URLRequestContextGetter> request_context_getter(
177 storage_partition->GetURLRequestContext());
178 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner(
179 request_context_getter->GetNetworkTaskRunner());
180 network_task_runner->PostTask(
181 FROM_HERE,
182 base::BindOnce(&CreateReportingServiceProxyOnNetworkTaskRunner,
183 std::move(request), std::move(request_context_getter)));
184}
185
186} // namespace content