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

Side by Side Diff: chrome/browser/safe_browsing/protocol_manager.cc

Issue 8375039: Create a content::UrlFetcher interface that lives in content/public/common and convert users to i... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: review comments Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/safe_browsing/protocol_manager.h" 5 #include "chrome/browser/safe_browsing/protocol_manager.h"
6 6
7 #ifndef NDEBUG 7 #ifndef NDEBUG
8 #include "base/base64.h" 8 #include "base/base64.h"
9 #endif 9 #endif
10 #include "base/environment.h" 10 #include "base/environment.h"
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 169 }
170 bool use_mac = !client_key_.empty(); 170 bool use_mac = !client_key_.empty();
171 GURL gethash_url = GetHashUrl(use_mac); 171 GURL gethash_url = GetHashUrl(use_mac);
172 URLFetcher* fetcher = new URLFetcher(gethash_url, URLFetcher::POST, this); 172 URLFetcher* fetcher = new URLFetcher(gethash_url, URLFetcher::POST, this);
173 hash_requests_[fetcher] = check; 173 hash_requests_[fetcher] = check;
174 174
175 std::string get_hash; 175 std::string get_hash;
176 SafeBrowsingProtocolParser parser; 176 SafeBrowsingProtocolParser parser;
177 parser.FormatGetHash(prefixes, &get_hash); 177 parser.FormatGetHash(prefixes, &get_hash);
178 178
179 fetcher->set_load_flags(net::LOAD_DISABLE_CACHE); 179 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE);
180 fetcher->set_request_context(request_context_getter_); 180 fetcher->SetRequestContext(request_context_getter_);
181 fetcher->set_upload_data("text/plain", get_hash); 181 fetcher->SetUploadData("text/plain", get_hash);
182 fetcher->Start(); 182 fetcher->Start();
183 } 183 }
184 184
185 void SafeBrowsingProtocolManager::GetNextUpdate() { 185 void SafeBrowsingProtocolManager::GetNextUpdate() {
186 if (initial_request_) { 186 if (initial_request_) {
187 if (client_key_.empty() || wrapped_key_.empty()) { 187 if (client_key_.empty() || wrapped_key_.empty()) {
188 IssueKeyRequest(); 188 IssueKeyRequest();
189 return; 189 return;
190 } else { 190 } else {
191 initial_request_ = false; 191 initial_request_ = false;
192 } 192 }
193 } 193 }
194 194
195 if (!request_.get()) 195 if (!request_.get())
196 IssueUpdateRequest(); 196 IssueUpdateRequest();
197 } 197 }
198 198
199 // content::URLFetcherDelegate implementation ---------------------------------- 199 // content::URLFetcherDelegate implementation ----------------------------------
200 200
201 // All SafeBrowsing request responses are handled here. 201 // All SafeBrowsing request responses are handled here.
202 // TODO(paulg): Clarify with the SafeBrowsing team whether a failed parse of a 202 // TODO(paulg): Clarify with the SafeBrowsing team whether a failed parse of a
203 // chunk should retry the download and parse of that chunk (and 203 // chunk should retry the download and parse of that chunk (and
204 // what back off / how many times to try), and if that effects the 204 // what back off / how many times to try), and if that effects the
205 // update back off. For now, a failed parse of the chunk means we 205 // update back off. For now, a failed parse of the chunk means we
206 // drop it. This isn't so bad because the next UPDATE_REQUEST we 206 // drop it. This isn't so bad because the next UPDATE_REQUEST we
207 // do will report all the chunks we have. If that chunk is still 207 // do will report all the chunks we have. If that chunk is still
208 // required, the SafeBrowsing servers will tell us to get it again. 208 // required, the SafeBrowsing servers will tell us to get it again.
209 void SafeBrowsingProtocolManager::OnURLFetchComplete(const URLFetcher* source) { 209 void SafeBrowsingProtocolManager::OnURLFetchComplete(
210 scoped_ptr<const URLFetcher> fetcher; 210 const content::URLFetcher* source) {
211 scoped_ptr<const content::URLFetcher> fetcher;
211 bool parsed_ok = true; 212 bool parsed_ok = true;
212 bool must_back_off = false; // Reduce SafeBrowsing service query frequency. 213 bool must_back_off = false; // Reduce SafeBrowsing service query frequency.
213 214
214 // See if this is a safebrowsing report fetcher. We don't take any action for 215 // See if this is a safebrowsing report fetcher. We don't take any action for
215 // the response to those. 216 // the response to those.
216 std::set<const URLFetcher*>::iterator sit = safebrowsing_reports_.find( 217 std::set<const content::URLFetcher*>::iterator sit =
217 source); 218 safebrowsing_reports_.find(source);
218 if (sit != safebrowsing_reports_.end()) { 219 if (sit != safebrowsing_reports_.end()) {
219 const URLFetcher* report = *sit; 220 const content::URLFetcher* report = *sit;
220 safebrowsing_reports_.erase(sit); 221 safebrowsing_reports_.erase(sit);
221 delete report; 222 delete report;
222 return; 223 return;
223 } 224 }
224 225
225 HashRequests::iterator it = hash_requests_.find(source); 226 HashRequests::iterator it = hash_requests_.find(source);
226 if (it != hash_requests_.end()) { 227 if (it != hash_requests_.end()) {
227 // GetHash response. 228 // GetHash response.
228 fetcher.reset(it->first); 229 fetcher.reset(it->first);
229 SafeBrowsingService::SafeBrowsingCheck* check = it->second; 230 SafeBrowsingService::SafeBrowsingCheck* check = it->second;
230 std::vector<SBFullHashResult> full_hashes; 231 std::vector<SBFullHashResult> full_hashes;
231 bool can_cache = false; 232 bool can_cache = false;
232 if (source->response_code() == 200 || source->response_code() == 204) { 233 if (source->GetResponseCode() == 200 || source->GetResponseCode() == 204) {
233 // For tracking our GetHash false positive (204) rate, compared to real 234 // For tracking our GetHash false positive (204) rate, compared to real
234 // (200) responses. 235 // (200) responses.
235 if (source->response_code() == 200) 236 if (source->GetResponseCode() == 200)
236 RecordGetHashResult(check->is_download, GET_HASH_STATUS_200); 237 RecordGetHashResult(check->is_download, GET_HASH_STATUS_200);
237 else 238 else
238 RecordGetHashResult(check->is_download, GET_HASH_STATUS_204); 239 RecordGetHashResult(check->is_download, GET_HASH_STATUS_204);
239 can_cache = true; 240 can_cache = true;
240 gethash_error_count_ = 0; 241 gethash_error_count_ = 0;
241 gethash_back_off_mult_ = 1; 242 gethash_back_off_mult_ = 1;
242 bool re_key = false; 243 bool re_key = false;
243 SafeBrowsingProtocolParser parser; 244 SafeBrowsingProtocolParser parser;
244 std::string data; 245 std::string data;
245 source->GetResponseAsString(&data); 246 source->GetResponseAsString(&data);
246 parsed_ok = parser.ParseGetHash( 247 parsed_ok = parser.ParseGetHash(
247 data.data(), 248 data.data(),
248 static_cast<int>(data.length()), 249 static_cast<int>(data.length()),
249 client_key_, 250 client_key_,
250 &re_key, 251 &re_key,
251 &full_hashes); 252 &full_hashes);
252 if (!parsed_ok) { 253 if (!parsed_ok) {
253 // If we fail to parse it, we must still inform the SafeBrowsingService 254 // If we fail to parse it, we must still inform the SafeBrowsingService
254 // so that it doesn't hold up the user's request indefinitely. Not sure 255 // so that it doesn't hold up the user's request indefinitely. Not sure
255 // what to do at that point though! 256 // what to do at that point though!
256 full_hashes.clear(); 257 full_hashes.clear();
257 } else { 258 } else {
258 if (re_key) 259 if (re_key)
259 HandleReKey(); 260 HandleReKey();
260 } 261 }
261 } else { 262 } else {
262 HandleGetHashError(Time::Now()); 263 HandleGetHashError(Time::Now());
263 if (source->status().status() == net::URLRequestStatus::FAILED) { 264 if (source->GetStatus().status() == net::URLRequestStatus::FAILED) {
264 VLOG(1) << "SafeBrowsing GetHash request for: " << source->url() 265 VLOG(1) << "SafeBrowsing GetHash request for: " << source->GetUrl()
265 << " failed with error: " << source->status().error(); 266 << " failed with error: " << source->GetStatus().error();
266 } else { 267 } else {
267 VLOG(1) << "SafeBrowsing GetHash request for: " << source->url() 268 VLOG(1) << "SafeBrowsing GetHash request for: " << source->GetUrl()
268 << " failed with error: " << source->response_code(); 269 << " failed with error: " << source->GetResponseCode();
269 } 270 }
270 } 271 }
271 272
272 // Call back the SafeBrowsingService with full_hashes, even if there was a 273 // Call back the SafeBrowsingService with full_hashes, even if there was a
273 // parse error or an error response code (in which case full_hashes will be 274 // parse error or an error response code (in which case full_hashes will be
274 // empty). We can't block the user regardless of the error status. 275 // empty). We can't block the user regardless of the error status.
275 sb_service_->HandleGetHashResults(check, full_hashes, can_cache); 276 sb_service_->HandleGetHashResults(check, full_hashes, can_cache);
276 277
277 hash_requests_.erase(it); 278 hash_requests_.erase(it);
278 } else { 279 } else {
279 // Update, chunk or key response. 280 // Update, chunk or key response.
280 fetcher.reset(request_.release()); 281 fetcher.reset(request_.release());
281 282
282 if (request_type_ == UPDATE_REQUEST) { 283 if (request_type_ == UPDATE_REQUEST) {
283 if (!fetcher.get()) { 284 if (!fetcher.get()) {
284 // We've timed out waiting for an update response, so we've cancelled 285 // We've timed out waiting for an update response, so we've cancelled
285 // the update request and scheduled a new one. Ignore this response. 286 // the update request and scheduled a new one. Ignore this response.
286 return; 287 return;
287 } 288 }
288 289
289 // Cancel the update response timeout now that we have the response. 290 // Cancel the update response timeout now that we have the response.
290 update_timer_.Stop(); 291 update_timer_.Stop();
291 } 292 }
292 293
293 if (source->response_code() == 200) { 294 if (source->GetResponseCode() == 200) {
294 // We have data from the SafeBrowsing service. 295 // We have data from the SafeBrowsing service.
295 std::string data; 296 std::string data;
296 source->GetResponseAsString(&data); 297 source->GetResponseAsString(&data);
297 parsed_ok = HandleServiceResponse( 298 parsed_ok = HandleServiceResponse(
298 source->url(), data.data(), static_cast<int>(data.length())); 299 source->GetUrl(), data.data(), static_cast<int>(data.length()));
299 if (!parsed_ok) { 300 if (!parsed_ok) {
300 VLOG(1) << "SafeBrowsing request for: " << source->url() 301 VLOG(1) << "SafeBrowsing request for: " << source->GetUrl()
301 << " failed parse."; 302 << " failed parse.";
302 must_back_off = true; 303 must_back_off = true;
303 chunk_request_urls_.clear(); 304 chunk_request_urls_.clear();
304 UpdateFinished(false); 305 UpdateFinished(false);
305 } 306 }
306 307
307 switch (request_type_) { 308 switch (request_type_) {
308 case CHUNK_REQUEST: 309 case CHUNK_REQUEST:
309 if (parsed_ok) 310 if (parsed_ok)
310 chunk_request_urls_.pop_front(); 311 chunk_request_urls_.pop_front();
(...skipping 17 matching lines...) Expand all
328 default: 329 default:
329 NOTREACHED(); 330 NOTREACHED();
330 break; 331 break;
331 } 332 }
332 } else { 333 } else {
333 // The SafeBrowsing service error, or very bad response code: back off. 334 // The SafeBrowsing service error, or very bad response code: back off.
334 must_back_off = true; 335 must_back_off = true;
335 if (request_type_ == CHUNK_REQUEST) 336 if (request_type_ == CHUNK_REQUEST)
336 chunk_request_urls_.clear(); 337 chunk_request_urls_.clear();
337 UpdateFinished(false); 338 UpdateFinished(false);
338 if (source->status().status() == net::URLRequestStatus::FAILED) { 339 if (source->GetStatus().status() == net::URLRequestStatus::FAILED) {
339 VLOG(1) << "SafeBrowsing request for: " << source->url() 340 VLOG(1) << "SafeBrowsing request for: " << source->GetUrl()
340 << " failed with error: " << source->status().error(); 341 << " failed with error: " << source->GetStatus().error();
341 } else { 342 } else {
342 VLOG(1) << "SafeBrowsing request for: " << source->url() 343 VLOG(1) << "SafeBrowsing request for: " << source->GetUrl()
343 << " failed with error: " << source->response_code(); 344 << " failed with error: " << source->GetResponseCode();
344 } 345 }
345 } 346 }
346 } 347 }
347 348
348 // Schedule a new update request if we've finished retrieving all the chunks 349 // Schedule a new update request if we've finished retrieving all the chunks
349 // from the previous update. We treat the update request and the chunk URLs it 350 // from the previous update. We treat the update request and the chunk URLs it
350 // contains as an atomic unit as far as back off is concerned. 351 // contains as an atomic unit as far as back off is concerned.
351 if (chunk_request_urls_.empty() && 352 if (chunk_request_urls_.empty() &&
352 (request_type_ == CHUNK_REQUEST || request_type_ == UPDATE_REQUEST)) 353 (request_type_ == CHUNK_REQUEST || request_type_ == UPDATE_REQUEST))
353 ScheduleNextUpdate(must_back_off); 354 ScheduleNextUpdate(must_back_off);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 // don't get the next url until the previous one has been written to disk so 556 // don't get the next url until the previous one has been written to disk so
556 // that we don't use too much memory. 557 // that we don't use too much memory.
557 if (request_.get() || chunk_request_urls_.empty() || chunk_pending_to_write_) 558 if (request_.get() || chunk_request_urls_.empty() || chunk_pending_to_write_)
558 return; 559 return;
559 560
560 ChunkUrl next_chunk = chunk_request_urls_.front(); 561 ChunkUrl next_chunk = chunk_request_urls_.front();
561 DCHECK(!next_chunk.url.empty()); 562 DCHECK(!next_chunk.url.empty());
562 GURL chunk_url = NextChunkUrl(next_chunk.url); 563 GURL chunk_url = NextChunkUrl(next_chunk.url);
563 request_type_ = CHUNK_REQUEST; 564 request_type_ = CHUNK_REQUEST;
564 request_.reset(new URLFetcher(chunk_url, URLFetcher::GET, this)); 565 request_.reset(new URLFetcher(chunk_url, URLFetcher::GET, this));
565 request_->set_load_flags(net::LOAD_DISABLE_CACHE); 566 request_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
566 request_->set_request_context(request_context_getter_); 567 request_->SetRequestContext(request_context_getter_);
567 chunk_request_start_ = base::Time::Now(); 568 chunk_request_start_ = base::Time::Now();
568 request_->Start(); 569 request_->Start();
569 } 570 }
570 571
571 void SafeBrowsingProtocolManager::IssueKeyRequest() { 572 void SafeBrowsingProtocolManager::IssueKeyRequest() {
572 GURL key_url = MacKeyUrl(); 573 GURL key_url = MacKeyUrl();
573 request_type_ = GETKEY_REQUEST; 574 request_type_ = GETKEY_REQUEST;
574 request_.reset(new URLFetcher(key_url, URLFetcher::GET, this)); 575 request_.reset(new URLFetcher(key_url, URLFetcher::GET, this));
575 request_->set_load_flags(net::LOAD_DISABLE_CACHE); 576 request_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
576 request_->set_request_context(request_context_getter_); 577 request_->SetRequestContext(request_context_getter_);
577 request_->Start(); 578 request_->Start();
578 } 579 }
579 580
580 void SafeBrowsingProtocolManager::OnGetChunksComplete( 581 void SafeBrowsingProtocolManager::OnGetChunksComplete(
581 const std::vector<SBListChunkRanges>& lists, bool database_error) { 582 const std::vector<SBListChunkRanges>& lists, bool database_error) {
582 DCHECK_EQ(request_type_, UPDATE_REQUEST); 583 DCHECK_EQ(request_type_, UPDATE_REQUEST);
583 if (database_error) { 584 if (database_error) {
584 UpdateFinished(false); 585 UpdateFinished(false);
585 ScheduleNextUpdate(false); 586 ScheduleNextUpdate(false);
586 return; 587 return;
(...skipping 19 matching lines...) Expand all
606 if (!found_phishing) 607 if (!found_phishing)
607 list_data.append(FormatList( 608 list_data.append(FormatList(
608 SBListChunkRanges(safe_browsing_util::kPhishingList), use_mac)); 609 SBListChunkRanges(safe_browsing_util::kPhishingList), use_mac));
609 610
610 if (!found_malware) 611 if (!found_malware)
611 list_data.append(FormatList( 612 list_data.append(FormatList(
612 SBListChunkRanges(safe_browsing_util::kMalwareList), use_mac)); 613 SBListChunkRanges(safe_browsing_util::kMalwareList), use_mac));
613 614
614 GURL update_url = UpdateUrl(use_mac); 615 GURL update_url = UpdateUrl(use_mac);
615 request_.reset(new URLFetcher(update_url, URLFetcher::POST, this)); 616 request_.reset(new URLFetcher(update_url, URLFetcher::POST, this));
616 request_->set_load_flags(net::LOAD_DISABLE_CACHE); 617 request_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
617 request_->set_request_context(request_context_getter_); 618 request_->SetRequestContext(request_context_getter_);
618 request_->set_upload_data("text/plain", list_data); 619 request_->SetUploadData("text/plain", list_data);
619 request_->Start(); 620 request_->Start();
620 621
621 // Begin the update request timeout. 622 // Begin the update request timeout.
622 update_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(kSbMaxUpdateWaitSec), 623 update_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(kSbMaxUpdateWaitSec),
623 this, 624 this,
624 &SafeBrowsingProtocolManager::UpdateResponseTimeout); 625 &SafeBrowsingProtocolManager::UpdateResponseTimeout);
625 } 626 }
626 627
627 // If we haven't heard back from the server with an update response, this method 628 // If we haven't heard back from the server with an update response, this method
628 // will run. Close the current update session and schedule another update. 629 // will run. Close the current update session and schedule another update.
(...skipping 21 matching lines...) Expand all
650 const GURL& page_url, 651 const GURL& page_url,
651 const GURL& referrer_url, 652 const GURL& referrer_url,
652 bool is_subresource, 653 bool is_subresource,
653 SafeBrowsingService::UrlCheckResult threat_type, 654 SafeBrowsingService::UrlCheckResult threat_type,
654 const std::string& post_data) { 655 const std::string& post_data) {
655 GURL report_url = SafeBrowsingHitUrl(malicious_url, page_url, 656 GURL report_url = SafeBrowsingHitUrl(malicious_url, page_url,
656 referrer_url, is_subresource, 657 referrer_url, is_subresource,
657 threat_type); 658 threat_type);
658 URLFetcher* report = new URLFetcher( 659 URLFetcher* report = new URLFetcher(
659 report_url, post_data.empty() ? URLFetcher::GET : URLFetcher::POST, this); 660 report_url, post_data.empty() ? URLFetcher::GET : URLFetcher::POST, this);
660 report->set_load_flags(net::LOAD_DISABLE_CACHE); 661 report->SetLoadFlags(net::LOAD_DISABLE_CACHE);
661 report->set_request_context(request_context_getter_); 662 report->SetRequestContext(request_context_getter_);
662 if (!post_data.empty()) 663 if (!post_data.empty())
663 report->set_upload_data("text/plain", post_data); 664 report->SetUploadData("text/plain", post_data);
664 report->Start(); 665 report->Start();
665 safebrowsing_reports_.insert(report); 666 safebrowsing_reports_.insert(report);
666 } 667 }
667 668
668 // Sends malware details for users who opt-in. 669 // Sends malware details for users who opt-in.
669 void SafeBrowsingProtocolManager::ReportMalwareDetails( 670 void SafeBrowsingProtocolManager::ReportMalwareDetails(
670 const std::string& report) { 671 const std::string& report) {
671 GURL report_url = MalwareDetailsUrl(); 672 GURL report_url = MalwareDetailsUrl();
672 URLFetcher* fetcher = new URLFetcher(report_url, URLFetcher::POST, this); 673 URLFetcher* fetcher = new URLFetcher(report_url, URLFetcher::POST, this);
673 fetcher->set_load_flags(net::LOAD_DISABLE_CACHE); 674 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE);
674 fetcher->set_request_context(request_context_getter_); 675 fetcher->SetRequestContext(request_context_getter_);
675 fetcher->set_upload_data("application/octet-stream", report); 676 fetcher->SetUploadData("application/octet-stream", report);
676 // Don't try too hard to send reports on failures. 677 // Don't try too hard to send reports on failures.
677 fetcher->set_automatically_retry_on_5xx(false); 678 fetcher->SetAutomaticallyRetryOn5xx(false);
678 fetcher->Start(); 679 fetcher->Start();
679 safebrowsing_reports_.insert(fetcher); 680 safebrowsing_reports_.insert(fetcher);
680 } 681 }
681 682
682 683
683 // static 684 // static
684 std::string SafeBrowsingProtocolManager::FormatList( 685 std::string SafeBrowsingProtocolManager::FormatList(
685 const SBListChunkRanges& list, bool use_mac) { 686 const SBListChunkRanges& list, bool use_mac) {
686 std::string formatted_results; 687 std::string formatted_results;
687 formatted_results.append(list.name); 688 formatted_results.append(list.name);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 if (!additional_query_.empty()) { 825 if (!additional_query_.empty()) {
825 if (next_url.find("?") != std::string::npos) { 826 if (next_url.find("?") != std::string::npos) {
826 next_url.append("&"); 827 next_url.append("&");
827 } else { 828 } else {
828 next_url.append("?"); 829 next_url.append("?");
829 } 830 }
830 next_url.append(additional_query_); 831 next_url.append(additional_query_);
831 } 832 }
832 return GURL(next_url); 833 return GURL(next_url);
833 } 834 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/protocol_manager.h ('k') | chrome/browser/safe_browsing/safe_browsing_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698