blob: ec2de4cc6720c83db198845a552c65a227c69880 [file] [log] [blame]
// Copyright 2016 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/safe_browsing_db/v4_protocol_manager_util.h"
#include "base/base64.h"
#include "base/metrics/sparse_histogram.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "net/base/escape.h"
using base::Time;
using base::TimeDelta;
namespace safe_browsing {
// The Safe Browsing V4 server URL prefix.
const char kSbV4UrlPrefix[] = "https://safebrowsing.googleapis.com/v4";
bool UpdateListIdentifier::operator==(const UpdateListIdentifier& other) const {
return platform_type == other.platform_type &&
threat_entry_type == other.threat_entry_type &&
threat_type == other.threat_type;
}
bool UpdateListIdentifier::operator!=(const UpdateListIdentifier& other) const {
return !operator==(other);
}
size_t UpdateListIdentifier::hash() const {
std::size_t first = std::hash<unsigned int>()(platform_type);
std::size_t second = std::hash<unsigned int>()(threat_entry_type);
std::size_t third = std::hash<unsigned int>()(threat_type);
std::size_t interim = base::HashInts(first, second);
return base::HashInts(interim, third);
}
V4ProtocolConfig::V4ProtocolConfig() : disable_auto_update(false) {}
V4ProtocolConfig::V4ProtocolConfig(const V4ProtocolConfig& other) = default;
V4ProtocolConfig::~V4ProtocolConfig() {}
// static
// Backoff interval is MIN(((2^(n-1))*15 minutes) * (RAND + 1), 24 hours) where
// n is the number of consecutive errors.
base::TimeDelta V4ProtocolManagerUtil::GetNextBackOffInterval(
size_t* error_count,
size_t* multiplier) {
DCHECK(multiplier && error_count);
(*error_count)++;
if (*error_count > 1 && *error_count < 9) {
// With error count 9 and above we will hit the 24 hour max interval.
// Cap the multiplier here to prevent integer overflow errors.
*multiplier *= 2;
}
base::TimeDelta next =
base::TimeDelta::FromMinutes(*multiplier * (1 + base::RandDouble()) * 15);
base::TimeDelta day = base::TimeDelta::FromHours(24);
if (next < day)
return next;
else
return day;
}
// static
void V4ProtocolManagerUtil::RecordHttpResponseOrErrorCode(
const char* metric_name,
const net::URLRequestStatus& status,
int response_code) {
UMA_HISTOGRAM_SPARSE_SLOWLY(
metric_name, status.is_success() ? response_code : status.error());
}
// static
// The API hash call uses the pver4 Safe Browsing server.
GURL V4ProtocolManagerUtil::GetRequestUrl(const std::string& request_base64,
const std::string& method_name,
const V4ProtocolConfig& config) {
std::string url =
ComposeUrl(kSbV4UrlPrefix, method_name, request_base64,
config.client_name, config.version, config.key_param);
return GURL(url);
}
// static
std::string V4ProtocolManagerUtil::ComposeUrl(const std::string& prefix,
const std::string& method,
const std::string& request_base64,
const std::string& client_id,
const std::string& version,
const std::string& key_param) {
DCHECK(!prefix.empty() && !method.empty() && !client_id.empty() &&
!version.empty());
std::string url =
base::StringPrintf("%s/%s/%s?alt=proto&client_id=%s&client_version=%s",
prefix.c_str(), method.c_str(), request_base64.c_str(),
client_id.c_str(), version.c_str());
if (!key_param.empty()) {
base::StringAppendF(&url, "&key=%s",
net::EscapeQueryParamValue(key_param, true).c_str());
}
return url;
}
} // namespace safe_browsing