Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: rlz/lib/financial_ping.cc

Issue 10642009: Add a regenerate button to regenerate the password in Windows. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Sync and Merge. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « rlz/lib/financial_ping.h ('k') | rlz/lib/financial_ping_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 // Library functions related to the Financial Server ping.
6
7 #include "rlz/lib/financial_ping.h"
8
9 #include "base/basictypes.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/string_util.h"
12 #include "base/stringprintf.h"
13 #include "base/utf_string_conversions.h"
14 #include "rlz/lib/assert.h"
15 #include "rlz/lib/lib_values.h"
16 #include "rlz/lib/machine_id.h"
17 #include "rlz/lib/rlz_lib.h"
18 #include "rlz/lib/rlz_value_store.h"
19 #include "rlz/lib/string_utils.h"
20
21 #if !defined(OS_WIN)
22 #include "base/time.h"
23 #endif
24
25 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET)
26
27 #include <windows.h>
28 #include <wininet.h>
29
30 namespace {
31
32 class InternetHandle {
33 public:
34 InternetHandle(HINTERNET handle) { handle_ = handle; }
35 ~InternetHandle() { if (handle_) InternetCloseHandle(handle_); }
36 operator HINTERNET() const { return handle_; }
37 bool operator!() const { return (handle_ == NULL); }
38
39 private:
40 HINTERNET handle_;
41 };
42
43 } // namespace
44
45 #else
46
47 #include "base/bind.h"
48 #include "base/message_loop.h"
49 #include "base/time.h"
50 #include "googleurl/src/gurl.h"
51 #include "net/base/load_flags.h"
52 #include "net/url_request/url_fetcher.h"
53 #include "net/url_request/url_fetcher_delegate.h"
54 #include "net/url_request/url_request_context.h"
55 #include "net/url_request/url_request_context_getter.h"
56
57 #endif
58
59 namespace {
60
61 // Returns the time relative to a fixed point in the past in multiples of
62 // 100 ns stepts. The point in the past is arbitrary but can't change, as the
63 // result of this value is stored on disk.
64 int64 GetSystemTimeAsInt64() {
65 #if defined(OS_WIN)
66 FILETIME now_as_file_time;
67 // Relative to Jan 1, 1601 (UTC).
68 GetSystemTimeAsFileTime(&now_as_file_time);
69
70 LARGE_INTEGER integer;
71 integer.HighPart = now_as_file_time.dwHighDateTime;
72 integer.LowPart = now_as_file_time.dwLowDateTime;
73 return integer.QuadPart;
74 #else
75 // Seconds since epoch (Jan 1, 1970).
76 double now_seconds = base::Time::Now().ToDoubleT();
77 return static_cast<int64>(now_seconds * 1000 * 1000 * 10);
78 #endif
79 }
80
81 } // namespace
82
83
84 namespace rlz_lib {
85
86 bool FinancialPing::FormRequest(Product product,
87 const AccessPoint* access_points, const char* product_signature,
88 const char* product_brand, const char* product_id,
89 const char* product_lang, bool exclude_machine_id,
90 std::string* request) {
91 if (!request) {
92 ASSERT_STRING("FinancialPing::FormRequest: request is NULL");
93 return false;
94 }
95
96 request->clear();
97
98 ScopedRlzValueStoreLock lock;
99 RlzValueStore* store = lock.GetStore();
100 if (!store || !store->HasAccess(RlzValueStore::kReadAccess))
101 return false;
102
103 if (!access_points) {
104 ASSERT_STRING("FinancialPing::FormRequest: access_points is NULL");
105 return false;
106 }
107
108 if (!product_signature) {
109 ASSERT_STRING("FinancialPing::FormRequest: product_signature is NULL");
110 return false;
111 }
112
113 if (!SupplementaryBranding::GetBrand().empty()) {
114 if (SupplementaryBranding::GetBrand() != product_brand) {
115 ASSERT_STRING("FinancialPing::FormRequest: supplementary branding bad");
116 return false;
117 }
118 }
119
120 base::StringAppendF(request, "%s?", kFinancialPingPath);
121
122 // Add the signature, brand, product id and language.
123 base::StringAppendF(request, "%s=%s", kProductSignatureCgiVariable,
124 product_signature);
125 if (product_brand)
126 base::StringAppendF(request, "&%s=%s", kProductBrandCgiVariable,
127 product_brand);
128
129 if (product_id)
130 base::StringAppendF(request, "&%s=%s", kProductIdCgiVariable, product_id);
131
132 if (product_lang)
133 base::StringAppendF(request, "&%s=%s", kProductLanguageCgiVariable,
134 product_lang);
135
136 // Add the product events.
137 char cgi[kMaxCgiLength + 1];
138 cgi[0] = 0;
139 bool has_events = GetProductEventsAsCgi(product, cgi, arraysize(cgi));
140 if (has_events)
141 base::StringAppendF(request, "&%s", cgi);
142
143 // If we don't have any events, we should ping all the AP's on the system
144 // that we know about and have a current RLZ value, even if they are not
145 // used by this product.
146 AccessPoint all_points[LAST_ACCESS_POINT];
147 if (!has_events) {
148 char rlz[kMaxRlzLength + 1];
149 int idx = 0;
150 for (int ap = NO_ACCESS_POINT + 1; ap < LAST_ACCESS_POINT; ap++) {
151 rlz[0] = 0;
152 AccessPoint point = static_cast<AccessPoint>(ap);
153 if (GetAccessPointRlz(point, rlz, arraysize(rlz)) &&
154 rlz[0] != '\0')
155 all_points[idx++] = point;
156 }
157 all_points[idx] = NO_ACCESS_POINT;
158 }
159
160 // Add the RLZ's and the DCC if needed. This is the same as get PingParams.
161 // This will also include the RLZ Exchange Protocol CGI Argument.
162 cgi[0] = 0;
163 if (GetPingParams(product, has_events ? access_points : all_points,
164 cgi, arraysize(cgi)))
165 base::StringAppendF(request, "&%s", cgi);
166
167 if (has_events && !exclude_machine_id) {
168 std::string machine_id;
169 if (GetMachineId(&machine_id)) {
170 base::StringAppendF(request, "&%s=%s", kMachineIdCgiVariable,
171 machine_id.c_str());
172 }
173 }
174
175 return true;
176 }
177
178 #if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET)
179 // The URLRequestContextGetter used by FinancialPing::PingServer().
180 net::URLRequestContextGetter* g_context;
181
182 bool FinancialPing::SetURLRequestContext(
183 net::URLRequestContextGetter* context) {
184 ScopedRlzValueStoreLock lock;
185 RlzValueStore* store = lock.GetStore();
186 if (!store)
187 return false;
188
189 g_context = context;
190 return true;
191 }
192
193 namespace {
194
195 class FinancialPingUrlFetcherDelegate : public net::URLFetcherDelegate {
196 public:
197 FinancialPingUrlFetcherDelegate(MessageLoop* loop) : loop_(loop) { }
198 virtual void OnURLFetchComplete(const net::URLFetcher* source);
199 private:
200 MessageLoop* loop_;
201 };
202
203 void FinancialPingUrlFetcherDelegate::OnURLFetchComplete(
204 const net::URLFetcher* source) {
205 loop_->Quit();
206 }
207
208 } // namespace
209
210 #endif
211
212 bool FinancialPing::PingServer(const char* request, std::string* response) {
213 if (!response)
214 return false;
215
216 response->clear();
217
218 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET)
219 // Initialize WinInet.
220 InternetHandle inet_handle = InternetOpenA(kFinancialPingUserAgent,
221 INTERNET_OPEN_TYPE_PRECONFIG,
222 NULL, NULL, 0);
223 if (!inet_handle)
224 return false;
225
226 // Open network connection.
227 InternetHandle connection_handle = InternetConnectA(inet_handle,
228 kFinancialServer, kFinancialPort, "", "", INTERNET_SERVICE_HTTP,
229 INTERNET_FLAG_NO_CACHE_WRITE, 0);
230 if (!connection_handle)
231 return false;
232
233 // Prepare the HTTP request.
234 InternetHandle http_handle = HttpOpenRequestA(connection_handle,
235 "GET", request, NULL, NULL, kFinancialPingResponseObjects,
236 INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES, NULL);
237 if (!http_handle)
238 return false;
239
240 // Timeouts are probably:
241 // INTERNET_OPTION_SEND_TIMEOUT, INTERNET_OPTION_RECEIVE_TIMEOUT
242
243 // Send the HTTP request. Note: Fails if user is working in off-line mode.
244 if (!HttpSendRequest(http_handle, NULL, 0, NULL, 0))
245 return false;
246
247 // Check the response status.
248 DWORD status;
249 DWORD status_size = sizeof(status);
250 if (!HttpQueryInfo(http_handle, HTTP_QUERY_STATUS_CODE |
251 HTTP_QUERY_FLAG_NUMBER, &status, &status_size, NULL) ||
252 200 != status)
253 return false;
254
255 // Get the response text.
256 scoped_array<char> buffer(new char[kMaxPingResponseLength]);
257 if (buffer.get() == NULL)
258 return false;
259
260 DWORD bytes_read = 0;
261 while (InternetReadFile(http_handle, buffer.get(), kMaxPingResponseLength,
262 &bytes_read) && bytes_read > 0) {
263 response->append(buffer.get(), bytes_read);
264 bytes_read = 0;
265 };
266
267 return true;
268 #else
269 // Run a blocking event loop to match the win inet implementation.
270 MessageLoop loop;
271 FinancialPingUrlFetcherDelegate delegate(&loop);
272
273 std::string url = base::StringPrintf("http://%s:%d%s",
274 kFinancialServer, kFinancialPort,
275 request);
276
277 scoped_ptr<net::URLFetcher> fetcher(net::URLFetcher::Create(
278 GURL(url), net::URLFetcher::GET, &delegate));
279
280 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE |
281 net::LOAD_DO_NOT_SEND_AUTH_DATA |
282 net::LOAD_DO_NOT_PROMPT_FOR_LOGIN |
283 net::LOAD_DO_NOT_SEND_COOKIES |
284 net::LOAD_DO_NOT_SAVE_COOKIES);
285
286 // Ensure rlz_lib::SetURLRequestContext() has been called before sending
287 // pings.
288 CHECK(g_context);
289 fetcher->SetRequestContext(g_context);
290
291 const base::TimeDelta kTimeout = base::TimeDelta::FromMinutes(5);
292 loop.PostTask(
293 FROM_HERE,
294 base::Bind(&net::URLFetcher::Start, base::Unretained(fetcher.get())));
295 loop.PostNonNestableDelayedTask(
296 FROM_HERE, MessageLoop::QuitClosure(), kTimeout);
297
298 loop.Run();
299
300 if (fetcher->GetResponseCode() != 200)
301 return false;
302
303 return fetcher->GetResponseAsString(response);
304 #endif
305 }
306
307 bool FinancialPing::IsPingTime(Product product, bool no_delay) {
308 ScopedRlzValueStoreLock lock;
309 RlzValueStore* store = lock.GetStore();
310 if (!store || !store->HasAccess(RlzValueStore::kReadAccess))
311 return false;
312
313 int64 last_ping = 0;
314 if (!store->ReadPingTime(product, &last_ping))
315 return true;
316
317 uint64 now = GetSystemTimeAsInt64();
318 int64 interval = now - last_ping;
319
320 // If interval is negative, clock was probably reset. So ping.
321 if (interval < 0)
322 return true;
323
324 // Check if this product has any unreported events.
325 char cgi[kMaxCgiLength + 1];
326 cgi[0] = 0;
327 bool has_events = GetProductEventsAsCgi(product, cgi, arraysize(cgi));
328 if (no_delay && has_events)
329 return true;
330
331 return interval >= (has_events ? kEventsPingInterval : kNoEventsPingInterval);
332 }
333
334
335 bool FinancialPing::UpdateLastPingTime(Product product) {
336 ScopedRlzValueStoreLock lock;
337 RlzValueStore* store = lock.GetStore();
338 if (!store || !store->HasAccess(RlzValueStore::kWriteAccess))
339 return false;
340
341 uint64 now = GetSystemTimeAsInt64();
342 return store->WritePingTime(product, now);
343 }
344
345
346 bool FinancialPing::ClearLastPingTime(Product product) {
347 ScopedRlzValueStoreLock lock;
348 RlzValueStore* store = lock.GetStore();
349 if (!store || !store->HasAccess(RlzValueStore::kWriteAccess))
350 return false;
351 return store->ClearPingTime(product);
352 }
353
354 } // namespace
OLDNEW
« no previous file with comments | « rlz/lib/financial_ping.h ('k') | rlz/lib/financial_ping_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698