1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/remote_database_manager.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "base/timer/elapsed_timer.h"
11 #include "chrome/browser/safe_browsing/safe_browsing_api_handler.h"
12 #include "content/public/browser/browser_thread.h"
14 using content::BrowserThread
;
17 // RemoteSafeBrowsingDatabaseManager::ClientRequest methods
19 class RemoteSafeBrowsingDatabaseManager::ClientRequest
{
21 ClientRequest(Client
* client
,
22 RemoteSafeBrowsingDatabaseManager
* db_manager
,
25 static void OnRequestDoneWeak(const base::WeakPtr
<ClientRequest
>& req
,
26 SBThreatType matched_threat_type
,
27 const std::string
& metadata
);
28 void OnRequestDone(SBThreatType matched_threat_type
,
29 const std::string
& metadata
);
32 Client
* client() const { return client_
; }
33 const GURL
& url() const { return url_
; }
34 base::WeakPtr
<ClientRequest
> GetWeakPtr() {
35 return weak_factory_
.GetWeakPtr();
40 RemoteSafeBrowsingDatabaseManager
* db_manager_
;
42 base::ElapsedTimer timer_
;
43 base::WeakPtrFactory
<ClientRequest
> weak_factory_
;
46 RemoteSafeBrowsingDatabaseManager::ClientRequest::ClientRequest(
48 RemoteSafeBrowsingDatabaseManager
* db_manager
,
50 : client_(client
), db_manager_(db_manager
), url_(url
), weak_factory_(this) {
54 void RemoteSafeBrowsingDatabaseManager::ClientRequest::OnRequestDoneWeak(
55 const base::WeakPtr
<ClientRequest
>& req
,
56 SBThreatType matched_threat_type
,
57 const std::string
& metadata
) {
58 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
60 return; // Previously canceled
61 req
->OnRequestDone(matched_threat_type
, metadata
);
64 void RemoteSafeBrowsingDatabaseManager::ClientRequest::OnRequestDone(
65 SBThreatType matched_threat_type
,
66 const std::string
& metadata
) {
67 DVLOG(1) << "OnRequestDone took " << timer_
.Elapsed().InMilliseconds()
68 << " ms for client " << client_
<< " and URL " << url_
;
69 client_
->OnCheckBrowseUrlResult(url_
, matched_threat_type
, metadata
);
70 UMA_HISTOGRAM_TIMES("SB2.RemoteCall.Elapsed", timer_
.Elapsed());
71 // CancelCheck() will delete *this.
72 db_manager_
->CancelCheck(client_
);
76 // RemoteSafeBrowsingDatabaseManager methods
79 // TODO(nparker): Add tests for this class
80 RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager()
82 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
85 RemoteSafeBrowsingDatabaseManager::~RemoteSafeBrowsingDatabaseManager() {
89 bool RemoteSafeBrowsingDatabaseManager::CanCheckUrl(const GURL
& url
) const {
90 return url
.SchemeIs(url::kHttpsScheme
) || url
.SchemeIs(url::kHttpScheme
) ||
91 url
.SchemeIs(url::kFtpScheme
);
94 bool RemoteSafeBrowsingDatabaseManager::download_protection_enabled()
99 bool RemoteSafeBrowsingDatabaseManager::CheckDownloadUrl(
100 const std::vector
<GURL
>& url_chain
,
106 bool RemoteSafeBrowsingDatabaseManager::CheckExtensionIDs(
107 const std::set
<std::string
>& extension_ids
,
113 bool RemoteSafeBrowsingDatabaseManager::MatchMalwareIP(
114 const std::string
& ip_address
) {
119 bool RemoteSafeBrowsingDatabaseManager::MatchCsdWhitelistUrl(const GURL
& url
) {
124 bool RemoteSafeBrowsingDatabaseManager::MatchDownloadWhitelistUrl(
130 bool RemoteSafeBrowsingDatabaseManager::MatchDownloadWhitelistString(
131 const std::string
& str
) {
136 bool RemoteSafeBrowsingDatabaseManager::MatchInclusionWhitelistUrl(
142 bool RemoteSafeBrowsingDatabaseManager::IsMalwareKillSwitchOn() {
147 bool RemoteSafeBrowsingDatabaseManager::IsCsdWhitelistKillSwitchOn() {
152 bool RemoteSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL
& url
,
154 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
158 bool can_check_url
= CanCheckUrl(url
);
159 UMA_HISTOGRAM_BOOLEAN("SB2.RemoteCall.CanCheckUrl", can_check_url
);
161 return true; // Safe, continue right away.
163 scoped_ptr
<ClientRequest
> req(new ClientRequest(client
, this, url
));
164 std::vector
<SBThreatType
> threat_types
; // Not currently used.
166 DVLOG(1) << "Checking for client " << client
<< " and URL " << url
;
167 SafeBrowsingApiHandler
* api_handler
= SafeBrowsingApiHandler::GetInstance();
168 // If your build hits this at run time, then you should have either not built
169 // with safe_browsing=3, or set a SafeBrowingApiHandler singleton at startup.
170 DCHECK(api_handler
) << "SafeBrowsingApiHandler was never constructed";
171 api_handler
->StartURLCheck(
172 base::Bind(&ClientRequest::OnRequestDoneWeak
, req
->GetWeakPtr()), url
,
175 UMA_HISTOGRAM_COUNTS_10000("SB2.RemoteCall.ChecksPending",
176 current_requests_
.size());
177 current_requests_
.push_back(req
.release());
179 // Defer the resource load.
183 void RemoteSafeBrowsingDatabaseManager::CancelCheck(Client
* client
) {
184 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
186 for (auto itr
= current_requests_
.begin(); itr
!= current_requests_
.end();
188 if ((*itr
)->client() == client
) {
189 DVLOG(2) << "Canceling check for URL " << (*itr
)->url();
191 current_requests_
.erase(itr
);
198 void RemoteSafeBrowsingDatabaseManager::StartOnIOThread() {
199 VLOG(1) << "RemoteSafeBrowsingDatabaseManager starting";
203 void RemoteSafeBrowsingDatabaseManager::StopOnIOThread(bool shutdown
) {
204 // |shutdown| is not used.
205 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
206 DVLOG(1) << "RemoteSafeBrowsingDatabaseManager stopping";
208 // Call back and delete any remaining clients. OnRequestDone() modifies
209 // |current_requests_|, so we make a copy first.
210 std::vector
<ClientRequest
*> to_callback(current_requests_
);
211 for (auto req
: to_callback
) {
212 DVLOG(1) << "Stopping: Invoking unfinished req for URL " << req
->url();
213 req
->OnRequestDone(SB_THREAT_TYPE_SAFE
, std::string());