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

Side by Side Diff: components/safe_browsing_db/v4_update_protocol_manager.cc

Issue 1954393002: Initialize and reset V4LocalDBManager. Instantiate V4Stores. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@v4_01_db_realz
Patch Set: CR feedback Created 4 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/safe_browsing_db/v4_update_protocol_manager.h" 5 #include "components/safe_browsing_db/v4_update_protocol_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // static 93 // static
94 V4UpdateProtocolManagerFactory* V4UpdateProtocolManager::factory_ = NULL; 94 V4UpdateProtocolManagerFactory* V4UpdateProtocolManager::factory_ = NULL;
95 95
96 // static 96 // static
97 std::unique_ptr<V4UpdateProtocolManager> V4UpdateProtocolManager::Create( 97 std::unique_ptr<V4UpdateProtocolManager> V4UpdateProtocolManager::Create(
98 net::URLRequestContextGetter* request_context_getter, 98 net::URLRequestContextGetter* request_context_getter,
99 const V4ProtocolConfig& config, 99 const V4ProtocolConfig& config,
100 const base::hash_map<UpdateListIdentifier, std::string>& 100 const base::hash_map<UpdateListIdentifier, std::string>&
101 current_list_states, 101 current_list_states,
102 V4UpdateCallback callback) { 102 V4UpdateCallback callback) {
103 if (!factory_) 103 if (!factory_) {
104 factory_ = new V4UpdateProtocolManagerFactoryImpl(); 104 factory_ = new V4UpdateProtocolManagerFactoryImpl();
105 }
105 return factory_->CreateProtocolManager(request_context_getter, config, 106 return factory_->CreateProtocolManager(request_context_getter, config,
106 current_list_states, callback); 107 current_list_states, callback);
107 } 108 }
108 109
109 void V4UpdateProtocolManager::ResetUpdateErrors() { 110 void V4UpdateProtocolManager::ResetUpdateErrors() {
110 update_error_count_ = 0; 111 update_error_count_ = 0;
111 update_back_off_mult_ = 1; 112 update_back_off_mult_ = 1;
112 } 113 }
113 114
114 V4UpdateProtocolManager::V4UpdateProtocolManager( 115 V4UpdateProtocolManager::V4UpdateProtocolManager(
115 net::URLRequestContextGetter* request_context_getter, 116 net::URLRequestContextGetter* request_context_getter,
116 const V4ProtocolConfig& config, 117 const V4ProtocolConfig& config,
117 const base::hash_map<UpdateListIdentifier, std::string>& 118 const base::hash_map<UpdateListIdentifier, std::string>&
118 current_list_states, 119 current_list_states,
119 V4UpdateCallback callback) 120 V4UpdateCallback update_callback)
120 : current_list_states_(current_list_states), 121 : current_list_states_(current_list_states),
121 update_error_count_(0), 122 update_error_count_(0),
122 update_back_off_mult_(1), 123 update_back_off_mult_(1),
123 next_update_interval_(base::TimeDelta::FromSeconds( 124 next_update_interval_(base::TimeDelta::FromSeconds(
124 base::RandInt(kV4TimerStartIntervalSecMin, 125 base::RandInt(kV4TimerStartIntervalSecMin,
125 kV4TimerStartIntervalSecMax))), 126 kV4TimerStartIntervalSecMax))),
126 config_(config), 127 config_(config),
127 request_context_getter_(request_context_getter), 128 request_context_getter_(request_context_getter),
128 url_fetcher_id_(0), 129 url_fetcher_id_(0),
129 callback_(callback) { 130 update_callback_(update_callback) {
130 ScheduleNextUpdate(false /* no back off */); 131 // Do not auto-schedule updates. Let the owner (V4LocalDatabaseManager) do it
132 // when it is ready to process updates.
133 DVLOG(1) << "V4UpdateProtocolManager::V4UpdateProtocolManager: "
134 << "next_update_interval_: " << next_update_interval_;
131 } 135 }
132 136
133 V4UpdateProtocolManager::~V4UpdateProtocolManager() {} 137 V4UpdateProtocolManager::~V4UpdateProtocolManager() {}
134 138
135 bool V4UpdateProtocolManager::IsUpdateScheduled() const { 139 bool V4UpdateProtocolManager::IsUpdateScheduled() const {
136 return update_timer_.IsRunning(); 140 return update_timer_.IsRunning();
137 } 141 }
138 142
139 void V4UpdateProtocolManager::ScheduleNextUpdate(bool back_off) { 143 void V4UpdateProtocolManager::ScheduleNextUpdate() {
144 ScheduleNextUpdateWithBackoff(false);
145 }
146
147 void V4UpdateProtocolManager::ScheduleNextUpdateWithBackoff(bool back_off) {
148 DCHECK(CalledOnValidThread());
149
140 // TODO(vakh): Set disable_auto_update correctly using the command line 150 // TODO(vakh): Set disable_auto_update correctly using the command line
141 // switch. 151 // switch.
142 if (config_.disable_auto_update) { 152 if (config_.disable_auto_update) {
143 DCHECK(!IsUpdateScheduled()); 153 DCHECK(!IsUpdateScheduled());
144 return; 154 return;
145 } 155 }
146 156
147 // Reschedule with the new update. 157 // Reschedule with the new update.
148 base::TimeDelta next_update_interval = GetNextUpdateInterval(back_off); 158 base::TimeDelta next_update_interval = GetNextUpdateInterval(back_off);
149 ScheduleNextUpdateAfterInterval(next_update_interval); 159 ScheduleNextUpdateAfterInterval(next_update_interval);
150 } 160 }
151 161
152 // According to section 5 of the SafeBrowsing protocol specification, we must 162 // According to section 5 of the SafeBrowsing protocol specification, we must
153 // back off after a certain number of errors. 163 // back off after a certain number of errors.
154 base::TimeDelta V4UpdateProtocolManager::GetNextUpdateInterval(bool back_off) { 164 base::TimeDelta V4UpdateProtocolManager::GetNextUpdateInterval(bool back_off) {
155 DCHECK(CalledOnValidThread()); 165 DCHECK(CalledOnValidThread());
156 DCHECK(next_update_interval_ > base::TimeDelta()); 166 DCHECK(next_update_interval_ > base::TimeDelta());
167
157 base::TimeDelta next = next_update_interval_; 168 base::TimeDelta next = next_update_interval_;
158 if (back_off) { 169 if (back_off) {
159 next = V4ProtocolManagerUtil::GetNextBackOffInterval( 170 next = V4ProtocolManagerUtil::GetNextBackOffInterval(
160 &update_error_count_, &update_back_off_mult_); 171 &update_error_count_, &update_back_off_mult_);
161 } 172 }
173
174 if (!last_response_time_.is_null()) {
175 // The callback spent some time updating the database, including disk I/O.
176 // Do not wait that extra time.
177 base::TimeDelta callback_time = Time::Now() - last_response_time_;
178 if (callback_time < next) {
179 next -= callback_time;
180 } else {
181 // If the callback took too long, schedule the next update with no delay.
182 next = base::TimeDelta();
183 }
184 }
162 DVLOG(1) << "V4UpdateProtocolManager::GetNextUpdateInterval: " 185 DVLOG(1) << "V4UpdateProtocolManager::GetNextUpdateInterval: "
163 << "next_interval: " << next; 186 << "next_interval: " << next;
164 return next; 187 return next;
165 } 188 }
166 189
167 void V4UpdateProtocolManager::ScheduleNextUpdateAfterInterval( 190 void V4UpdateProtocolManager::ScheduleNextUpdateAfterInterval(
168 base::TimeDelta interval) { 191 base::TimeDelta interval) {
169 DCHECK(CalledOnValidThread()); 192 DCHECK(CalledOnValidThread());
170 DCHECK(interval >= base::TimeDelta()); 193 DCHECK(interval >= base::TimeDelta());
194
171 // Unschedule any current timer. 195 // Unschedule any current timer.
172 update_timer_.Stop(); 196 update_timer_.Stop();
173 update_timer_.Start(FROM_HERE, interval, this, 197 update_timer_.Start(FROM_HERE, interval, this,
174 &V4UpdateProtocolManager::IssueUpdateRequest); 198 &V4UpdateProtocolManager::IssueUpdateRequest);
175 } 199 }
176 200
177 std::string V4UpdateProtocolManager::GetBase64SerializedUpdateRequestProto( 201 std::string V4UpdateProtocolManager::GetBase64SerializedUpdateRequestProto(
178 const base::hash_map<UpdateListIdentifier, std::string>& 202 const base::hash_map<UpdateListIdentifier, std::string>&
179 current_list_states) { 203 current_list_states) {
180 // Build the request. Client info and client states are not added to the 204 // Build the request. Client info and client states are not added to the
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 269
246 void V4UpdateProtocolManager::IssueUpdateRequest() { 270 void V4UpdateProtocolManager::IssueUpdateRequest() {
247 DCHECK(CalledOnValidThread()); 271 DCHECK(CalledOnValidThread());
248 272
249 // If an update request is already pending, record and return silently. 273 // If an update request is already pending, record and return silently.
250 if (request_.get()) { 274 if (request_.get()) {
251 RecordUpdateResult(V4OperationResult::ALREADY_PENDING_ERROR); 275 RecordUpdateResult(V4OperationResult::ALREADY_PENDING_ERROR);
252 return; 276 return;
253 } 277 }
254 278
255 std::string req_base64 = GetBase64SerializedUpdateRequestProto( 279 std::string req_base64 =
256 current_list_states_); 280 GetBase64SerializedUpdateRequestProto(current_list_states_);
Scott Hess - ex-Googler 2016/05/12 23:18:00 I generally appreciate this kind of formatting. A
vakh (use Gerrit instead) 2016/05/13 00:07:32 Acknowledged. vim auto format :)
257 GURL update_url = GetUpdateUrl(req_base64); 281 GURL update_url = GetUpdateUrl(req_base64);
258 282
259 request_.reset(net::URLFetcher::Create(url_fetcher_id_++, update_url, 283 request_.reset(net::URLFetcher::Create(url_fetcher_id_++, update_url,
260 net::URLFetcher::GET, this) 284 net::URLFetcher::GET, this)
261 .release()); 285 .release());
262 286
263 request_->SetLoadFlags(net::LOAD_DISABLE_CACHE); 287 request_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
264 request_->SetRequestContext(request_context_getter_.get()); 288 request_->SetRequestContext(request_context_getter_.get());
265 request_->Start(); 289 request_->Start();
266 // TODO(vakh): Handle request timeout. 290 // TODO(vakh): Handle request timeout.
267 } 291 }
268 292
269 // net::URLFetcherDelegate implementation ---------------------------------- 293 // net::URLFetcherDelegate implementation ----------------------------------
270 294
271 // SafeBrowsing request responses are handled here. 295 // SafeBrowsing request responses are handled here.
272 void V4UpdateProtocolManager::OnURLFetchComplete( 296 void V4UpdateProtocolManager::OnURLFetchComplete(
273 const net::URLFetcher* source) { 297 const net::URLFetcher* source) {
274 DCHECK(CalledOnValidThread()); 298 DCHECK(CalledOnValidThread());
275 299
276 int response_code = source->GetResponseCode(); 300 int response_code = source->GetResponseCode();
277 net::URLRequestStatus status = source->GetStatus(); 301 net::URLRequestStatus status = source->GetStatus();
278 V4ProtocolManagerUtil::RecordHttpResponseOrErrorCode( 302 V4ProtocolManagerUtil::RecordHttpResponseOrErrorCode(
279 "SafeBrowsing.V4UpdateHttpResponseOrErrorCode", status, response_code); 303 "SafeBrowsing.V4UpdateHttpResponseOrErrorCode", status, response_code);
280 304
305 last_response_time_ = Time::Now();
306
281 std::vector<ListUpdateResponse> list_update_responses; 307 std::vector<ListUpdateResponse> list_update_responses;
282 bool back_off;
283 if (status.is_success() && response_code == net::HTTP_OK) { 308 if (status.is_success() && response_code == net::HTTP_OK) {
284 back_off = false;
285 RecordUpdateResult(V4OperationResult::STATUS_200); 309 RecordUpdateResult(V4OperationResult::STATUS_200);
286 ResetUpdateErrors(); 310 ResetUpdateErrors();
287 std::string data; 311 std::string data;
288 source->GetResponseAsString(&data); 312 source->GetResponseAsString(&data);
289 if (!ParseUpdateResponse(data, &list_update_responses)) { 313 if (!ParseUpdateResponse(data, &list_update_responses)) {
290 list_update_responses.clear(); 314 list_update_responses.clear();
291 RecordUpdateResult(V4OperationResult::PARSE_ERROR); 315 RecordUpdateResult(V4OperationResult::PARSE_ERROR);
292 } 316 }
317 request_.reset();
318
293 // Invoke the callback with list_update_responses. 319 // Invoke the callback with list_update_responses.
294 // The caller should update its state now, based on list_update_responses. 320 // The caller should update its state now, based on list_update_responses.
295 callback_.Run(list_update_responses); 321 // The callback must call ScheduleNextUpdate() at the end to resume
322 // downloading updates.
323 update_callback_.Run(list_update_responses);
296 } else { 324 } else {
297 back_off = true;
298 DVLOG(1) << "SafeBrowsing GetEncodedUpdates request for: " 325 DVLOG(1) << "SafeBrowsing GetEncodedUpdates request for: "
299 << source->GetURL() << " failed with error: " << status.error() 326 << source->GetURL() << " failed with error: " << status.error()
300 << " and response code: " << response_code; 327 << " and response code: " << response_code;
301 328
302 if (status.status() == net::URLRequestStatus::FAILED) { 329 if (status.status() == net::URLRequestStatus::FAILED) {
303 RecordUpdateResult(V4OperationResult::NETWORK_ERROR); 330 RecordUpdateResult(V4OperationResult::NETWORK_ERROR);
304 } else { 331 } else {
305 RecordUpdateResult(V4OperationResult::HTTP_ERROR); 332 RecordUpdateResult(V4OperationResult::HTTP_ERROR);
306 } 333 }
307 // TODO(vakh): Figure out whether it is just a network error vs backoff vs 334 // TODO(vakh): Figure out whether it is just a network error vs backoff vs
308 // another condition and RecordUpdateResult more accurately. 335 // another condition and RecordUpdateResult more accurately.
336
337 request_.reset();
338 ScheduleNextUpdateWithBackoff(true);
309 } 339 }
310 request_.reset();
311 ScheduleNextUpdate(back_off);
312 } 340 }
313 341
314 GURL V4UpdateProtocolManager::GetUpdateUrl( 342 GURL V4UpdateProtocolManager::GetUpdateUrl(
315 const std::string& req_base64) const { 343 const std::string& req_base64) const {
316 GURL url = V4ProtocolManagerUtil::GetRequestUrl(req_base64, "encodedUpdates", 344 GURL url = V4ProtocolManagerUtil::GetRequestUrl(req_base64, "encodedUpdates",
317 config_); 345 config_);
318 DVLOG(1) << "V4UpdateProtocolManager::GetUpdateUrl: " 346 DVLOG(1) << "V4UpdateProtocolManager::GetUpdateUrl: "
319 << "url: " << url; 347 << "url: " << url;
320 return url; 348 return url;
321 } 349 }
322 350
323 } // namespace safe_browsing 351 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698