| OLD | NEW | 
|---|
| 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "update_engine/omaha_request_action.h" | 5 #include "update_engine/omaha_request_action.h" | 
| 6 #include <inttypes.h> | 6 #include <inttypes.h> | 
| 7 #include <sstream> | 7 #include <sstream> | 
| 8 | 8 | 
| 9 #include <libxml/parser.h> | 9 #include <libxml/parser.h> | 
| 10 #include <libxml/xpath.h> | 10 #include <libxml/xpath.h> | 
| 11 #include <libxml/xpathInternals.h> | 11 #include <libxml/xpathInternals.h> | 
| 12 | 12 | 
|  | 13 #include "base/string_util.h" | 
| 13 #include "chromeos/obsolete_logging.h" | 14 #include "chromeos/obsolete_logging.h" | 
| 14 #include "update_engine/action_pipe.h" | 15 #include "update_engine/action_pipe.h" | 
| 15 #include "update_engine/utils.h" | 16 #include "update_engine/utils.h" | 
| 16 | 17 | 
| 17 using std::string; | 18 using std::string; | 
| 18 | 19 | 
| 19 namespace chromeos_update_engine { | 20 namespace chromeos_update_engine { | 
| 20 | 21 | 
| 21 const char* const OmahaRequestParams::kAppId( | 22 const char* const OmahaRequestParams::kAppId( | 
| 22     "{87efface-864d-49a5-9bb3-4b050a7c227a}"); | 23     "{87efface-864d-49a5-9bb3-4b050a7c227a}"); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 52     xmlXPathFreeObject(reinterpret_cast<xmlXPathObject*>(x)); | 53     xmlXPathFreeObject(reinterpret_cast<xmlXPathObject*>(x)); | 
| 53   } | 54   } | 
| 54 }; | 55 }; | 
| 55 class ScopedPtrXmlXPathContextFree { | 56 class ScopedPtrXmlXPathContextFree { | 
| 56  public: | 57  public: | 
| 57   inline void operator()(void* x) const { | 58   inline void operator()(void* x) const { | 
| 58     xmlXPathFreeContext(reinterpret_cast<xmlXPathContext*>(x)); | 59     xmlXPathFreeContext(reinterpret_cast<xmlXPathContext*>(x)); | 
| 59   } | 60   } | 
| 60 }; | 61 }; | 
| 61 | 62 | 
| 62 // Returns a properly formatted omaha request for a request to Omaha. | 63 string FormatRequest(const OmahaEvent* event, | 
| 63 string FormatRequest(const OmahaRequestParams& params) { | 64                      const OmahaRequestParams& params) { | 
|  | 65   string body; | 
|  | 66   if (event == NULL) { | 
|  | 67     body = string( | 
|  | 68         "        <o:ping active=\"0\"></o:ping>\n" | 
|  | 69         "        <o:updatecheck></o:updatecheck>\n"); | 
|  | 70   } else { | 
|  | 71     body = StringPrintf( | 
|  | 72         "        <o:event eventtype=\"%d\" eventresult=\"%d\" " | 
|  | 73         "errorcode=\"%d\"></o:event>\n", | 
|  | 74         event->type, event->result, event->error_code); | 
|  | 75   } | 
| 64   return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | 76   return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | 
| 65                 "<o:gupdate xmlns:o=\"http://www.google.com/update2/request\" " | 77                 "<o:gupdate xmlns:o=\"http://www.google.com/update2/request\" " | 
| 66                 "version=\"" + XmlEncode(kGupdateVersion) + "\" " | 78                 "version=\"" + XmlEncode(kGupdateVersion) + "\" " | 
| 67                 "updaterversion=\"" + XmlEncode(kGupdateVersion) + "\" " | 79                 "updaterversion=\"" + XmlEncode(kGupdateVersion) + "\" " | 
| 68                 "protocol=\"2.0\" " | 80                 "protocol=\"2.0\" " | 
| 69                 "machineid=\"") + XmlEncode(params.machine_id) + "\" ismachine=\
     "1\" " | 81                 "machineid=\"") + XmlEncode(params.machine_id) + | 
| 70       "userid=\"" + XmlEncode(params.user_id) + "\">\n" | 82       "\" ismachine=\"1\" userid=\"" + XmlEncode(params.user_id) + "\">\n" | 
| 71       "    <o:os version=\"" + XmlEncode(params.os_version) + "\" platform=\"" + | 83       "    <o:os version=\"" + XmlEncode(params.os_version) + "\" platform=\"" + | 
| 72       XmlEncode(params.os_platform) + "\" sp=\"" + | 84       XmlEncode(params.os_platform) + "\" sp=\"" + | 
| 73       XmlEncode(params.os_sp) + "\"></o:os>\n" | 85       XmlEncode(params.os_sp) + "\"></o:os>\n" | 
| 74       "    <o:app appid=\"" + XmlEncode(params.app_id) + "\" version=\"" + | 86       "    <o:app appid=\"" + XmlEncode(params.app_id) + "\" version=\"" + | 
| 75       XmlEncode(params.app_version) + "\" " | 87       XmlEncode(params.app_version) + "\" " | 
| 76       "lang=\"" + XmlEncode(params.app_lang) + "\" track=\"" + | 88       "lang=\"" + XmlEncode(params.app_lang) + "\" track=\"" + | 
| 77       XmlEncode(params.app_track) + "\" board=\"" + | 89       XmlEncode(params.app_track) + "\" board=\"" + | 
| 78       XmlEncode(params.os_board) + "\">\n" | 90       XmlEncode(params.os_board) + "\">\n" + body + | 
| 79       "        <o:ping active=\"0\"></o:ping>\n" |  | 
| 80       "        <o:updatecheck></o:updatecheck>\n" |  | 
| 81       "    </o:app>\n" | 91       "    </o:app>\n" | 
| 82       "</o:gupdate>\n"; | 92       "</o:gupdate>\n"; | 
| 83 } | 93 } | 
| 84 }  // namespace {} | 94 }  // namespace {} | 
| 85 | 95 | 
| 86 // Encodes XML entities in a given string with libxml2. input must be | 96 // Encodes XML entities in a given string with libxml2. input must be | 
| 87 // UTF-8 formatted. Output will be UTF-8 formatted. | 97 // UTF-8 formatted. Output will be UTF-8 formatted. | 
| 88 string XmlEncode(const string& input) { | 98 string XmlEncode(const string& input) { | 
| 89   //  // TODO(adlr): if allocating a new xmlDoc each time is taking up too much | 99   //  // TODO(adlr): if allocating a new xmlDoc each time is taking up too much | 
| 90   //  // cpu, considering creating one and caching it. | 100   //  // cpu, considering creating one and caching it. | 
| 91   //  scoped_ptr_malloc<xmlDoc, ScopedPtrXmlDocFree> xml_doc( | 101   //  scoped_ptr_malloc<xmlDoc, ScopedPtrXmlDocFree> xml_doc( | 
| 92   //      xmlNewDoc(ConstXMLStr("1.0"))); | 102   //      xmlNewDoc(ConstXMLStr("1.0"))); | 
| 93   //  if (!xml_doc.get()) { | 103   //  if (!xml_doc.get()) { | 
| 94   //    LOG(ERROR) << "Unable to create xmlDoc"; | 104   //    LOG(ERROR) << "Unable to create xmlDoc"; | 
| 95   //    return ""; | 105   //    return ""; | 
| 96   //  } | 106   //  } | 
| 97   scoped_ptr_malloc<xmlChar, ScopedPtrXmlFree> str( | 107   scoped_ptr_malloc<xmlChar, ScopedPtrXmlFree> str( | 
| 98       xmlEncodeEntitiesReentrant(NULL, ConstXMLStr(input.c_str()))); | 108       xmlEncodeEntitiesReentrant(NULL, ConstXMLStr(input.c_str()))); | 
| 99   return string(reinterpret_cast<const char *>(str.get())); | 109   return string(reinterpret_cast<const char *>(str.get())); | 
| 100 } | 110 } | 
| 101 | 111 | 
| 102 OmahaRequestAction::OmahaRequestAction(HttpFetcher* http_fetcher) | 112 OmahaRequestAction::OmahaRequestAction(OmahaEvent* event, | 
| 103     : http_fetcher_(http_fetcher) {} | 113                                        HttpFetcher* http_fetcher) | 
|  | 114     : event_(event), | 
|  | 115       http_fetcher_(http_fetcher) {} | 
| 104 | 116 | 
| 105 OmahaRequestAction::~OmahaRequestAction() {} | 117 OmahaRequestAction::~OmahaRequestAction() {} | 
| 106 | 118 | 
| 107 void OmahaRequestAction::PerformAction() { | 119 void OmahaRequestAction::PerformAction() { | 
| 108   CHECK(HasInputObject()); | 120   CHECK(HasInputObject()); | 
| 109   params_ = GetInputObject(); | 121   params_ = GetInputObject(); | 
| 110   http_fetcher_->set_delegate(this); | 122   http_fetcher_->set_delegate(this); | 
| 111   string request_post(FormatRequest(params_)); | 123   string request_post(FormatRequest(event_.get(), params_)); | 
| 112   http_fetcher_->SetPostData(request_post.data(), request_post.size()); | 124   http_fetcher_->SetPostData(request_post.data(), request_post.size()); | 
| 113   LOG(INFO) << "Checking for update at " << params_.update_url; | 125   LOG(INFO) << "Posting an Omaha request to " << params_.update_url; | 
| 114   LOG(INFO) << "Request: " << request_post; | 126   LOG(INFO) << "Request: " << request_post; | 
| 115   http_fetcher_->BeginTransfer(params_.update_url); | 127   http_fetcher_->BeginTransfer(params_.update_url); | 
| 116 } | 128 } | 
| 117 | 129 | 
| 118 void OmahaRequestAction::TerminateProcessing() { | 130 void OmahaRequestAction::TerminateProcessing() { | 
| 119   http_fetcher_->TerminateTransfer(); | 131   http_fetcher_->TerminateTransfer(); | 
| 120 } | 132 } | 
| 121 | 133 | 
| 122 // We just store the response in the buffer. Once we've received all bytes, | 134 // We just store the response in the buffer. Once we've received all bytes, | 
| 123 // we'll look in the buffer and decide what to do. | 135 // we'll look in the buffer and decide what to do. | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 188   return ret; | 200   return ret; | 
| 189 } | 201 } | 
| 190 }  // namespace {} | 202 }  // namespace {} | 
| 191 | 203 | 
| 192 // If the transfer was successful, this uses libxml2 to parse the response | 204 // If the transfer was successful, this uses libxml2 to parse the response | 
| 193 // and fill in the appropriate fields of the output object. Also, notifies | 205 // and fill in the appropriate fields of the output object. Also, notifies | 
| 194 // the processor that we're done. | 206 // the processor that we're done. | 
| 195 void OmahaRequestAction::TransferComplete(HttpFetcher *fetcher, | 207 void OmahaRequestAction::TransferComplete(HttpFetcher *fetcher, | 
| 196                                           bool successful) { | 208                                           bool successful) { | 
| 197   ScopedActionCompleter completer(processor_, this); | 209   ScopedActionCompleter completer(processor_, this); | 
| 198   LOG(INFO) << "Update check response: " << string(response_buffer_.begin(), | 210   LOG(INFO) << "Omaha request response: " << string(response_buffer_.begin(), | 
| 199                                                    response_buffer_.end()); | 211                                                     response_buffer_.end()); | 
|  | 212 | 
|  | 213   // Events are best effort transactions -- assume they always succeed. | 
|  | 214   if (IsEvent()) { | 
|  | 215     CHECK(!HasOutputPipe()) << "No output pipe allowed for event requests."; | 
|  | 216     completer.set_success(true); | 
|  | 217     return; | 
|  | 218   } | 
|  | 219 | 
| 200   if (!successful) { | 220   if (!successful) { | 
| 201     LOG(ERROR) << "Update check network transfer failed."; | 221     LOG(ERROR) << "Omaha request network transfer failed."; | 
| 202     return; | 222     return; | 
| 203   } | 223   } | 
| 204   if (!HasOutputPipe()) { | 224   if (!HasOutputPipe()) { | 
| 205     // Just set success to whether or not the http transfer succeeded, | 225     // Just set success to whether or not the http transfer succeeded, | 
| 206     // which must be true at this point in the code. | 226     // which must be true at this point in the code. | 
| 207     completer.set_success(true); | 227     completer.set_success(true); | 
| 208     return; | 228     return; | 
| 209   } | 229   } | 
| 210 | 230 | 
| 211   // parse our response and fill the fields in the output object | 231   // parse our response and fill the fields in the output object | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 266   output_object.hash = XmlGetProperty(updatecheck_node, "hash"); | 286   output_object.hash = XmlGetProperty(updatecheck_node, "hash"); | 
| 267   output_object.size = ParseInt(XmlGetProperty(updatecheck_node, "size")); | 287   output_object.size = ParseInt(XmlGetProperty(updatecheck_node, "size")); | 
| 268   output_object.needs_admin = | 288   output_object.needs_admin = | 
| 269       XmlGetProperty(updatecheck_node, "needsadmin") == "true"; | 289       XmlGetProperty(updatecheck_node, "needsadmin") == "true"; | 
| 270   output_object.prompt = XmlGetProperty(updatecheck_node, "Prompt") == "true"; | 290   output_object.prompt = XmlGetProperty(updatecheck_node, "Prompt") == "true"; | 
| 271   SetOutputObject(output_object); | 291   SetOutputObject(output_object); | 
| 272   return; | 292   return; | 
| 273 } | 293 } | 
| 274 | 294 | 
| 275 };  // namespace chromeos_update_engine | 295 };  // namespace chromeos_update_engine | 
| OLD | NEW | 
|---|