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

Side by Side Diff: components/domain_reliability/context.cc

Issue 252613002: Domain Reliability: More security review. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix one unittest Created 6 years, 7 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/domain_reliability/context.h" 5 #include "components/domain_reliability/context.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h" 13 #include "base/metrics/sparse_histogram.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "components/domain_reliability/beacon.h"
15 #include "components/domain_reliability/dispatcher.h" 16 #include "components/domain_reliability/dispatcher.h"
16 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
17 #include "net/url_request/url_request_context_getter.h" 18 #include "net/url_request/url_request_context_getter.h"
18 19
19 using base::DictionaryValue; 20 using base::DictionaryValue;
20 using base::ListValue; 21 using base::ListValue;
21 using base::Value; 22 using base::Value;
22 23
23 namespace domain_reliability { 24 namespace domain_reliability {
24 25
25 namespace { 26 namespace {
26 const char* kReporter = "chrome";
27 typedef std::deque<DomainReliabilityBeacon> BeaconDeque; 27 typedef std::deque<DomainReliabilityBeacon> BeaconDeque;
28 typedef BeaconDeque::iterator BeaconIterator; 28 typedef BeaconDeque::iterator BeaconIterator;
29 typedef BeaconDeque::const_iterator BeaconConstIterator; 29 typedef BeaconDeque::const_iterator BeaconConstIterator;
30 } // namespace 30 } // namespace
31 31
32 const int DomainReliabilityContext::kMaxQueuedBeacons = 150; 32 class DomainReliabilityContext::ResourceState {
33 public:
34 ResourceState(DomainReliabilityContext* context,
35 const DomainReliabilityConfig::Resource* config)
36 : context(context),
37 config(config),
38 successful_requests(0),
39 failed_requests(0) {}
40 ~ResourceState() {}
41
42 scoped_ptr<base::Value> ToValue(base::TimeTicks upload_time) const {
43 ListValue* beacons_value = new ListValue();
44 for (BeaconConstIterator it = beacons.begin(); it != beacons.end(); ++it)
45 beacons_value->Append(it->ToValue(upload_time));
46
47 DictionaryValue* resource_value = new DictionaryValue();
48 resource_value->SetString("resource_name", config->name);
49 resource_value->SetInteger("successful_requests", successful_requests);
50 resource_value->SetInteger("failed_requests", failed_requests);
Ryan Sleevi 2014/04/30 23:58:11 Doesn't this imply that successful/failed should b
Deprecated (see juliatuttle) 2014/05/02 19:23:40 Done.
51 resource_value->Set("beacons", beacons_value);
52
53 return scoped_ptr<Value>(resource_value);
54 }
55
56 // Remembers the current state of the resource data when an upload starts.
57 void MarkUpload() {
58 uploading_beacons_size = beacons.size();
59 uploading_successful_requests = successful_requests;
60 uploading_failed_requests = failed_requests;
61 }
62
63 // Uses the state remembered by |MarkUpload| to remove successfully uploaded
64 // data but keep beacons and request counts added after the upload started.
65 void CommitUpload() {
66 BeaconIterator begin = beacons.begin();
67 BeaconIterator end = begin + uploading_beacons_size;
68 beacons.erase(begin, end);
69 successful_requests -= uploading_successful_requests;
70 failed_requests -= uploading_failed_requests;
71 }
72
73 // Gets the start time of the oldest beacon, if there are any. Returns true
74 // and sets |oldest_start_out| if so; otherwise, returns false.
75 bool GetOldestBeaconStart(base::TimeTicks* oldest_start_out) const {
76 if (beacons.empty())
77 return false;
78 *oldest_start_out = beacons[0].start_time;
79 return true;
80 }
81
82 // Removes the oldest beacon. DCHECKs if there isn't one.
83 void RemoveOldestBeacon() {
84 DCHECK(!beacons.empty());
85 beacons.erase(beacons.begin());
86 // If that just removed a beacon counted in uploading_beacons_size,
87 // decrement
88 // that.
89 if (uploading_beacons_size > 0)
90 --uploading_beacons_size;
91 }
92
93 DomainReliabilityContext* context;
94 const DomainReliabilityConfig::Resource* config;
95
96 std::deque<DomainReliabilityBeacon> beacons;
97 unsigned successful_requests;
98 unsigned failed_requests;
99
100 // State saved during uploads; if an upload succeeds, these are used to
101 // remove uploaded data from the beacon list and request counters.
102 size_t uploading_beacons_size;
103 unsigned uploading_successful_requests;
104 unsigned uploading_failed_requests;
105
106 private:
107 DISALLOW_COPY_AND_ASSIGN(ResourceState);
108 };
109
110 // static
111 const size_t DomainReliabilityContext::kMaxQueuedBeacons = 150;
33 112
34 DomainReliabilityContext::DomainReliabilityContext( 113 DomainReliabilityContext::DomainReliabilityContext(
35 MockableTime* time, 114 MockableTime* time,
36 const DomainReliabilityScheduler::Params& scheduler_params, 115 const DomainReliabilityScheduler::Params& scheduler_params,
116 const char* upload_reporter_string,
37 DomainReliabilityDispatcher* dispatcher, 117 DomainReliabilityDispatcher* dispatcher,
38 DomainReliabilityUploader* uploader, 118 DomainReliabilityUploader* uploader,
39 scoped_ptr<const DomainReliabilityConfig> config) 119 scoped_ptr<const DomainReliabilityConfig> config)
40 : config_(config.Pass()), 120 : config_(config.Pass()),
41 time_(time), 121 time_(time),
42 scheduler_(time, config_->collectors.size(), scheduler_params, 122 upload_reporter_string_(upload_reporter_string),
123 scheduler_(time,
124 config_->collectors.size(),
125 scheduler_params,
43 base::Bind(&DomainReliabilityContext::ScheduleUpload, 126 base::Bind(&DomainReliabilityContext::ScheduleUpload,
44 base::Unretained(this))), 127 base::Unretained(this))),
45 dispatcher_(dispatcher), 128 dispatcher_(dispatcher),
46 uploader_(uploader), 129 uploader_(uploader),
47 beacon_count_(0), 130 beacon_count_(0),
48 weak_factory_(this) { 131 weak_factory_(this) {
49 InitializeResourceStates(); 132 InitializeResourceStates();
50 } 133 }
51 134
52 DomainReliabilityContext::~DomainReliabilityContext() {} 135 DomainReliabilityContext::~DomainReliabilityContext() {}
53 136
54 void DomainReliabilityContext::AddBeacon( 137 void DomainReliabilityContext::OnBeacon(const GURL& url,
55 const DomainReliabilityBeacon& beacon, 138 const DomainReliabilityBeacon& beacon) {
56 const GURL& url) { 139 size_t index = config_->GetResourceIndexForUrl(url);
57 int index = config_->GetResourceIndexForUrl(url); 140 if (index == DomainReliabilityConfig::kInvalidResourceIndex)
58 if (index < 0)
59 return; 141 return;
60 DCHECK_GT(states_.size(), static_cast<size_t>(index)); 142 DCHECK_GT(states_.size(), index);
61 143
62 ResourceState* state = states_[index]; 144 ResourceState* state = states_[index];
63 bool success = beacon.http_response_code >= 200 && 145 bool success = beacon.http_response_code >= 200 &&
64 beacon.http_response_code < 400; 146 beacon.http_response_code < 400;
65 if (success) 147 if (success)
66 ++state->successful_requests; 148 ++state->successful_requests;
67 else 149 else
68 ++state->failed_requests; 150 ++state->failed_requests;
69 151
70 VLOG(1) << "Received Beacon: " 152 VLOG(1) << "Received Beacon: "
(...skipping 14 matching lines...) Expand all
85 evicted = true; 167 evicted = true;
86 } 168 }
87 scheduler_.OnBeaconAdded(); 169 scheduler_.OnBeaconAdded();
88 reported = true; 170 reported = true;
89 UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.ReportedBeaconError", 171 UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.ReportedBeaconError",
90 -beacon.chrome_error); 172 -beacon.chrome_error);
91 // TODO(ttuttle): Histogram HTTP response code? 173 // TODO(ttuttle): Histogram HTTP response code?
92 } 174 }
93 175
94 UMA_HISTOGRAM_BOOLEAN("DomainReliability.BeaconReported", reported); 176 UMA_HISTOGRAM_BOOLEAN("DomainReliability.BeaconReported", reported);
95 UMA_HISTOGRAM_BOOLEAN("DomainReliability.AddBeaconDidEvict", evicted); 177 UMA_HISTOGRAM_BOOLEAN("DomainReliability.OnBeaconDidEvict", evicted);
96 } 178 }
97 179
98 void DomainReliabilityContext::GetQueuedDataForTesting( 180 void DomainReliabilityContext::GetQueuedDataForTesting(
99 int resource_index, 181 size_t resource_index,
100 std::vector<DomainReliabilityBeacon>* beacons_out, 182 std::vector<DomainReliabilityBeacon>* beacons_out,
101 int* successful_requests_out, 183 unsigned* successful_requests_out,
102 int* failed_requests_out) const { 184 unsigned* failed_requests_out) const {
103 DCHECK_LE(0, resource_index); 185 DCHECK_NE(DomainReliabilityConfig::kInvalidResourceIndex, resource_index);
104 DCHECK_GT(static_cast<int>(states_.size()), resource_index); 186 DCHECK_GT(states_.size(), resource_index);
105 const ResourceState& state = *states_[resource_index]; 187 const ResourceState& state = *states_[resource_index];
106 if (beacons_out) { 188 if (beacons_out)
107 beacons_out->resize(state.beacons.size()); 189 beacons_out->assign(state.beacons.begin(), state.beacons.end());
108 std::copy(state.beacons.begin(), state.beacons.end(), beacons_out->begin());
109 }
110 if (successful_requests_out) 190 if (successful_requests_out)
111 *successful_requests_out = state.successful_requests; 191 *successful_requests_out = state.successful_requests;
112 if (failed_requests_out) 192 if (failed_requests_out)
113 *failed_requests_out = state.failed_requests; 193 *failed_requests_out = state.failed_requests;
114 } 194 }
115 195
116 DomainReliabilityContext::ResourceState::ResourceState(
117 DomainReliabilityContext* context,
118 const DomainReliabilityConfig::Resource* config)
119 : context(context),
120 config(config),
121 successful_requests(0),
122 failed_requests(0) {}
123
124 DomainReliabilityContext::ResourceState::~ResourceState() {}
125
126 scoped_ptr<Value> DomainReliabilityContext::ResourceState::ToValue(
127 base::TimeTicks upload_time) const {
128 ListValue* beacons_value = new ListValue();
129 for (BeaconConstIterator it = beacons.begin(); it != beacons.end(); ++it)
130 beacons_value->Append(it->ToValue(upload_time));
131
132 DictionaryValue* resource_value = new DictionaryValue();
133 resource_value->SetString("resource_name", config->name);
134 resource_value->SetInteger("successful_requests", successful_requests);
135 resource_value->SetInteger("failed_requests", failed_requests);
136 resource_value->Set("beacons", beacons_value);
137
138 return scoped_ptr<Value>(resource_value);
139 }
140
141 void DomainReliabilityContext::ResourceState::MarkUpload() {
142 uploading_beacons_size = beacons.size();
143 uploading_successful_requests = successful_requests;
144 uploading_failed_requests = failed_requests;
145 }
146
147 void DomainReliabilityContext::ResourceState::CommitUpload() {
148 BeaconIterator begin = beacons.begin();
149 BeaconIterator end = begin + uploading_beacons_size;
150 beacons.erase(begin, end);
151 successful_requests -= uploading_successful_requests;
152 failed_requests -= uploading_failed_requests;
153 }
154
155 bool DomainReliabilityContext::ResourceState::GetOldestBeaconStart(
156 base::TimeTicks* oldest_start_out) const {
157 if (beacons.empty())
158 return false;
159
160 *oldest_start_out = beacons[0].start_time;
161 return true;
162 }
163
164 void DomainReliabilityContext::ResourceState::RemoveOldestBeacon() {
165 DCHECK(!beacons.empty());
166 beacons.erase(beacons.begin());
167 // If that just removed a beacon counted in uploading_beacons_size, decrement
168 // that.
169 if (uploading_beacons_size > 0)
170 --uploading_beacons_size;
171 }
172
173 void DomainReliabilityContext::InitializeResourceStates() { 196 void DomainReliabilityContext::InitializeResourceStates() {
174 ScopedVector<DomainReliabilityConfig::Resource>::const_iterator it; 197 ScopedVector<DomainReliabilityConfig::Resource>::const_iterator it;
175 for (it = config_->resources.begin(); it != config_->resources.end(); ++it) 198 for (it = config_->resources.begin(); it != config_->resources.end(); ++it)
176 states_.push_back(new ResourceState(this, *it)); 199 states_.push_back(new ResourceState(this, *it));
177 } 200 }
178 201
179 void DomainReliabilityContext::ScheduleUpload( 202 void DomainReliabilityContext::ScheduleUpload(
180 base::TimeDelta min_delay, 203 base::TimeDelta min_delay,
181 base::TimeDelta max_delay) { 204 base::TimeDelta max_delay) {
182 dispatcher_->ScheduleTask( 205 dispatcher_->ScheduleTask(
183 base::Bind( 206 base::Bind(
184 &DomainReliabilityContext::StartUpload, 207 &DomainReliabilityContext::StartUpload,
185 weak_factory_.GetWeakPtr()), 208 weak_factory_.GetWeakPtr()),
186 min_delay, 209 min_delay,
187 max_delay); 210 max_delay);
188 } 211 }
189 212
190 void DomainReliabilityContext::StartUpload() { 213 void DomainReliabilityContext::StartUpload() {
191 MarkUpload(); 214 MarkUpload();
192 215
193 DCHECK(upload_time_.is_null()); 216 DCHECK(upload_time_.is_null());
194 upload_time_ = time_->NowTicks(); 217 upload_time_ = time_->NowTicks();
195 std::string report_json; 218 std::string report_json;
196 scoped_ptr<const Value> report_value(CreateReport(upload_time_)); 219 scoped_ptr<const Value> report_value(CreateReport(upload_time_));
197 base::JSONWriter::Write(report_value.get(), &report_json); 220 base::JSONWriter::Write(report_value.get(), &report_json);
198 report_value.reset(); 221 report_value.reset();
199 222
200 int collector_index; 223 size_t collector_index = scheduler_.OnUploadStart();
201 scheduler_.OnUploadStart(&collector_index);
202 224
203 uploader_->UploadReport( 225 uploader_->UploadReport(
204 report_json, 226 report_json,
205 config_->collectors[collector_index]->upload_url, 227 config_->collectors[collector_index]->upload_url,
206 base::Bind( 228 base::Bind(
207 &DomainReliabilityContext::OnUploadComplete, 229 &DomainReliabilityContext::OnUploadComplete,
208 weak_factory_.GetWeakPtr())); 230 weak_factory_.GetWeakPtr()));
209 231
210 UMA_HISTOGRAM_BOOLEAN("DomainReliability.UploadFailover", 232 UMA_HISTOGRAM_BOOLEAN("DomainReliability.UploadFailover",
211 collector_index > 0); 233 collector_index > 0);
(...skipping 15 matching lines...) Expand all
227 upload_time_ = base::TimeTicks(); 249 upload_time_ = base::TimeTicks();
228 } 250 }
229 251
230 scoped_ptr<const Value> DomainReliabilityContext::CreateReport( 252 scoped_ptr<const Value> DomainReliabilityContext::CreateReport(
231 base::TimeTicks upload_time) const { 253 base::TimeTicks upload_time) const {
232 ListValue* resources_value = new ListValue(); 254 ListValue* resources_value = new ListValue();
233 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) 255 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it)
234 resources_value->Append((*it)->ToValue(upload_time).release()); 256 resources_value->Append((*it)->ToValue(upload_time).release());
235 257
236 DictionaryValue* report_value = new DictionaryValue(); 258 DictionaryValue* report_value = new DictionaryValue();
237 report_value->SetString("reporter", kReporter); 259 report_value->SetString("reporter", upload_reporter_string_);
238 report_value->Set("resource_reports", resources_value); 260 report_value->Set("resource_reports", resources_value);
239 261
240 return scoped_ptr<const Value>(report_value); 262 return scoped_ptr<const Value>(report_value);
241 } 263 }
242 264
243 void DomainReliabilityContext::MarkUpload() { 265 void DomainReliabilityContext::MarkUpload() {
244 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) 266 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it)
245 (*it)->MarkUpload(); 267 (*it)->MarkUpload();
246 uploading_beacon_count_ = beacon_count_; 268 uploading_beacon_count_ = beacon_count_;
247 } 269 }
248 270
249 void DomainReliabilityContext::CommitUpload() { 271 void DomainReliabilityContext::CommitUpload() {
250 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) 272 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it)
251 (*it)->CommitUpload(); 273 (*it)->CommitUpload();
252 beacon_count_ -= uploading_beacon_count_; 274 beacon_count_ -= uploading_beacon_count_;
253 } 275 }
254 276
255 void DomainReliabilityContext::RemoveOldestBeacon() { 277 void DomainReliabilityContext::RemoveOldestBeacon() {
256 DCHECK_LT(0, beacon_count_); 278 DCHECK_LT(0u, beacon_count_);
257 279
258 base::TimeTicks min_time; 280 base::TimeTicks min_time;
259 ResourceState* min_resource = NULL; 281 ResourceState* min_resource = NULL;
260 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) { 282 for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) {
261 base::TimeTicks oldest; 283 base::TimeTicks oldest;
262 if ((*it)->GetOldestBeaconStart(&oldest)) { 284 if ((*it)->GetOldestBeaconStart(&oldest)) {
263 if (!min_resource || oldest < min_time) { 285 if (!min_resource || oldest < min_time) {
264 min_time = oldest; 286 min_time = oldest;
265 min_resource = *it; 287 min_resource = *it;
266 } 288 }
267 } 289 }
268 } 290 }
269 DCHECK(min_resource); 291 DCHECK(min_resource);
270 292
271 VLOG(1) << "Removing oldest beacon from " << min_resource->config->name; 293 VLOG(1) << "Removing oldest beacon from " << min_resource->config->name;
272 294
273 min_resource->RemoveOldestBeacon(); 295 min_resource->RemoveOldestBeacon();
274 --beacon_count_; 296 --beacon_count_;
275 // If that just removed a beacon counted in uploading_beacon_count_, decrement 297 // If that just removed a beacon counted in uploading_beacon_count_, decrement
276 // that. 298 // that.
277 if (uploading_beacon_count_ > 0) 299 if (uploading_beacon_count_ > 0)
278 --uploading_beacon_count_; 300 --uploading_beacon_count_;
279 } 301 }
280 302
281 } // namespace domain_reliability 303 } // namespace domain_reliability
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698