OLD | NEW |
| (Empty) |
1 // Copyright 2013 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 "chrome/browser/component_updater/component_updater_utils.h" | |
6 | |
7 #include <cmath> | |
8 | |
9 #include "base/file_util.h" | |
10 #include "base/files/file_path.h" | |
11 #include "base/guid.h" | |
12 #include "base/strings/string_number_conversions.h" | |
13 #include "base/strings/string_piece.h" | |
14 #include "base/strings/string_util.h" | |
15 #include "base/strings/stringprintf.h" | |
16 #include "base/sys_info.h" | |
17 #include "base/win/windows_version.h" | |
18 #include "chrome/browser/component_updater/component_updater_configurator.h" | |
19 #include "chrome/browser/component_updater/crx_update_item.h" | |
20 #include "components/omaha_query_params/omaha_query_params.h" | |
21 #include "net/base/load_flags.h" | |
22 #include "net/url_request/url_fetcher.h" | |
23 #include "net/url_request/url_request_context_getter.h" | |
24 #include "net/url_request/url_request_status.h" | |
25 | |
26 using omaha_query_params::OmahaQueryParams; | |
27 | |
28 namespace component_updater { | |
29 | |
30 namespace { | |
31 | |
32 // Returns the amount of physical memory in GB, rounded to the nearest GB. | |
33 int GetPhysicalMemoryGB() { | |
34 const double kOneGB = 1024 * 1024 * 1024; | |
35 const int64 phys_mem = base::SysInfo::AmountOfPhysicalMemory(); | |
36 return static_cast<int>(std::floor(0.5 + phys_mem / kOneGB)); | |
37 } | |
38 | |
39 } // namespace | |
40 | |
41 std::string BuildProtocolRequest(const std::string& browser_version, | |
42 const std::string& channel, | |
43 const std::string& lang, | |
44 const std::string& os_long_name, | |
45 const std::string& request_body, | |
46 const std::string& additional_attributes) { | |
47 const std::string prod_id( | |
48 OmahaQueryParams::GetProdIdString(OmahaQueryParams::CHROME)); | |
49 | |
50 std::string request( | |
51 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
52 "<request protocol=\"3.0\" "); | |
53 | |
54 if (!additional_attributes.empty()) | |
55 base::StringAppendF(&request, "%s ", additional_attributes.c_str()); | |
56 | |
57 // Chrome version and platform information. | |
58 base::StringAppendF( | |
59 &request, | |
60 "version=\"%s-%s\" prodversion=\"%s\" " | |
61 "requestid=\"{%s}\" lang=\"%s\" updaterchannel=\"%s\" prodchannel=\"%s\" " | |
62 "os=\"%s\" arch=\"%s\" nacl_arch=\"%s\"", | |
63 prod_id.c_str(), | |
64 browser_version.c_str(), // "version" | |
65 browser_version.c_str(), // "prodversion" | |
66 base::GenerateGUID().c_str(), // "requestid" | |
67 lang.c_str(), // "lang", | |
68 channel.c_str(), // "updaterchannel" | |
69 channel.c_str(), // "prodchannel" | |
70 OmahaQueryParams::GetOS(), // "os" | |
71 OmahaQueryParams::GetArch(), // "arch" | |
72 OmahaQueryParams::GetNaclArch()); // "nacl_arch" | |
73 #if defined(OS_WIN) | |
74 const bool is_wow64(base::win::OSInfo::GetInstance()->wow64_status() == | |
75 base::win::OSInfo::WOW64_ENABLED); | |
76 if (is_wow64) | |
77 base::StringAppendF(&request, " wow64=\"1\""); | |
78 #endif | |
79 base::StringAppendF(&request, ">"); | |
80 | |
81 // HW platform information. | |
82 base::StringAppendF(&request, | |
83 "<hw physmemory=\"%d\"/>", | |
84 GetPhysicalMemoryGB()); // "physmem" in GB. | |
85 | |
86 // OS version and platform information. | |
87 base::StringAppendF( | |
88 &request, | |
89 "<os platform=\"%s\" version=\"%s\" arch=\"%s\"/>", | |
90 os_long_name.c_str(), // "platform" | |
91 base::SysInfo().OperatingSystemVersion().c_str(), // "version" | |
92 base::SysInfo().OperatingSystemArchitecture().c_str()); // "arch" | |
93 | |
94 // The actual payload of the request. | |
95 base::StringAppendF(&request, "%s</request>", request_body.c_str()); | |
96 | |
97 return request; | |
98 } | |
99 | |
100 net::URLFetcher* SendProtocolRequest( | |
101 const GURL& url, | |
102 const std::string& protocol_request, | |
103 net::URLFetcherDelegate* url_fetcher_delegate, | |
104 net::URLRequestContextGetter* url_request_context_getter) { | |
105 net::URLFetcher* url_fetcher(net::URLFetcher::Create( | |
106 0, url, net::URLFetcher::POST, url_fetcher_delegate)); | |
107 | |
108 url_fetcher->SetUploadData("application/xml", protocol_request); | |
109 url_fetcher->SetRequestContext(url_request_context_getter); | |
110 url_fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
111 net::LOAD_DO_NOT_SAVE_COOKIES | | |
112 net::LOAD_DISABLE_CACHE); | |
113 url_fetcher->SetAutomaticallyRetryOn5xx(false); | |
114 url_fetcher->Start(); | |
115 | |
116 return url_fetcher; | |
117 } | |
118 | |
119 bool FetchSuccess(const net::URLFetcher& fetcher) { | |
120 return GetFetchError(fetcher) == 0; | |
121 } | |
122 | |
123 int GetFetchError(const net::URLFetcher& fetcher) { | |
124 const net::URLRequestStatus::Status status(fetcher.GetStatus().status()); | |
125 switch (status) { | |
126 case net::URLRequestStatus::IO_PENDING: | |
127 case net::URLRequestStatus::CANCELED: | |
128 // Network status is a small positive number. | |
129 return status; | |
130 | |
131 case net::URLRequestStatus::SUCCESS: { | |
132 // Response codes are positive numbers, greater than 100. | |
133 const int response_code(fetcher.GetResponseCode()); | |
134 if (response_code == 200) | |
135 return 0; | |
136 else | |
137 return response_code ? response_code : -1; | |
138 } | |
139 | |
140 case net::URLRequestStatus::FAILED: { | |
141 // Network errors are small negative numbers. | |
142 const int error = fetcher.GetStatus().error(); | |
143 return error ? error : -1; | |
144 } | |
145 | |
146 default: | |
147 return -1; | |
148 } | |
149 } | |
150 | |
151 bool HasDiffUpdate(const CrxUpdateItem* update_item) { | |
152 return !update_item->crx_diffurls.empty(); | |
153 } | |
154 | |
155 bool IsHttpServerError(int status_code) { | |
156 return 500 <= status_code && status_code < 600; | |
157 } | |
158 | |
159 bool DeleteFileAndEmptyParentDirectory(const base::FilePath& filepath) { | |
160 if (!base::DeleteFile(filepath, false)) | |
161 return false; | |
162 | |
163 const base::FilePath dirname(filepath.DirName()); | |
164 if (!base::IsDirectoryEmpty(dirname)) | |
165 return true; | |
166 | |
167 return base::DeleteFile(dirname, false); | |
168 } | |
169 | |
170 // Produces an extension-like friendly id. | |
171 std::string HexStringToID(const std::string& hexstr) { | |
172 std::string id; | |
173 for (size_t i = 0; i < hexstr.size(); ++i) { | |
174 int val = 0; | |
175 if (base::HexStringToInt( | |
176 base::StringPiece(hexstr.begin() + i, hexstr.begin() + i + 1), | |
177 &val)) { | |
178 id.append(1, val + 'a'); | |
179 } else { | |
180 id.append(1, 'a'); | |
181 } | |
182 } | |
183 | |
184 // TODO(tommycli): Add back the DCHECK validating the generated id. This | |
185 // requires moving the extension id_util functions into components/crx_file. | |
186 | |
187 return id; | |
188 } | |
189 | |
190 std::string GetCrxComponentID(const CrxComponent& component) { | |
191 return HexStringToID(base::StringToLowerASCII( | |
192 base::HexEncode(&component.pk_hash[0], component.pk_hash.size() / 2))); | |
193 } | |
194 | |
195 } // namespace component_updater | |
OLD | NEW |