blob: 60c67718533536fd846b18ee9372a0c55cf85eb2 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h"
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"
namespace subresource_filter {
constexpr base::TimeDelta
SubresourceFilterSafeBrowsingClientRequest::kCheckURLTimeout;
SubresourceFilterSafeBrowsingClientRequest::
SubresourceFilterSafeBrowsingClientRequest(
size_t request_id,
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
SubresourceFilterSafeBrowsingClient* client)
: request_id_(request_id),
database_manager_(std::move(database_manager)),
client_(client) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
timer_.SetTaskRunner(std::move(io_task_runner));
}
SubresourceFilterSafeBrowsingClientRequest::
~SubresourceFilterSafeBrowsingClientRequest() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (!request_completed_)
database_manager_->CancelCheck(this);
timer_.Stop();
}
void SubresourceFilterSafeBrowsingClientRequest::Start(const GURL& url) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
start_time_ = base::TimeTicks::Now();
// Just return SAFE if the database is not supported.
bool synchronous_finish =
!database_manager_->IsSupported() ||
database_manager_->CheckUrlForSubresourceFilter(url, this);
if (synchronous_finish) {
request_completed_ = true;
SendCheckResultToClient(false /* served_from_network */,
safe_browsing::SB_THREAT_TYPE_SAFE,
safe_browsing::ThreatMetadata());
return;
}
timer_.Start(
FROM_HERE, kCheckURLTimeout,
base::BindOnce(
&SubresourceFilterSafeBrowsingClientRequest::OnCheckUrlTimeout,
base::Unretained(this)));
}
void SubresourceFilterSafeBrowsingClientRequest::OnCheckBrowseUrlResult(
const GURL& url,
safe_browsing::SBThreatType threat_type,
const safe_browsing::ThreatMetadata& metadata) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
request_completed_ = true;
SendCheckResultToClient(true /* served_from_network */, threat_type,
metadata);
}
void SubresourceFilterSafeBrowsingClientRequest::OnCheckUrlTimeout() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
SendCheckResultToClient(true /* served_from_network */,
safe_browsing::SB_THREAT_TYPE_SAFE,
safe_browsing::ThreatMetadata());
}
void SubresourceFilterSafeBrowsingClientRequest::SendCheckResultToClient(
bool served_from_network,
safe_browsing::SBThreatType threat_type,
const safe_browsing::ThreatMetadata& metadata) {
SubresourceFilterSafeBrowsingClient::CheckResult result;
result.request_id = request_id_;
result.threat_type = threat_type;
result.threat_metadata = metadata;
result.check_time = base::TimeTicks::Now() - start_time_;
// This memeber is separate from |request_completed_|, in that it just
// indicates that this request is done processing (due to completion or
// timeout).
result.finished = true;
UMA_HISTOGRAM_TIMES("SubresourceFilter.SafeBrowsing.CheckTime",
result.check_time);
// Will delete |this|.
client_->OnCheckBrowseUrlResult(this, result);
}
} // namespace subresource_filter