Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: net/reporting/reporting_serializer.cc

Issue 2751883003: Reporting: Implement serializer. (Closed)
Patch Set: Move after Context CL Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
5 #include "net/reporting/reporting_serializer.h"
6
7 #include <vector>
8
9 #include "base/memory/ptr_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/time/clock.h"
12 #include "base/time/tick_clock.h"
13 #include "base/time/time.h"
14 #include "base/values.h"
15 #include "net/reporting/reporting_cache.h"
16 #include "net/reporting/reporting_client.h"
17 #include "net/reporting/reporting_context.h"
18 #include "net/reporting/reporting_policy.h"
19 #include "net/reporting/reporting_report.h"
20
21 namespace net {
22
23 namespace {
24
25 std::string SerializeTicks(base::TimeTicks time_ticks,
26 ReportingContext* context) {
27 base::Time time =
28 time_ticks - context->tick_clock()->NowTicks() + context->clock()->Now();
29 return base::Int64ToString(time.ToInternalValue());
30 }
31
32 bool DeserializeTicks(const std::string& serialized,
33 base::TimeTicks* time_ticks_out,
34 ReportingContext* context) {
35 int64_t internal;
36 if (!base::StringToInt64(serialized, &internal))
37 return false;
38
39 base::Time time = base::Time::FromInternalValue(internal);
40 *time_ticks_out =
41 time - context->clock()->Now() + context->tick_clock()->NowTicks();
42 return true;
43 }
44
45 std::unique_ptr<base::Value> SerializeReport(const ReportingReport& report,
46 ReportingContext* context) {
47 auto serialized = base::MakeUnique<base::DictionaryValue>();
48
49 serialized->SetString("url", report.url.spec());
50 serialized->SetString("group", report.group);
51 serialized->SetString("type", report.type);
52 serialized->Set("body", report.body->CreateDeepCopy());
53 serialized->SetString("queued", SerializeTicks(report.queued, context));
54 serialized->SetInteger("attempts", report.attempts);
55
56 return std::move(serialized);
57 }
58
59 bool DeserializeReport(const base::DictionaryValue& report,
60 ReportingContext* context) {
61 std::string url_string;
62 if (!report.GetString("url", &url_string))
63 return false;
64 GURL url(url_string);
65 if (!url.is_valid())
66 return false;
67
68 std::string group;
69 if (!report.GetString("group", &group))
70 return false;
shivanisha 2017/04/05 18:47:31 dcheck group is not empty. Also type and body belo
Julia Tuttle 2017/04/06 20:20:55 There's nothing actually disallowing those members
71
72 std::string type;
73 if (!report.GetString("type", &type))
74 return false;
75
76 const base::Value* body;
77 if (!report.Get("body", &body))
78 return false;
79
80 std::string queued_string;
81 if (!report.GetString("queued", &queued_string))
82 return false;
83 base::TimeTicks queued;
84 if (!DeserializeTicks(queued_string, &queued, context))
85 return false;
86
87 int attempts;
88 if (!report.GetInteger("attempts", &attempts))
89 return false;
90 if (attempts < 0)
91 return false;
92
93 context->cache()->AddReport(url, group, type, body->CreateDeepCopy(), queued,
94 attempts);
shivanisha 2017/04/05 18:47:31 I believe the invocation of this call will only be
Julia Tuttle 2017/04/06 20:20:55 Yeah, I'll check in DeserializeFromValue that ther
95 return true;
96 }
97
98 std::unique_ptr<base::Value> SerializeReports(ReportingContext* context) {
99 std::vector<const ReportingReport*> reports;
100 context->cache()->GetReports(&reports);
101
102 auto serialized = base::MakeUnique<base::ListValue>();
103 for (const ReportingReport* report : reports)
104 serialized->Append(SerializeReport(*report, context));
105
106 return std::move(serialized);
107 }
108
109 bool DeserializeReports(const base::ListValue& reports,
110 ReportingContext* context) {
111 for (size_t i = 0; i < reports.GetSize(); ++i) {
112 const base::DictionaryValue* report;
113 if (!reports.GetDictionary(i, &report))
114 return false;
115 if (!DeserializeReport(*report, context))
116 return false;
117 }
118
119 return true;
120 }
121
122 std::unique_ptr<base::Value> SerializeOrigin(const url::Origin& origin) {
123 auto serialized = base::MakeUnique<base::DictionaryValue>();
124
125 serialized->SetString("scheme", origin.scheme());
126 serialized->SetString("host", origin.host());
127 serialized->SetInteger("port", origin.port());
128 serialized->SetString("suborigin", origin.suborigin());
129
130 return std::move(serialized);
131 }
132
133 bool DeserializeOrigin(const base::DictionaryValue& serialized,
134 url::Origin* origin_out) {
135 std::string scheme;
136 if (!serialized.GetString("scheme", &scheme))
137 return false;
138
139 std::string host;
140 if (!serialized.GetString("host", &host))
141 return false;
142
143 int port_int;
144 if (!serialized.GetInteger("port", &port_int))
145 return false;
146 uint16_t port = static_cast<uint16_t>(port_int);
147 if (port_int != port)
148 return false;
149
150 std::string suborigin;
151 if (!serialized.GetString("suborigin", &suborigin))
152 return false;
153
154 *origin_out = url::Origin::CreateFromNormalizedTupleWithSuborigin(
155 scheme, host, port, suborigin);
156 return true;
157 }
158
159 std::unique_ptr<base::Value> SerializeClient(const ReportingClient& client,
160 ReportingContext* context) {
161 auto serialized = base::MakeUnique<base::DictionaryValue>();
162
163 serialized->Set("origin", SerializeOrigin(client.origin));
164 serialized->SetString("endpoint", client.endpoint.spec());
165 serialized->SetBoolean(
166 "subdomains", client.subdomains == ReportingClient::Subdomains::INCLUDE);
167 serialized->SetString("group", client.group);
168 serialized->SetString("expires", SerializeTicks(client.expires, context));
169
170 return std::move(serialized);
171 }
172
173 bool DeserializeClient(const base::DictionaryValue& client,
174 ReportingContext* context) {
175 const base::DictionaryValue* origin_value;
176 if (!client.GetDictionary("origin", &origin_value))
177 return false;
178 url::Origin origin;
179 if (!DeserializeOrigin(*origin_value, &origin))
180 return false;
181
182 std::string endpoint_string;
183 if (!client.GetString("endpoint", &endpoint_string))
184 return false;
185 GURL endpoint(endpoint_string);
186 if (!endpoint.is_valid())
187 return false;
188
189 bool subdomains_bool;
190 if (!client.GetBoolean("subdomains", &subdomains_bool))
191 return false;
192 ReportingClient::Subdomains subdomains =
193 subdomains_bool ? ReportingClient::Subdomains::INCLUDE
194 : ReportingClient::Subdomains::EXCLUDE;
195
196 std::string group;
197 if (!client.GetString("group", &group))
198 return false;
199
200 std::string expires_string;
201 if (!client.GetString("expires", &expires_string))
202 return false;
203 base::TimeTicks expires;
204 if (!DeserializeTicks(expires_string, &expires, context))
205 return false;
206
207 context->cache()->SetClient(origin, endpoint, subdomains, group, expires);
208 return true;
209 }
210
211 std::unique_ptr<base::Value> SerializeClients(ReportingContext* context) {
212 std::vector<const ReportingClient*> clients;
213 context->cache()->GetClients(&clients);
214
215 auto serialized = base::MakeUnique<base::ListValue>();
216 for (const ReportingClient* client : clients)
217 serialized->Append(SerializeClient(*client, context));
218
219 return std::move(serialized);
220 }
221
222 bool DeserializeClients(const base::ListValue& clients,
223 ReportingContext* context) {
224 for (size_t i = 0; i < clients.GetSize(); ++i) {
225 const base::DictionaryValue* client;
226 if (!clients.GetDictionary(i, &client))
227 return false;
228 if (!DeserializeClient(*client, context))
229 return false;
230 }
231
232 return true;
233 }
234
235 } // namespace
236
237 // static
238 std::unique_ptr<base::Value> ReportingSerializer::SerializeToValue(
239 ReportingContext* context) {
240 auto serialized = base::MakeUnique<base::DictionaryValue>();
241
242 serialized->SetInteger("reporting_serialized_cache_version", 1);
shivanisha 2017/04/05 18:47:31 May be have a static const as the version instead
Julia Tuttle 2017/04/06 20:20:55 Done.
243
244 bool persist_reports = context->policy().persist_reports_across_restarts;
245 serialized->SetBoolean("includes_reports", persist_reports);
246 if (persist_reports)
247 serialized->Set("reports", SerializeReports(context));
248
249 bool persist_clients = context->policy().persist_clients_across_restarts;
250 serialized->SetBoolean("includes_clients", persist_clients);
251 if (persist_clients)
252 serialized->Set("clients", SerializeClients(context));
253
254 return std::move(serialized);
255 }
256
257 // static
258 bool ReportingSerializer::DeserializeFromValue(
259 const base::Value& serialized_value,
260 ReportingContext* context) {
261 int version;
262
263 const base::DictionaryValue* serialized;
264 if (!serialized_value.GetAsDictionary(&serialized))
265 return false;
266
267 if (!serialized->GetInteger("reporting_serialized_cache_version", &version))
268 return false;
269 if (version != 1)
270 return false;
271
272 bool includes_reports;
273 bool includes_clients;
274 if (!serialized->GetBoolean("includes_reports", &includes_reports) ||
275 !serialized->GetBoolean("includes_clients", &includes_clients)) {
276 return false;
277 }
278
shivanisha 2017/04/05 18:47:31 DCHECK that the cache does not contain any reports
Julia Tuttle 2017/04/06 20:20:55 Done.
279 if (includes_reports) {
280 const base::ListValue* reports;
281 if (!serialized->GetList("reports", &reports))
282 return false;
283 if (!DeserializeReports(*reports, context))
284 return false;
285 }
286
287 if (includes_clients) {
288 const base::ListValue* clients;
289 if (!serialized->GetList("clients", &clients))
290 return false;
291 if (!DeserializeClients(*clients, context))
292 return false;
293 }
294
295 return true;
296 }
297
298 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698