// Copyright 2014 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/update_client/utils.h" #include #include #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/guid.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/sys_info.h" #include "base/win/windows_version.h" #include "components/crx_file/id_util.h" #include "components/update_client/configurator.h" #include "components/update_client/crx_update_item.h" #include "components/update_client/update_client.h" #include "components/update_client/update_query_params.h" #include "net/base/load_flags.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" namespace update_client { namespace { // Returns the amount of physical memory in GB, rounded to the nearest GB. int GetPhysicalMemoryGB() { const double kOneGB = 1024 * 1024 * 1024; const int64_t phys_mem = base::SysInfo::AmountOfPhysicalMemory(); return static_cast(std::floor(0.5 + phys_mem / kOneGB)); } // Produces an extension-like friendly id. std::string HexStringToID(const std::string& hexstr) { std::string id; for (size_t i = 0; i < hexstr.size(); ++i) { int val = 0; if (base::HexStringToInt( base::StringPiece(hexstr.begin() + i, hexstr.begin() + i + 1), &val)) { id.append(1, val + 'a'); } else { id.append(1, 'a'); } } DCHECK(crx_file::id_util::IdIsValid(id)); return id; } } // namespace std::string BuildProtocolRequest(const std::string& browser_version, const std::string& channel, const std::string& lang, const std::string& os_long_name, const std::string& request_body, const std::string& additional_attributes) { const std::string prod_id( UpdateQueryParams::GetProdIdString(UpdateQueryParams::CHROME)); std::string request( "" "wow64_status() == base::win::OSInfo::WOW64_ENABLED); if (is_wow64) base::StringAppendF(&request, " wow64=\"1\""); #endif base::StringAppendF(&request, ">"); // HW platform information. base::StringAppendF(&request, "", GetPhysicalMemoryGB()); // "physmem" in GB. // OS version and platform information. base::StringAppendF( &request, "", os_long_name.c_str(), // "platform" base::SysInfo().OperatingSystemVersion().c_str(), // "version" base::SysInfo().OperatingSystemArchitecture().c_str()); // "arch" // The actual payload of the request. base::StringAppendF(&request, "%s", request_body.c_str()); return request; } scoped_ptr SendProtocolRequest( const GURL& url, const std::string& protocol_request, net::URLFetcherDelegate* url_fetcher_delegate, net::URLRequestContextGetter* url_request_context_getter) { scoped_ptr url_fetcher = net::URLFetcher::Create( 0, url, net::URLFetcher::POST, url_fetcher_delegate); url_fetcher->SetUploadData("application/xml", protocol_request); url_fetcher->SetRequestContext(url_request_context_getter); url_fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DISABLE_CACHE); url_fetcher->SetAutomaticallyRetryOn5xx(false); url_fetcher->Start(); return url_fetcher; } bool FetchSuccess(const net::URLFetcher& fetcher) { return GetFetchError(fetcher) == 0; } int GetFetchError(const net::URLFetcher& fetcher) { const net::URLRequestStatus::Status status(fetcher.GetStatus().status()); switch (status) { case net::URLRequestStatus::IO_PENDING: case net::URLRequestStatus::CANCELED: // Network status is a small positive number. return status; case net::URLRequestStatus::SUCCESS: { // Response codes are positive numbers, greater than 100. const int response_code(fetcher.GetResponseCode()); if (response_code == 200) return 0; else return response_code ? response_code : -1; } case net::URLRequestStatus::FAILED: { // Network errors are small negative numbers. const int error = fetcher.GetStatus().error(); return error ? error : -1; } default: return -1; } } bool HasDiffUpdate(const CrxUpdateItem* update_item) { return !update_item->crx_diffurls.empty(); } bool IsHttpServerError(int status_code) { return 500 <= status_code && status_code < 600; } bool DeleteFileAndEmptyParentDirectory(const base::FilePath& filepath) { if (!base::DeleteFile(filepath, false)) return false; const base::FilePath dirname(filepath.DirName()); if (!base::IsDirectoryEmpty(dirname)) return true; return base::DeleteFile(dirname, false); } std::string GetCrxComponentID(const CrxComponent& component) { const size_t kCrxIdSize = 16; CHECK_GE(component.pk_hash.size(), kCrxIdSize); return HexStringToID(base::ToLowerASCII( base::HexEncode(&component.pk_hash[0], kCrxIdSize))); } } // namespace update_client