summaryrefslogtreecommitdiffstats
path: root/components/safe_browsing_db/v4_protocol_manager_util.cc
blob: 2dddc161e563115576fe844dd36e1e4dd36dfdde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// 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);
}

// 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