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

Side by Side Diff: tools/OmahaCompatibility/HttpServer/xml_parser.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 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 | « tools/OmahaCompatibility/HttpServer/xml_parser.h ('k') | tools/OmahaCompatibility/build.scons » ('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 2008-2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16
17 #include "omaha/tools/omahacompatibility/httpserver/xml_parser.h"
18 #include <msxml2.h>
19 #include "omaha/common/string.h"
20 #include "omaha/common/xml_utils.h"
21 #include "omaha/goopdate/goopdate_xml_parser.h"
22
23 namespace omaha {
24
25 // Constant strings to form the server responses.
26 const TCHAR* const kResponseXmlHeader = _T("<?xml version=\"1.0\" encoding=\"UTF -8\"?>"); // NOLINT
27 const TCHAR* const kResponseXmlGupdateHeader = _T("<gupdate xmlns=\"http://www.g oogle.com/update2/response\" protocol=\"2.0\">"); // NOLINT
28 const TCHAR* const kResponseAppEvent = _T("<app appid=\"%s\" status=\"ok\"><even t status=\"ok\"/></app>"); // NOLINT
29 const TCHAR* const kResponseAppNoUpdate = _T("<app appid=\"%s\" status=\"ok\"><e vent status=\"no-update\"/></app>"); // NOLINT
30 const TCHAR* const kResponseAppUpdate = _T("<app appid=\"%s\" status=\"ok\"><upd atecheck codebase=\"%s\" hash=\"%s\" needsadmin=\"%s\" size=\"%d\" status=\"ok\" /></app>"); // NOLINT
31 const TCHAR* const kResponseGupdateEndTag = _T("</gupdate>");
32
33 // Constants for creating the xml request.
34 namespace Xml {
35 const TCHAR* const kHeaderText =
36 _T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
37 const TCHAR* const kProcessingText =
38 _T("version=\"1.0\" encoding=\"UTF-8\"");
39
40 namespace Namespace {
41 const TCHAR* const kRequest = _T("http://www.google.com/update2/request");
42 const TCHAR* const kResponse = _T("http://www.google.com/update2/response");
43 const TCHAR* const kSeed = _T("http://www.google.com/update2/install");
44 } // Namespace.
45
46 namespace Element {
47 const TCHAR* const kXml = _T("xml");
48 const TCHAR* const kRequests = _T("gupdate");
49 const TCHAR* const kOmahaVersion = _T("updaterversion");
50 const TCHAR* const kOs = _T("os");
51 const TCHAR* const kApp = _T("app");
52 const TCHAR* const kUpdateCheck = _T("updatecheck");
53 const TCHAR* const kPing = _T("ping");
54 const TCHAR* const kEvent = _T("event");
55 const TCHAR* const kComponents = _T("components");
56 const TCHAR* const kComponent = _T("component");
57
58 const TCHAR* const kResponses = _T("gupdate");
59 } // namespace Element.
60
61 namespace Attribute {
62 const TCHAR* const kActive = _T("active");
63 const TCHAR* const kAdditionalParameter = _T("ap");
64 const TCHAR* const kAppGuid = _T("appguid");
65 const TCHAR* const kApplicationName = _T("appname");
66 const TCHAR* const kAppId = _T("appid");
67 const TCHAR* const kArguments = _T("arguments");
68 const TCHAR* const kBrandCode = _T("brand");
69 const TCHAR* const kBrowserType = _T("browser");
70 const TCHAR* const kClientId = _T("client");
71 const TCHAR* const kCodebase = _T("codebase");
72 const TCHAR* const kCountry = _T("country");
73 const TCHAR* const kErrorCode = _T("errorcode");
74 const TCHAR* const kEventResult = _T("eventresult");
75 const TCHAR* const kEventType = _T("eventtype");
76 const TCHAR* const kExtraCode1 = _T("extracode1");
77 const TCHAR* const kHash = _T("hash");
78 const TCHAR* const kIsMachine = _T("ismachine");
79 const TCHAR* const kInstallationId = _T("iid");
80 const TCHAR* const kInstallSource = _T("installsource");
81 const TCHAR* const kLang = _T("lang");
82 const TCHAR* const kNeedsAdmin = _T("needsadmin");
83 const TCHAR* const kParameter = _T("parameter");
84 const TCHAR* const kPlatform = _T("platform");
85 const TCHAR* const kPreviousVersion = _T("previousversion");
86 const TCHAR* const kProtocol = _T("protocol");
87 const TCHAR* const kServicePack = _T("sp");
88 const TCHAR* const kSessionId = _T("sessionid");
89 const TCHAR* const kSignature = _T("signature");
90 const TCHAR* const kSize = _T("size");
91 const TCHAR* const kStatus = _T("status");
92 const TCHAR* const kSuccessAction = _T("onsuccess");
93 const TCHAR* const kSuccessUrl = _T("successurl");
94 const TCHAR* const kTag = _T("tag");
95 const TCHAR* const kTestSource = _T("testsource");
96 const TCHAR* const kTerminateAllBrowsers = _T("terminateallbrowsers");
97 const TCHAR* const kVersion = _T("version");
98 const TCHAR* const kXmlns = _T("xmlns");
99 const TCHAR* const kTTToken = _T("tttoken");
100 } // namespace Attribute.
101
102 namespace Value {
103 const TCHAR* const kRequestType = _T("UpdateRequest");
104 const TCHAR* const kProtocol = _T("2.0");
105 const TCHAR* const kVersion2 = _T("2.0");
106 const TCHAR* const kVersion3 = _T("3.0");
107 const TCHAR* const kTrue = _T("true");
108 const TCHAR* const kFalse = _T("false");
109 const TCHAR* const kStatusError = _T("error");
110 const TCHAR* const kSuccessActionDefault = _T("default");
111 const TCHAR* const kSuccessActionExitSilently = _T("exitsilently");
112 const TCHAR* const kWinPlatform = _T("win");
113
114 const TCHAR* const kStatusOk = kResponseStatusOkValue;
115 } // namespace value.
116 } // namespace xml.
117
118 HRESULT ReadAttribute(IXMLDOMNode* node,
119 const TCHAR* attr_name,
120 BSTR* value) {
121 ASSERT1(node != NULL);
122 ASSERT1(attr_name != NULL);
123 ASSERT1(value != NULL);
124
125 // First read the attributes.
126 CComPtr<IXMLDOMNamedNodeMap> attributes;
127 HRESULT hr = node->get_attributes(&attributes);
128 if (FAILED(hr)) { return hr; }
129 if (!attributes) { return E_FAIL; } // Protect against msxml S_FALSE return.
130
131 CComPtr<IXMLDOMNode> attribute_node;
132 CComVariant node_value;
133 CComBSTR temp_attr_name(attr_name);
134
135 // Get the attribute using a named node.
136 hr = attributes->getNamedItem(static_cast<BSTR>(temp_attr_name),
137 &attribute_node);
138 if (FAILED(hr)) { return hr; }
139 if (!attribute_node) { return E_FAIL; } // Protect against msxml S_FALSE
140 // return.
141
142 hr = attribute_node->get_nodeValue(&node_value);
143 if (FAILED(hr)) { return hr; }
144 if (node_value.vt == VT_EMPTY) { return E_FAIL; }
145
146 // Extract the variant into a BSTR.
147 node_value.CopyTo(value);
148
149 return S_OK;
150 }
151
152 HRESULT ReadIntAttribute(IXMLDOMNode* node,
153 const TCHAR* attr_name,
154 int* value) {
155 ASSERT1(node != NULL);
156 ASSERT1(attr_name != NULL);
157 ASSERT1(value != NULL);
158
159 CComBSTR node_value;
160 HRESULT hr = ReadAttribute(node, attr_name, &node_value);
161 if (FAILED(hr)) { return hr; }
162 if (!String_StringToDecimalIntChecked(
163 static_cast<const TCHAR*>(node_value), value)) {
164 return E_FAIL;
165 }
166 return S_OK;
167 }
168
169 HRESULT ReadGuidAttribute(IXMLDOMNode* node,
170 const TCHAR* attr_name,
171 GUID* value) {
172 ASSERT1(node != NULL);
173 ASSERT1(attr_name != NULL);
174 ASSERT1(value != NULL);
175
176 CComBSTR node_value;
177 HRESULT hr = ReadAttribute(node, attr_name, &node_value);
178 if (FAILED(hr)) { return hr; }
179 hr = ::CLSIDFromString(static_cast<TCHAR*>(node_value), value);
180 if (FAILED(hr)) { return hr; }
181
182 return S_OK;
183 }
184
185 HRESULT ReadStringAttribute(IXMLDOMNode* node,
186 const TCHAR* attr_name,
187 CString* value) {
188 ASSERT1(node != NULL);
189 ASSERT1(attr_name != NULL);
190 ASSERT1(value != NULL);
191
192 CComBSTR node_value;
193 HRESULT hr = ReadAttribute(node, attr_name, &node_value);
194 if (FAILED(hr)) { return hr; }
195
196 // Will extract the underlying string.
197 *value = static_cast<TCHAR*>(node_value);
198
199 return S_OK;
200 }
201
202 HRESULT ParseAppUpdateCheckNode(IXMLDOMNode* node, AppData* request) {
203 ASSERT1(node);
204 ASSERT1(request);
205
206 // Read the tag value.
207 CString str;
208 ReadStringAttribute(node, Xml::Attribute::kTag, &str);
209 request->set_ap(str);
210
211 return S_OK;
212 }
213
214 HRESULT ParseAppPingNode(IXMLDOMNode* node, AppRequestData* request) {
215 ASSERT1(node);
216 ASSERT1(request);
217
218 // Read the event type.
219 int event_type = 0;
220 HRESULT hr = ReadIntAttribute(node, Xml::Attribute::kEventType, &event_type);
221 if (FAILED(hr)) { return hr; }
222
223 // Read the event result.
224 int event_result = 0;
225 hr = ReadIntAttribute(node, Xml::Attribute::kEventResult, &event_result);
226 if (FAILED(hr)) { return hr; }
227
228 // Read the errorcode.
229 int error_code = 0;
230 hr = ReadIntAttribute(node, Xml::Attribute::kErrorCode, &error_code);
231 if (FAILED(hr)) { return hr; }
232
233 // Read the extracode1.
234 int extra_code = 0;
235 hr = ReadIntAttribute(node, Xml::Attribute::kExtraCode1, &extra_code);
236 if (FAILED(hr)) { return hr; }
237
238 PingEvent ping_event(static_cast<PingEvent::Types>(event_type),
239 static_cast<PingEvent::Results>(event_result),
240 error_code,
241 extra_code,
242 CString());
243 request->AddPingEvent(ping_event);
244
245 return S_OK;
246 }
247
248 HRESULT ParseAppNode(IXMLDOMNode* node, AppRequestDataVector* request) {
249 ASSERT1(node);
250 ASSERT1(request);
251
252 AppRequest app_request;
253 AppData app_data;
254 AppRequestData app_request_data;
255
256 // Read the app guid.
257 GUID guid = {0};
258 HRESULT hr = ReadGuidAttribute(node, Xml::Attribute::kAppId, &guid);
259 if (FAILED(hr)) { return hr; }
260 app_data.set_app_guid(guid);
261
262 // Read the app version.
263 CString str;
264 hr = ReadStringAttribute(node, Xml::Attribute::kVersion, &str);
265 if (FAILED(hr)) { return hr; }
266 app_data.set_version(str);
267
268 // Read the app language.
269 hr = ReadStringAttribute(node, Xml::Attribute::kLang, &str);
270 if (FAILED(hr)) { return hr; }
271 app_data.set_language(str);
272
273 CComPtr<IXMLDOMNodeList> child_nodes;
274 // Get all the children of the Node.
275 hr = node->get_childNodes(&child_nodes);
276 if (FAILED(hr)) { return hr; }
277 if (!child_nodes) { return E_FAIL; } // Protect against msxml S_FALSE return.
278
279 // Go Over all the children and read each of them. we will ignore ones that
280 // we dont understand.
281 hr = child_nodes->reset();
282 if (FAILED(hr)) { return hr; }
283
284 CComPtr<IXMLDOMNode> child_node;
285 while (child_nodes->nextNode(&child_node) != S_FALSE) {
286 XMLFQName child_node_name;
287 hr = GetXMLFQName(child_node, &child_node_name);
288 if (FAILED(hr)) { return hr; }
289
290 if (child_node_name.base == Xml::Element::kUpdateCheck) {
291 // Read in the update check request.
292 hr = ParseAppUpdateCheckNode(child_node, &app_data);
293 if (FAILED(hr)) { return hr; }
294 } else if (child_node_name.base == Xml::Element::kEvent) {
295 // Read in the ping request.
296 hr = ParseAppPingNode(child_node, &app_request_data);
297 }
298
299 child_node = NULL;
300 }
301
302 app_request_data.set_app_data(app_data);
303 request->push_back(app_request_data);
304 return S_OK;
305 }
306
307 HRESULT ParseGupdateNode(IXMLDOMNode* node, AppRequestDataVector* request) {
308 ASSERT1(node);
309 ASSERT1(request);
310
311 CComPtr<IXMLDOMNodeList> child_nodes;
312 // Get all the children of the Node.
313 HRESULT hr = node->get_childNodes(&child_nodes);
314 if (FAILED(hr)) { return hr; }
315 if (!child_nodes) { return E_FAIL; } // Protect against msxml S_FALSE return.
316
317 // Go Over all the children and read each of them. we will ignore ones that
318 // we dont understand.
319 hr = child_nodes->reset();
320 if (FAILED(hr)) { return hr; }
321
322 CComPtr<IXMLDOMNode> child_node;
323 while (child_nodes->nextNode(&child_node) != S_FALSE) {
324 XMLFQName child_node_name;
325 hr = GetXMLFQName(child_node, &child_node_name);
326 if (FAILED(hr)) { return hr; }
327
328 if (child_node_name.base == Xml::Element::kApp) {
329 // we got a response we should read that in.
330 hr = ParseAppNode(child_node, request);
331 if (FAILED(hr)) { return hr; }
332 }
333 child_node = NULL;
334 }
335 return S_OK;
336 }
337
338 HRESULT ParseUpdateCheck(const CString& request_str,
339 AppRequestDataVector* request) {
340 ASSERT1(request);
341
342 CComPtr<IXMLDOMDocument> document;
343 HRESULT hr = LoadXMLFromMemory(request_str, false, &document);
344 if (FAILED(hr)) {
345 return hr;
346 }
347
348 CComPtr<IXMLDOMElement> document_element;
349 hr = document->get_documentElement(&document_element);
350 if (FAILED(hr)) {
351 return hr;
352 }
353 if (!document_element) { // Protect against msxml S_FALSE return.
354 return E_FAIL;
355 }
356
357 return ParseGupdateNode(document_element, request);
358 }
359
360 HRESULT BuildUpdateResponse(const ServerResponses& responses,
361 CString* response) {
362 ASSERT1(response);
363
364 CString response_str(kResponseXmlHeader);
365 response_str.Append(kResponseXmlGupdateHeader);
366
367 for (size_t i = 0; i < responses.size(); ++i) {
368 CString guid = responses[i].guid;
369
370 if (responses[i].is_ping) {
371 // If the response is to a ping event, then we just add the ok to the
372 // response. The reason this works is because we either have a ping
373 // request or a update check, never both. If this changes, then we need
374 // to change this code.
375 response_str.AppendFormat(kResponseAppEvent, guid);
376 } else if (responses[i].is_update_response) {
377 // respond with the value of the updates.
378 UpdateResponseData data = responses[i].response_data;
379 response_str.AppendFormat(kResponseAppUpdate,
380 guid,
381 data.url(),
382 data.hash(),
383 data.needs_admin() ? _T("true") : _T("false"),
384 data.size());
385 } else {
386 // respond with a no-update.
387 response_str.AppendFormat(kResponseAppNoUpdate, guid);
388 }
389 }
390
391 response_str.Append(kResponseGupdateEndTag);
392 *response = response_str;
393 return S_OK;
394 }
395
396 } // namespace omaha
OLDNEW
« no previous file with comments | « tools/OmahaCompatibility/HttpServer/xml_parser.h ('k') | tools/OmahaCompatibility/build.scons » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698