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

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

Issue 7313003: Separate memory purger from safe browsing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/safe_browsing_service.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/stl_util-inl.h" 11 #include "base/stl_util-inl.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
14 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/metrics/metrics_service.h" 15 #include "chrome/browser/metrics/metrics_service.h"
16 #include "chrome/browser/prefs/pref_service.h" 16 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/browser/profiles/profile_manager.h" 17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/safe_browsing/malware_details.h" 18 #include "chrome/browser/safe_browsing/malware_details.h"
19 #include "chrome/browser/safe_browsing/protocol_manager.h" 19 #include "chrome/browser/safe_browsing/protocol_manager.h"
20 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" 20 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_database.h" 21 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
22 #include "chrome/browser/tab_contents/tab_util.h" 22 #include "chrome/browser/tab_contents/tab_util.h"
23 #include "chrome/common/chrome_constants.h" 23 #include "chrome/common/chrome_constants.h"
24 #include "chrome/common/chrome_paths.h" 24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/url_constants.h" 27 #include "chrome/common/url_constants.h"
28 #include "content/browser/browser_thread.h" 28 #include "content/browser/browser_thread.h"
29 #include "content/browser/tab_contents/tab_contents.h" 29 #include "content/browser/tab_contents/tab_contents.h"
30 #include "content/common/notification_service.h"
30 #include "net/base/registry_controlled_domain.h" 31 #include "net/base/registry_controlled_domain.h"
31 #include "net/url_request/url_request_context_getter.h" 32 #include "net/url_request/url_request_context_getter.h"
32 33
33 #if defined(OS_WIN) 34 #if defined(OS_WIN)
34 #include "chrome/installer/util/browser_distribution.h" 35 #include "chrome/installer/util/browser_distribution.h"
35 #endif 36 #endif
36 37
37 namespace { 38 namespace {
38 39
39 // The default URL prefix where browser fetches chunk updates, hashes, 40 // The default URL prefix where browser fetches chunk updates, hashes,
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 else 462 else
462 ShutDown(); 463 ShutDown();
463 } 464 }
464 465
465 // static 466 // static
466 void SafeBrowsingService::RegisterPrefs(PrefService* prefs) { 467 void SafeBrowsingService::RegisterPrefs(PrefService* prefs) {
467 prefs->RegisterStringPref(prefs::kSafeBrowsingClientKey, ""); 468 prefs->RegisterStringPref(prefs::kSafeBrowsingClientKey, "");
468 prefs->RegisterStringPref(prefs::kSafeBrowsingWrappedKey, ""); 469 prefs->RegisterStringPref(prefs::kSafeBrowsingWrappedKey, "");
469 } 470 }
470 471
471 void SafeBrowsingService::CloseDatabase() {
472 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
473
474 // Cases to avoid:
475 // * If |closing_database_| is true, continuing will queue up a second
476 // request, |closing_database_| will be reset after handling the first
477 // request, and if any functions on the db thread recreate the database, we
478 // could start using it on the IO thread and then have the second request
479 // handler delete it out from under us.
480 // * If |database_| is NULL, then either no creation request is in flight, in
481 // which case we don't need to do anything, or one is in flight, in which
482 // case the database will be recreated before our deletion request is
483 // handled, and could be used on the IO thread in that time period, leading
484 // to the same problem as above.
485 // * If |queued_checks_| is non-empty and |database_| is non-NULL, we're
486 // about to be called back (in DatabaseLoadComplete()). This will call
487 // CheckUrl(), which will want the database. Closing the database here
488 // would lead to an infinite loop in DatabaseLoadComplete(), and even if it
489 // didn't, it would be pointless since we'd just want to recreate.
490 //
491 // The first two cases above are handled by checking DatabaseAvailable().
492 if (!DatabaseAvailable() || !queued_checks_.empty())
493 return;
494
495 closing_database_ = true;
496 if (safe_browsing_thread_.get()) {
497 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE,
498 NewRunnableMethod(this, &SafeBrowsingService::OnCloseDatabase));
499 }
500 }
501
502 void SafeBrowsingService::ResetDatabase() { 472 void SafeBrowsingService::ResetDatabase() {
503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
504 DCHECK(enabled_); 474 DCHECK(enabled_);
505 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 475 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
506 this, &SafeBrowsingService::OnResetDatabase)); 476 this, &SafeBrowsingService::OnResetDatabase));
507 } 477 }
508 478
509 void SafeBrowsingService::LogPauseDelay(base::TimeDelta time) { 479 void SafeBrowsingService::LogPauseDelay(base::TimeDelta time) {
510 UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time); 480 UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time);
511 } 481 }
512 482
513 SafeBrowsingService::~SafeBrowsingService() { 483 SafeBrowsingService::~SafeBrowsingService() {
514 // We should have already been shut down. If we're still enabled, then the 484 // We should have already been shut down. If we're still enabled, then the
515 // database isn't going to be closed properly, which could lead to corruption. 485 // database isn't going to be closed properly, which could lead to corruption.
516 DCHECK(!enabled_); 486 DCHECK(!enabled_);
517 } 487 }
518 488
519 void SafeBrowsingService::OnIOInitialize( 489 void SafeBrowsingService::OnIOInitialize(
520 const std::string& client_key, 490 const std::string& client_key,
521 const std::string& wrapped_key, 491 const std::string& wrapped_key,
522 net::URLRequestContextGetter* request_context_getter) { 492 net::URLRequestContextGetter* request_context_getter) {
523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
524 enabled_ = true; 494 enabled_ = true;
525 495
496 registrar_.Add(this, NotificationType::PURGE_MEMORY,
497 NotificationService::AllSources());
498
526 MakeDatabaseAvailable(); 499 MakeDatabaseAvailable();
527 500
528 // On Windows, get the safe browsing client name from the browser 501 // On Windows, get the safe browsing client name from the browser
529 // distribution classes in installer util. These classes don't yet have 502 // distribution classes in installer util. These classes don't yet have
530 // an analog on non-Windows builds so just keep the name specified here. 503 // an analog on non-Windows builds so just keep the name specified here.
531 #if defined(OS_WIN) 504 #if defined(OS_WIN)
532 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 505 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
533 std::string client_name(dist->GetSafeBrowsingName()); 506 std::string client_name(dist->GetSafeBrowsingName());
534 #else 507 #else
535 #if defined(GOOGLE_CHROME_BUILD) 508 #if defined(GOOGLE_CHROME_BUILD)
(...skipping 29 matching lines...) Expand all
565 protocol_manager_->Initialize(); 538 protocol_manager_->Initialize();
566 } 539 }
567 540
568 void SafeBrowsingService::OnIOShutdown() { 541 void SafeBrowsingService::OnIOShutdown() {
569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
570 if (!enabled_) 543 if (!enabled_)
571 return; 544 return;
572 545
573 enabled_ = false; 546 enabled_ = false;
574 547
548 registrar_.RemoveAll();
549
575 // This cancels all in-flight GetHash requests. 550 // This cancels all in-flight GetHash requests.
576 delete protocol_manager_; 551 delete protocol_manager_;
577 protocol_manager_ = NULL; 552 protocol_manager_ = NULL;
578 553
579 // Delete queued checks, calling back any clients with 'SAFE'. 554 // Delete queued checks, calling back any clients with 'SAFE'.
580 // If we don't do this here we may fail to close the database below. 555 // If we don't do this here we may fail to close the database below.
581 while (!queued_checks_.empty()) { 556 while (!queued_checks_.empty()) {
582 QueuedCheck queued = queued_checks_.front(); 557 QueuedCheck queued = queued_checks_.front();
583 if (queued.client) { 558 if (queued.client) {
584 SafeBrowsingCheck sb_check; 559 SafeBrowsingCheck sb_check;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 bool SafeBrowsingService::MakeDatabaseAvailable() { 610 bool SafeBrowsingService::MakeDatabaseAvailable() {
636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
637 DCHECK(enabled_); 612 DCHECK(enabled_);
638 if (DatabaseAvailable()) 613 if (DatabaseAvailable())
639 return true; 614 return true;
640 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, 615 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE,
641 NewRunnableMethod(this, &SafeBrowsingService::GetDatabase)); 616 NewRunnableMethod(this, &SafeBrowsingService::GetDatabase));
642 return false; 617 return false;
643 } 618 }
644 619
620 void SafeBrowsingService::CloseDatabase() {
621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
622
623 // Cases to avoid:
624 // * If |closing_database_| is true, continuing will queue up a second
625 // request, |closing_database_| will be reset after handling the first
626 // request, and if any functions on the db thread recreate the database, we
627 // could start using it on the IO thread and then have the second request
628 // handler delete it out from under us.
629 // * If |database_| is NULL, then either no creation request is in flight, in
630 // which case we don't need to do anything, or one is in flight, in which
631 // case the database will be recreated before our deletion request is
632 // handled, and could be used on the IO thread in that time period, leading
633 // to the same problem as above.
634 // * If |queued_checks_| is non-empty and |database_| is non-NULL, we're
635 // about to be called back (in DatabaseLoadComplete()). This will call
636 // CheckUrl(), which will want the database. Closing the database here
637 // would lead to an infinite loop in DatabaseLoadComplete(), and even if it
638 // didn't, it would be pointless since we'd just want to recreate.
639 //
640 // The first two cases above are handled by checking DatabaseAvailable().
641 if (!DatabaseAvailable() || !queued_checks_.empty())
642 return;
643
644 closing_database_ = true;
645 if (safe_browsing_thread_.get()) {
646 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE,
647 NewRunnableMethod(this, &SafeBrowsingService::OnCloseDatabase));
648 }
649 }
650
645 SafeBrowsingDatabase* SafeBrowsingService::GetDatabase() { 651 SafeBrowsingDatabase* SafeBrowsingService::GetDatabase() {
646 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 652 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
647 if (database_) 653 if (database_)
648 return database_; 654 return database_;
649 655
650 FilePath path; 656 FilePath path;
651 bool result = PathService::Get(chrome::DIR_USER_DATA, &path); 657 bool result = PathService::Get(chrome::DIR_USER_DATA, &path);
652 DCHECK(result); 658 DCHECK(result);
653 path = path.Append(chrome::kSafeBrowsingBaseFilename); 659 path = path.Append(chrome::kSafeBrowsingBaseFilename);
654 660
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 // Whitelist this domain and warning type for the given tab. 1201 // Whitelist this domain and warning type for the given tab.
1196 WhiteListedEntry entry; 1202 WhiteListedEntry entry;
1197 entry.render_process_host_id = resource.render_process_host_id; 1203 entry.render_process_host_id = resource.render_process_host_id;
1198 entry.render_view_id = resource.render_view_id; 1204 entry.render_view_id = resource.render_view_id;
1199 entry.domain = net::RegistryControlledDomainService::GetDomainAndRegistry( 1205 entry.domain = net::RegistryControlledDomainService::GetDomainAndRegistry(
1200 resource.url); 1206 resource.url);
1201 entry.result = resource.threat_type; 1207 entry.result = resource.threat_type;
1202 white_listed_entries_.push_back(entry); 1208 white_listed_entries_.push_back(entry);
1203 } 1209 }
1204 1210
1211 void SafeBrowsingService::Observe(NotificationType type,
1212 const NotificationSource& source,
1213 const NotificationDetails& details) {
1214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1215 DCHECK(type == NotificationType::PURGE_MEMORY);
1216 CloseDatabase();
1217 }
1218
1205 bool SafeBrowsingService::IsWhitelisted(const UnsafeResource& resource) { 1219 bool SafeBrowsingService::IsWhitelisted(const UnsafeResource& resource) {
1206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1207 // Check if the user has already ignored our warning for this render_view 1221 // Check if the user has already ignored our warning for this render_view
1208 // and domain. 1222 // and domain.
1209 for (size_t i = 0; i < white_listed_entries_.size(); ++i) { 1223 for (size_t i = 0; i < white_listed_entries_.size(); ++i) {
1210 const WhiteListedEntry& entry = white_listed_entries_[i]; 1224 const WhiteListedEntry& entry = white_listed_entries_[i];
1211 if (entry.render_process_host_id == resource.render_process_host_id && 1225 if (entry.render_process_host_id == resource.render_process_host_id &&
1212 entry.render_view_id == resource.render_view_id && 1226 entry.render_view_id == resource.render_view_id &&
1213 // Threat type must be the same or in the case of phishing they can 1227 // Threat type must be the same or in the case of phishing they can
1214 // either be client-side phishing URL or a SafeBrowsing phishing URL. 1228 // either be client-side phishing URL or a SafeBrowsing phishing URL.
1215 // If we show one type of phishing warning we don't want to show a 1229 // If we show one type of phishing warning we don't want to show a
1216 // second phishing warning. 1230 // second phishing warning.
1217 (entry.result == resource.threat_type || 1231 (entry.result == resource.threat_type ||
1218 (entry.result == URL_PHISHING && 1232 (entry.result == URL_PHISHING &&
1219 resource.threat_type == CLIENT_SIDE_PHISHING_URL) || 1233 resource.threat_type == CLIENT_SIDE_PHISHING_URL) ||
1220 (entry.result == CLIENT_SIDE_PHISHING_URL && 1234 (entry.result == CLIENT_SIDE_PHISHING_URL &&
1221 resource.threat_type == URL_PHISHING)) && 1235 resource.threat_type == URL_PHISHING)) &&
1222 entry.domain == 1236 entry.domain ==
1223 net::RegistryControlledDomainService::GetDomainAndRegistry( 1237 net::RegistryControlledDomainService::GetDomainAndRegistry(
1224 resource.url)) { 1238 resource.url)) {
1225 return true; 1239 return true;
1226 } 1240 }
1227 } 1241 }
1228 return false; 1242 return false;
1229 } 1243 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698