Index: chrome/browser/safe_browsing/browser_feature_extractor.cc |
diff --git a/chrome/browser/safe_browsing/browser_feature_extractor.cc b/chrome/browser/safe_browsing/browser_feature_extractor.cc |
index 29e70336f998fb1e83251d79f797594e49c23d47..b35fee338724ff020caafdde8f16994299b250d0 100644 |
--- a/chrome/browser/safe_browsing/browser_feature_extractor.cc |
+++ b/chrome/browser/safe_browsing/browser_feature_extractor.cc |
@@ -19,7 +19,8 @@ |
#include "chrome/browser/history/history_types.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/safe_browsing/browser_features.h" |
-#include "chrome/browser/safe_browsing/client_side_detection_service.h" |
+#include "chrome/browser/safe_browsing/client_side_detection_host.h" |
+#include "chrome/browser/safe_browsing/database_manager.h" |
#include "chrome/common/safe_browsing/csd.pb.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/navigation_controller.h" |
@@ -35,7 +36,25 @@ using content::WebContents; |
namespace safe_browsing { |
-const int BrowserFeatureExtractor::kMaxMalwareIPPerRequest = 5; |
+namespace { |
+ |
+const int kMaxMalwareIPPerRequest = 5; |
+ |
+void FilterBenignIpsOnIOThread( |
+ scoped_refptr<SafeBrowsingDatabaseManager> database_manager, |
+ IPUrlMap* ips) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ for (IPUrlMap::iterator it = ips->begin(); it != ips->end();) { |
+ if (!database_manager.get() || |
+ !database_manager->MatchMalwareIP(it->first)) { |
+ // it++ here returns a copy of the old iterator and passes it to erase. |
+ ips->erase(it++); |
+ } else { |
+ ++it; |
+ } |
+ } |
+} |
+} // namespace |
BrowseInfo::BrowseInfo() : http_status_code(0) {} |
@@ -132,9 +151,9 @@ static void AddNavigationFeatures( |
BrowserFeatureExtractor::BrowserFeatureExtractor( |
WebContents* tab, |
- ClientSideDetectionService* service) |
+ ClientSideDetectionHost* host) |
: tab_(tab), |
- service_(service), |
+ host_(host), |
weak_factory_(this) { |
DCHECK(tab); |
} |
@@ -169,11 +188,6 @@ void BrowserFeatureExtractor::ExtractFeatures(const BrowseInfo* info, |
DCHECK(info); |
DCHECK_EQ(0U, request->url().find("http:")); |
DCHECK(!callback.is_null()); |
- if (callback.is_null()) { |
- DLOG(ERROR) << "ExtractFeatures called without a callback object"; |
- return; |
- } |
- |
// Extract features pertaining to this navigation. |
const NavigationController& controller = tab_->GetController(); |
int url_index = -1; |
@@ -230,42 +244,39 @@ void BrowserFeatureExtractor::ExtractFeatures(const BrowseInfo* info, |
} |
void BrowserFeatureExtractor::ExtractMalwareFeatures( |
- const BrowseInfo* info, |
- ClientMalwareRequest* request) { |
+ BrowseInfo* info, |
+ ClientMalwareRequest* request, |
+ const MalwareDoneCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(request); |
- DCHECK(info); |
DCHECK_EQ(0U, request->url().find("http:")); |
- // get the IPs and urls that match the malware blacklisted IP list. |
- if (service_) { |
- int matched_bad_ips = 0; |
- for (IPUrlMap::const_iterator it = info->ips.begin(); |
- it != info->ips.end(); ++it) { |
- if (service_->IsBadIpAddress(it->first)) { |
- AddMalwareFeature(features::kBadIpFetch + it->first, |
- it->second, 1.0, request); |
- ++matched_bad_ips; |
- // Limit the number of matched bad IPs in one request to control |
- // the request's size |
- if (matched_bad_ips >= kMaxMalwareIPPerRequest) { |
- return; |
- } |
- } |
- } |
- } |
+ DCHECK(!callback.is_null()); |
+ |
+ // Grab the IPs because they might go away before we're done |
+ // checking them against the IP blacklist on the IO thread. |
+ scoped_ptr<IPUrlMap> ips(new IPUrlMap); |
+ ips->swap(info->ips); |
+ |
+ IPUrlMap* ips_ptr = ips.get(); |
+ |
+ // The API doesn't take a scoped_ptr because the API gets mocked and we |
+ // cannot mock an API that takes scoped_ptr as arguments. |
+ scoped_ptr<ClientMalwareRequest> req(request); |
+ |
+ // IP blacklist lookups have to happen on the IO thread. |
+ BrowserThread::PostTaskAndReply( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&FilterBenignIpsOnIOThread, |
+ host_->database_manager(), |
+ ips_ptr), |
+ base::Bind(&BrowserFeatureExtractor::FinishExtractMalwareFeatures, |
+ weak_factory_.GetWeakPtr(), |
+ base::Passed(&ips), callback, base::Passed(&req))); |
} |
void BrowserFeatureExtractor::ExtractBrowseInfoFeatures( |
const BrowseInfo& info, |
ClientPhishingRequest* request) { |
- if (service_) { |
- for (IPUrlMap::const_iterator it = info.ips.begin(); |
- it != info.ips.end(); ++it) { |
- if (service_->IsBadIpAddress(it->first)) { |
- AddFeature(features::kBadIpFetch + it->first, 1.0, request); |
- } |
- } |
- } |
if (info.unsafe_resource.get()) { |
// A SafeBrowsing interstitial was shown for the current URL. |
AddFeature(features::kSafeBrowsingMaliciousUrl + |
@@ -495,4 +506,24 @@ bool BrowserFeatureExtractor::GetHistoryService(HistoryService** history) { |
return false; |
} |
+void BrowserFeatureExtractor::FinishExtractMalwareFeatures( |
+ scoped_ptr<IPUrlMap> bad_ips, |
+ MalwareDoneCallback callback, |
+ scoped_ptr<ClientMalwareRequest> request) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ int matched_bad_ips = 0; |
+ for (IPUrlMap::const_iterator it = bad_ips->begin(); |
+ it != bad_ips->end(); ++it) { |
+ AddMalwareFeature(features::kBadIpFetch + it->first, |
+ it->second, 1.0, request.get()); |
+ ++matched_bad_ips; |
+ // Limit the number of matched bad IPs in one request to control |
+ // the request's size |
+ if (matched_bad_ips >= kMaxMalwareIPPerRequest) { |
+ break; |
+ } |
+ } |
+ callback.Run(true, request.Pass()); |
+} |
+ |
} // namespace safe_browsing |