15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A library to manage RLZ information for access-points shared 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// across different client applications. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/rlz_lib.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/assert.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/crc32.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/financial_ping.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/lib_values.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/rlz_value_store.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/string_utils.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Event information returned from ping response. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ReturnedEvent { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::AccessPoint access_point; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::Event event_type; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsAccessPointSupported(rlz_lib::AccessPoint point) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (point) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::NO_ACCESS_POINT: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::LAST_ACCESS_POINT: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::MOBILE_IDLE_SCREEN_BLACKBERRY: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::MOBILE_IDLE_SCREEN_WINMOB: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::MOBILE_IDLE_SCREEN_SYMBIAN: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These AP's are never available on Windows PCs. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::IE_DEFAULT_SEARCH: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::IE_HOME_PAGE: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::IETB_SEARCH_BOX: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::QUICK_SEARCH_BOX: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::GD_DESKBAND: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::GD_SEARCH_GADGET: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::GD_WEB_SERVER: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::GD_OUTLOOK: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::CHROME_OMNIBOX: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case rlz_lib::CHROME_HOME_PAGE: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO: Figure out when these settings are set to Google. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Current RLZ can only use [a-zA-Z0-9_\-] 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We will be more liberal and allow some additional chars, but not url meta 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chars. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsGoodRlzChar(const char ch) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsAsciiAlpha(ch) || IsAsciiDigit(ch)) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (ch) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '_': 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '-': 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '!': 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '@': 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '$': 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '*': 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '(': 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ')': 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ';': 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '.': 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '<': 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '>': 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function will remove bad rlz chars and also limit the max rlz to some 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reasonable size. It also assumes that normalized_rlz is at least 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// kMaxRlzLength+1 long. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NormalizeRlz(const char* raw_rlz, char* normalized_rlz) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = 0; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; raw_rlz[index] != 0 && index < rlz_lib::kMaxRlzLength; ++index) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char current = raw_rlz[index]; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsGoodRlzChar(current)) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) normalized_rlz[index] = current; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) normalized_rlz[index] = '.'; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) normalized_rlz[index] = 0; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetEventsFromResponseString( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& response_line, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& field_header, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ReturnedEvent>* event_array) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the string of events. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string events = response_line.substr(field_header.size()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespaceASCII(events, TRIM_LEADING, &events); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int events_length = events.find_first_of("\r\n "); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events_length < 0) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_length = events.size(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events = events.substr(0, events_length); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Break this up into individual events 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int event_end_index = -1; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int event_begin = event_end_index + 1; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_end_index = events.find(rlz_lib::kEventsCgiSeparator, event_begin); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int event_end = event_end_index; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_end < 0) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_end = events_length; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_string = events.substr(event_begin, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_end - event_begin); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_string.size() != 3) // 3 = 2(AP) + 1(E) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::AccessPoint point = rlz_lib::NO_ACCESS_POINT; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::Event event = rlz_lib::INVALID_EVENT; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetAccessPointFromName(event_string.substr(0, 2).c_str(), &point) || 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) point == rlz_lib::NO_ACCESS_POINT) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetEventFromName(event_string.substr(event_string.size() - 1).c_str(), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &event) || event == rlz_lib::INVALID_EVENT) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReturnedEvent current_event = {point, event}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_array->push_back(current_event); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (event_end_index >= 0); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Event storage functions. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RecordStatefulEvent(rlz_lib::Product product, rlz_lib::AccessPoint point, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::Event event) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::ScopedRlzValueStoreLock lock; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::RlzValueStore* store = lock.GetStore(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(rlz_lib::RlzValueStore::kWriteAccess)) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the new event to the value store. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* point_name = GetAccessPointName(point); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_name = GetEventName(event); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!point_name || !event_name) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!point_name[0] || !event_name[0]) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string new_event_value; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&new_event_value, "%s%s", point_name, event_name); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return store->AddStatefulEvent(product, new_event_value.c_str()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetProductEventsAsCgiHelper(rlz_lib::Product product, char* cgi, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t cgi_size, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::RlzValueStore* store) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepend the CGI param key to the buffer. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cgi_arg; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&cgi_arg, "%s=", rlz_lib::kEventsCgiVariable); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cgi_size <= cgi_arg.size()) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (index = 0; index < cgi_arg.size(); ++index) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[index] = cgi_arg[index]; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read stored events. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> events; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store->ReadProductEvents(product, &events)) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append the events to the buffer. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_values = 0; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (num_values = 0; num_values < events.size(); ++num_values) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[index] = '\0'; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int divider = num_values > 0 ? 1 : 0; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = cgi_size - (index + divider); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size <= 0) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cgi_size >= (rlz_lib::kMaxCgiLength + 1); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(cgi + index + divider, events[num_values].c_str(), size); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (divider) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[index] = rlz_lib::kEventsCgiSeparator; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index += std::min((int)events[num_values].length(), size) + divider; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[index] = '\0'; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return num_values > 0; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace rlz_lib { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetURLRequestContext(net::URLRequestContextGetter* context) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FinancialPing::SetURLRequestContext(context); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetProductEventsAsCgi(Product product, char* cgi, size_t cgi_size) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cgi || cgi_size <= 0) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("GetProductEventsAsCgi: Invalid buffer"); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[0] = 0; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedRlzValueStoreLock lock; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RlzValueStore* store = lock.GetStore(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(RlzValueStore::kReadAccess)) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size_local = std::min( 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(kMaxCgiLength + 1), cgi_size); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = GetProductEventsAsCgiHelper(product, cgi, size_local, store); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("GetProductEventsAsCgi: Possibly insufficient buffer size"); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[0] = 0; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RecordProductEvent(Product product, AccessPoint point, Event event) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedRlzValueStoreLock lock; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RlzValueStore* store = lock.GetStore(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(RlzValueStore::kWriteAccess)) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get this event's value. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* point_name = GetAccessPointName(point); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_name = GetEventName(event); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!point_name || !event_name) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!point_name[0] || !event_name[0]) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string new_event_value; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&new_event_value, "%s%s", point_name, event_name); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check whether this event is a stateful event. If so, don't record it. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (store->IsStatefulEvent(product, new_event_value.c_str())) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For a stateful event we skip recording, this function is also 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // considered successful. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the new event to the value store. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return store->AddProductEvent(product, new_event_value.c_str()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ClearProductEvent(Product product, AccessPoint point, Event event) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedRlzValueStoreLock lock; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RlzValueStore* store = lock.GetStore(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(RlzValueStore::kWriteAccess)) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the event's value store value and delete it. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* point_name = GetAccessPointName(point); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_name = GetEventName(event); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!point_name || !event_name) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!point_name[0] || !event_name[0]) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_value; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&event_value, "%s%s", point_name, event_name); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return store->ClearProductEvent(product, event_value.c_str()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RLZ storage functions. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetAccessPointRlz(AccessPoint point, char* rlz, size_t rlz_size) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rlz || rlz_size <= 0) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("GetAccessPointRlz: Invalid buffer"); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz[0] = 0; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedRlzValueStoreLock lock; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RlzValueStore* store = lock.GetStore(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(RlzValueStore::kReadAccess)) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsAccessPointSupported(point)) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return store->ReadAccessPointRlz(point, rlz, rlz_size); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetAccessPointRlz(AccessPoint point, const char* new_rlz) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedRlzValueStoreLock lock; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RlzValueStore* store = lock.GetStore(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(RlzValueStore::kWriteAccess)) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!new_rlz) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("SetAccessPointRlz: Invalid buffer"); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return false if the access point is not set to Google. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsAccessPointSupported(point)) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING(("SetAccessPointRlz: " 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cannot set RLZ for unsupported access point.")); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the RLZ length. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t rlz_length = strlen(new_rlz); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rlz_length > kMaxRlzLength) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("SetAccessPointRlz: RLZ length is exceeds max allowed."); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char normalized_rlz[kMaxRlzLength + 1]; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NormalizeRlz(new_rlz, normalized_rlz); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VERIFY(strlen(new_rlz) == rlz_length); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setting RLZ to empty == clearing. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (normalized_rlz[0] == 0) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return store->ClearAccessPointRlz(point); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return store->WriteAccessPointRlz(point, normalized_rlz); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Financial Server pinging functions. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FormFinancialPingRequest(Product product, const AccessPoint* access_points, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_signature, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_brand, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_id, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_lang, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool exclude_machine_id, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* request, size_t request_buffer_size) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request || request_buffer_size == 0) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request[0] = 0; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string request_string; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinancialPing::FormRequest(product, access_points, product_signature, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_brand, product_id, product_lang, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude_machine_id, &request_string)) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_string.size() >= request_buffer_size) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(request, request_string.c_str(), request_buffer_size); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request[request_buffer_size - 1] = 0; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PingFinancialServer(Product product, const char* request, char* response, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t response_buffer_size) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response || response_buffer_size == 0) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response[0] = 0; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the time is right to ping. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinancialPing::IsPingTime(product, false)) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send out the ping. 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_string; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinancialPing::PingServer(request, &response_string)) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_string.size() >= response_buffer_size) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(response, response_string.c_str(), response_buffer_size); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response[response_buffer_size - 1] = 0; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsPingResponseValid(const char* response, int* checksum_idx) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response || !response[0]) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (checksum_idx) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *checksum_idx = -1; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strlen(response) > kMaxPingResponseLength) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("IsPingResponseValid: response is too long to parse."); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the checksum line. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_string(response); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string checksum_param("\ncrc32: "); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int calculated_crc; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int checksum_index = response_string.find(checksum_param); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (checksum_index >= 0) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculate checksum of message preceeding checksum line. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (+ 1 to include the \n) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string message(response_string.substr(0, checksum_index + 1)); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Crc32(message.c_str(), &calculated_crc)) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum_param = "crc32: "; // Empty response case. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StartsWithASCII(response_string, checksum_param, true)) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum_index = 0; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Crc32("", &calculated_crc)) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the checksum value on the response. 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int checksum_end = response_string.find("\n", checksum_index + 1); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (checksum_end < 0) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum_end = response_string.size(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int checksum_begin = checksum_index + checksum_param.size(); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string checksum = response_string.substr(checksum_begin, 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum_end - checksum_begin + 1); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespaceASCII(checksum, TRIM_ALL, &checksum); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (checksum_idx) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *checksum_idx = checksum_index; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return calculated_crc == HexStringToInteger(checksum.c_str()); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Complex helpers built on top of other functions. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseFinancialPingResponse(Product product, const char* response) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the last ping time irrespective of success. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FinancialPing::UpdateLastPingTime(product); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the ping response - update RLZs, clear events. 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ParsePingResponse(product, response); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SendFinancialPing(Product product, const AccessPoint* access_points, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_signature, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_brand, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_id, const char* product_lang, 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool exclude_machine_id) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SendFinancialPing(product, access_points, product_signature, 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_brand, product_id, product_lang, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude_machine_id, false); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SendFinancialPing(Product product, const AccessPoint* access_points, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_signature, 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_brand, 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* product_id, const char* product_lang, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool exclude_machine_id, 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool skip_time_check) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the financial ping request. 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string request; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinancialPing::FormRequest(product, access_points, product_signature, 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_brand, product_id, product_lang, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude_machine_id, &request)) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the time is right to ping. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinancialPing::IsPingTime(product, skip_time_check)) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send out the ping, update the last ping time irrespective of success. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FinancialPing::UpdateLastPingTime(product); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FinancialPing::PingServer(request.c_str(), &response)) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the ping response - update RLZs, clear events. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ParsePingResponse(product, response.c_str()); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO: Use something like RSA to make sure the response is 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from a Google server. 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsePingResponse(Product product, const char* response) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::ScopedRlzValueStoreLock lock; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_lib::RlzValueStore* store = lock.GetStore(); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(rlz_lib::RlzValueStore::kWriteAccess)) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_string(response); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_length = -1; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsPingResponseValid(response, &response_length)) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == response_length) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // Empty response - no parsing. 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string events_variable; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string stateful_events_variable; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SStringPrintf(&events_variable, "%s: ", kEventsCgiVariable); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SStringPrintf(&stateful_events_variable, "%s: ", 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStatefulEventsCgiVariable); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rlz_cgi_length = strlen(kRlzCgiVariable); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Split response lines. Expected response format is lines of the form: 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rlzW1: 1R1_____en__252 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int line_end_index = -1; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int line_begin = line_end_index + 1; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line_end_index = response_string.find("\n", line_begin); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int line_end = line_end_index; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line_end < 0) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line_end = response_length; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line_end <= line_begin) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Empty line. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_line; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_line = response_string.substr(line_begin, line_end - line_begin); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (StartsWithASCII(response_line, kRlzCgiVariable, true)) { // An RLZ. 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int separator_index = -1; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((separator_index = response_line.find(": ")) < 0) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Not a valid key-value pair. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the access point. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string point_name = 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_line.substr(3, separator_index - rlz_cgi_length); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AccessPoint point = NO_ACCESS_POINT; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetAccessPointFromName(point_name.c_str(), &point) || 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) point == NO_ACCESS_POINT) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Not a valid access point. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the new RLZ. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string rlz_value(response_line.substr(separator_index + 2)); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespaceASCII(rlz_value, TRIM_LEADING, &rlz_value); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t rlz_length = rlz_value.find_first_of("\r\n "); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rlz_length == std::string::npos) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlz_length = rlz_value.size(); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rlz_length > kMaxRlzLength) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Too long. 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsAccessPointSupported(point)) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAccessPointRlz(point, rlz_value.substr(0, rlz_length).c_str()); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (StartsWithASCII(response_line, events_variable, true)) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear events which server parsed. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ReturnedEvent> event_array; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetEventsFromResponseString(response_line, events_variable, &event_array); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < event_array.size(); ++i) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearProductEvent(product, event_array[i].access_point, 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_array[i].event_type); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (StartsWithASCII(response_line, stateful_events_variable, true)) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record any stateful events the server send over. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ReturnedEvent> event_array; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetEventsFromResponseString(response_line, stateful_events_variable, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &event_array); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < event_array.size(); ++i) { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordStatefulEvent(product, event_array[i].access_point, 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_array[i].event_type); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (line_end_index >= 0); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the DCC in registry if needed. 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetMachineDealCodeFromPingResponse(response); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetPingParams(Product product, const AccessPoint* access_points, 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* cgi, size_t cgi_size) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cgi || cgi_size <= 0) { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("GetPingParams: Invalid buffer"); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[0] = 0; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!access_points) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STRING("GetPingParams: access_points is NULL"); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the RLZ Exchange Protocol version. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cgi_string(kProtocolCgiArgument); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the &rlz= over. 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&cgi_string, "&%s=", kRlzCgiVariable); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now add each of the RLZ's. Keep the lock during all GetAccessPointRlz() 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // calls below. 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedRlzValueStoreLock lock; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RlzValueStore* store = lock.GetStore(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!store || !store->HasAccess(RlzValueStore::kReadAccess)) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first_rlz = true; // comma before every RLZ but the first. 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; access_points[i] != NO_ACCESS_POINT; i++) { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char rlz[kMaxRlzLength + 1]; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetAccessPointRlz(access_points[i], rlz, arraysize(rlz))) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* access_point = GetAccessPointName(access_points[i]); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!access_point) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&cgi_string, "%s%s%s%s", 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_rlz ? "" : kRlzCgiSeparator, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_point, kRlzCgiIndicator, rlz); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_rlz = false; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Report the DCC too if not empty. DCCs are windows-only. 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char dcc[kMaxDccLength + 1]; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dcc[0] = 0; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetMachineDealCode(dcc, arraysize(dcc)) && dcc[0]) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&cgi_string, "&%s=%s", kDccCgiVariable, dcc); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cgi_string.size() >= cgi_size) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(cgi, cgi_string.c_str(), cgi_size); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgi[cgi_size - 1] = 0; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace rlz_lib 652