1 // Copyright 2016 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.
4
5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h"
6
7 #include <stdint.h>
8
9 #include "base/stl_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/time/time.h"
12 #include "base/version.h"
13 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
14 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
15 #include "components/data_reduction_proxy/core/common/version.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/url_util.h"
18 #include "net/http/http_response_headers.h"
19 #include "net/http/http_status_code.h"
20 #include "net/http/http_util.h"
21
22 #if defined(USE_GOOGLE_API_KEYS)
23 #include "google_apis/google_api_keys.h"
24 #endif
25
26 namespace data_reduction_proxy {
27
28 namespace {
29
30 #if defined(USE_GOOGLE_API_KEYS)
31 // Used in all Data Reduction Proxy URLs to specify API Key.
32 const char kApiKeyName[] = "key";
33 #endif
34
35 // Hostname used for the other bucket which consists of chrome-services traffic.
36 // This should be in sync with the same in DataReductionSiteBreakdownView.java
37 const char kOtherHostName[] = "Other";
38
39 } // namespace
40
41 namespace util {
42
ChromiumVersion()43 const char* ChromiumVersion() {
44 // Assert at compile time that the Chromium version is at least somewhat
45 // properly formed, e.g. the version string is at least as long as "0.0.0.0",
46 // and starts and ends with numeric digits. This is to prevent another
47 // regression like http://crbug.com/595471.
48 static_assert(base::size(PRODUCT_VERSION) >= base::size("0.0.0.0") &&
49 '0' <= PRODUCT_VERSION[0] && PRODUCT_VERSION[0] <= '9' &&
50 '0' <= PRODUCT_VERSION[base::size(PRODUCT_VERSION) - 2] &&
51 PRODUCT_VERSION[base::size(PRODUCT_VERSION) - 2] <= '9',
52 "PRODUCT_VERSION must be a string of the form "
53 "'MAJOR.MINOR.BUILD.PATCH', e.g. '1.2.3.4'. "
54 "PRODUCT_VERSION='" PRODUCT_VERSION "' is badly formed.");
55
56 return PRODUCT_VERSION;
57 }
58
GetChromiumBuildAndPatch(const std::string & version_string,std::string * build,std::string * patch)59 void GetChromiumBuildAndPatch(const std::string& version_string,
60 std::string* build,
61 std::string* patch) {
62 uint32_t build_number;
63 uint32_t patch_number;
64 GetChromiumBuildAndPatchAsInts(version_string, &build_number, &patch_number);
65 *build = base::NumberToString(build_number);
66 *patch = base::NumberToString(patch_number);
67 }
68
GetChromiumBuildAndPatchAsInts(const std::string & version_string,uint32_t * build,uint32_t * patch)69 void GetChromiumBuildAndPatchAsInts(const std::string& version_string,
70 uint32_t* build,
71 uint32_t* patch) {
72 base::Version version(version_string);
73 DCHECK(version.IsValid());
74 DCHECK_EQ(4U, version.components().size());
75 *build = version.components()[2];
76 *patch = version.components()[3];
77 }
78
GetStringForClient(Client client)79 const char* GetStringForClient(Client client) {
80 switch (client) {
81 case Client::UNKNOWN:
82 return "";
83 case Client::CRONET_ANDROID:
84 return "cronet";
85 case Client::WEBVIEW_ANDROID:
86 return "webview";
87 case Client::CHROME_ANDROID:
88 return "android";
89 case Client::CHROME_IOS:
90 return "ios";
91 case Client::CHROME_MAC:
92 return "mac";
93 case Client::CHROME_CHROMEOS:
94 return "chromeos";
95 case Client::CHROME_LINUX:
96 return "linux";
97 case Client::CHROME_WINDOWS:
98 return "win";
99 case Client::CHROME_DRAGONFLY:
100 return "dragonfly";
101 case Client::CHROME_FREEBSD:
102 return "freebsd";
103 case Client::CHROME_OPENBSD:
104 return "openbsd";
105 case Client::CHROME_SOLARIS:
106 return "solaris";
107 case Client::CHROME_QNX:
108 return "qnx";
109 default:
110 NOTREACHED();
111 return "";
112 }
113 }
114
AddApiKeyToUrl(const GURL & url)115 GURL AddApiKeyToUrl(const GURL& url) {
116 GURL new_url = url;
117 #if defined(USE_GOOGLE_API_KEYS)
118 std::string api_key = google_apis::GetAPIKey();
119 if (google_apis::HasAPIKeyConfigured() && !api_key.empty()) {
120 new_url = net::AppendOrReplaceQueryParameter(url, kApiKeyName, api_key);
121 }
122 #endif
123 return net::AppendOrReplaceQueryParameter(new_url, "alt", "proto");
124 }
125
GetSiteBreakdownOtherHostName()126 const char* GetSiteBreakdownOtherHostName() {
127 return kOtherHostName;
128 }
129
130 } // namespace util
131
132 namespace protobuf_parser {
133
SchemeFromPrefetchScheme(PrefetchProxyConfig_Proxy_Scheme proxy_scheme)134 std::string SchemeFromPrefetchScheme(
135 PrefetchProxyConfig_Proxy_Scheme proxy_scheme) {
136 switch (proxy_scheme) {
137 case PrefetchProxyConfig_Proxy_Scheme_HTTP:
138 return "http";
139 case PrefetchProxyConfig_Proxy_Scheme_HTTPS:
140 return "https";
141 default:
142 return std::string();
143 }
144 }
145
TimeDeltaToDuration(const base::TimeDelta & time_delta,Duration * duration)146 void TimeDeltaToDuration(const base::TimeDelta& time_delta,
147 Duration* duration) {
148 duration->set_seconds(time_delta.InSeconds());
149 base::TimeDelta partial_seconds =
150 time_delta - base::TimeDelta::FromSeconds(time_delta.InSeconds());
151 duration->set_nanos(partial_seconds.InMicroseconds() *
152 base::Time::kNanosecondsPerMicrosecond);
153 }
154
DurationToTimeDelta(const Duration & duration)155 base::TimeDelta DurationToTimeDelta(const Duration& duration) {
156 return base::TimeDelta::FromSeconds(duration.seconds()) +
157 base::TimeDelta::FromMicroseconds(
158 duration.nanos() / base::Time::kNanosecondsPerMicrosecond);
159 }
160
TimeToTimestamp(const base::Time & time,Timestamp * timestamp)161 void TimeToTimestamp(const base::Time& time, Timestamp* timestamp) {
162 timestamp->set_seconds((time - base::Time::UnixEpoch()).InSeconds());
163 timestamp->set_nanos(((time - base::Time::UnixEpoch()).InMicroseconds() %
164 base::Time::kMicrosecondsPerSecond) *
165 base::Time::kNanosecondsPerMicrosecond);
166 }
167
TimestampToTime(const Timestamp & timestamp)168 base::Time TimestampToTime(const Timestamp& timestamp) {
169 base::Time t = base::Time::UnixEpoch();
170 t += base::TimeDelta::FromSeconds(timestamp.seconds());
171 t += base::TimeDelta::FromMicroseconds(
172 timestamp.nanos() / base::Time::kNanosecondsPerMicrosecond);
173 return t;
174 }
175
CreateDurationFromTimeDelta(const base::TimeDelta & time_delta)176 std::unique_ptr<Duration> CreateDurationFromTimeDelta(
177 const base::TimeDelta& time_delta) {
178 std::unique_ptr<Duration> duration(new Duration);
179 TimeDeltaToDuration(time_delta, duration.get());
180 return duration;
181 }
182
CreateTimestampFromTime(const base::Time & time)183 std::unique_ptr<Timestamp> CreateTimestampFromTime(const base::Time& time) {
184 std::unique_ptr<Timestamp> timestamp(new Timestamp);
185 TimeToTimestamp(time, timestamp.get());
186 return timestamp;
187 }
188
189 } // namespace protobuf_parser
190
191 } // namespace data_reduction_proxy
192