blob: 582fe5f4a1ae295e8489a6234d0d48e963ccfd24 [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// 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
3// found in the LICENSE file.
4
Darin Petkov6a5b3222010-07-13 14:55:28 -07005#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H__
6#define CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H__
rspangler@google.com49fdf182009-10-10 00:57:34 +00007
rspangler@google.com49fdf182009-10-10 00:57:34 +00008#include <sys/stat.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07009#include <sys/types.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000010#include <fcntl.h>
11
12#include <string>
13
14#include <curl/curl.h>
15
16#include "base/scoped_ptr.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070017#include "update_engine/action.h"
18#include "update_engine/http_fetcher.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000019
Darin Petkov6a5b3222010-07-13 14:55:28 -070020// The Omaha Request action makes a request to Omaha and can output
21// the response on the output ActionPipe.
rspangler@google.com49fdf182009-10-10 00:57:34 +000022
rspangler@google.com49fdf182009-10-10 00:57:34 +000023namespace chromeos_update_engine {
24
25// Encodes XML entities in a given string with libxml2. input must be
26// UTF-8 formatted. Output will be UTF-8 formatted.
27std::string XmlEncode(const std::string& input);
28
Darin Petkov6a5b3222010-07-13 14:55:28 -070029// This struct encapsulates the data Omaha gets for the request.
rspangler@google.com49fdf182009-10-10 00:57:34 +000030// These strings in this struct should not be XML escaped.
Darin Petkov6a5b3222010-07-13 14:55:28 -070031struct OmahaRequestParams {
32 OmahaRequestParams()
rspangler@google.com49fdf182009-10-10 00:57:34 +000033 : os_platform(kOsPlatform), os_version(kOsVersion), app_id(kAppId) {}
Darin Petkov6a5b3222010-07-13 14:55:28 -070034 OmahaRequestParams(const std::string& in_machine_id,
35 const std::string& in_user_id,
36 const std::string& in_os_platform,
37 const std::string& in_os_version,
38 const std::string& in_os_sp,
39 const std::string& in_os_board,
40 const std::string& in_app_id,
41 const std::string& in_app_version,
42 const std::string& in_app_lang,
43 const std::string& in_app_track,
44 const std::string& in_update_url)
rspangler@google.com49fdf182009-10-10 00:57:34 +000045 : machine_id(in_machine_id),
46 user_id(in_user_id),
47 os_platform(in_os_platform),
48 os_version(in_os_version),
49 os_sp(in_os_sp),
Andrew de los Reyes37c20322010-06-30 13:27:19 -070050 os_board(in_os_board),
rspangler@google.com49fdf182009-10-10 00:57:34 +000051 app_id(in_app_id),
52 app_version(in_app_version),
53 app_lang(in_app_lang),
Andrew de los Reyesf9714432010-05-04 10:21:23 -070054 app_track(in_app_track),
55 update_url(in_update_url) {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000056
Andrew de los Reyesf9714432010-05-04 10:21:23 -070057 std::string machine_id;
58 std::string user_id;
59 std::string os_platform;
60 std::string os_version;
61 std::string os_sp;
Andrew de los Reyes37c20322010-06-30 13:27:19 -070062 std::string os_board;
Andrew de los Reyesf9714432010-05-04 10:21:23 -070063 std::string app_id;
64 std::string app_version;
65 std::string app_lang;
66 std::string app_track;
Darin Petkov6a5b3222010-07-13 14:55:28 -070067
Andrew de los Reyesf9714432010-05-04 10:21:23 -070068 std::string update_url;
rspangler@google.com49fdf182009-10-10 00:57:34 +000069
70 // Suggested defaults
71 static const char* const kAppId;
72 static const char* const kOsPlatform;
73 static const char* const kOsVersion;
Andrew de los Reyesf9714432010-05-04 10:21:23 -070074 static const char* const kUpdateUrl;
rspangler@google.com49fdf182009-10-10 00:57:34 +000075};
76
Darin Petkov6a5b3222010-07-13 14:55:28 -070077// This struct encapsulates the data Omaha's response for the request.
rspangler@google.com49fdf182009-10-10 00:57:34 +000078// These strings in this struct are not XML escaped.
Darin Petkov6a5b3222010-07-13 14:55:28 -070079struct OmahaResponse {
80 OmahaResponse()
rspangler@google.com49fdf182009-10-10 00:57:34 +000081 : update_exists(false), size(0), needs_admin(false), prompt(false) {}
82 // True iff there is an update to be downloaded.
83 bool update_exists;
84
85 // These are only valid if update_exists is true:
86 std::string display_version;
87 std::string codebase;
88 std::string more_info_url;
89 std::string hash;
90 off_t size;
91 bool needs_admin;
92 bool prompt;
93};
94COMPILE_ASSERT(sizeof(off_t) == 8, off_t_not_64bit);
95
Darin Petkov0dc8e9a2010-07-14 14:51:57 -070096// This struct encapsulates the Omaha event information. For a
97// complete list of defined event types and results, see
98// http://code.google.com/p/omaha/wiki/ServerProtocol#event
99struct OmahaEvent {
100 enum Type {
101 kTypeUnknown = 0,
102 kTypeDownloadComplete = 1,
103 kTypeInstallComplete = 2,
104 kTypeUpdateComplete = 3,
105 };
106
107 enum Result {
108 kResultError = 0,
109 kResultSuccess = 1,
110 };
111
112 OmahaEvent()
113 : type(kTypeUnknown),
114 result(kResultError),
115 error_code(0) {}
116 OmahaEvent(Type in_type, Result in_result, int in_error_code)
117 : type(in_type),
118 result(in_result),
119 error_code(in_error_code) {}
120
121 Type type;
122 Result result;
123 int error_code;
124};
125
Darin Petkov6a5b3222010-07-13 14:55:28 -0700126class OmahaRequestAction;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000127class NoneType;
128
129template<>
Darin Petkov6a5b3222010-07-13 14:55:28 -0700130class ActionTraits<OmahaRequestAction> {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000131 public:
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700132 // Takes parameters on the input pipe.
Darin Petkov6a5b3222010-07-13 14:55:28 -0700133 typedef OmahaRequestParams InputObjectType;
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700134 // On UpdateCheck success, puts the Omaha response on output. Event
135 // requests do not have an output pipe.
Darin Petkov6a5b3222010-07-13 14:55:28 -0700136 typedef OmahaResponse OutputObjectType;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000137};
138
Darin Petkov6a5b3222010-07-13 14:55:28 -0700139class OmahaRequestAction : public Action<OmahaRequestAction>,
140 public HttpFetcherDelegate {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000141 public:
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700142 // The ctor takes in all the parameters that will be used for making
143 // the request to Omaha. For some of them we have constants that
144 // should be used.
145 //
rspangler@google.com49fdf182009-10-10 00:57:34 +0000146 // Takes ownership of the passed in HttpFetcher. Useful for testing.
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700147 //
148 // Takes ownership of the passed in OmahaEvent. If |event| is NULL,
149 // this is an UpdateCheck request, otherwise it's an Event request.
150 // Event requests always succeed.
151 //
rspangler@google.com49fdf182009-10-10 00:57:34 +0000152 // A good calling pattern is:
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700153 // OmahaRequestAction(new OmahaEvent(...), new WhateverHttpFetcher);
154 // or
155 // OmahaRequestAction(NULL, new WhateverHttpFetcher);
156 OmahaRequestAction(OmahaEvent* event,
157 HttpFetcher* http_fetcher);
Darin Petkov6a5b3222010-07-13 14:55:28 -0700158 virtual ~OmahaRequestAction();
159 typedef ActionTraits<OmahaRequestAction>::InputObjectType InputObjectType;
160 typedef ActionTraits<OmahaRequestAction>::OutputObjectType OutputObjectType;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000161 void PerformAction();
162 void TerminateProcessing();
163
164 // Debugging/logging
Darin Petkov6a5b3222010-07-13 14:55:28 -0700165 static std::string StaticType() { return "OmahaRequestAction"; }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000166 std::string Type() const { return StaticType(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000167
168 // Delegate methods (see http_fetcher.h)
169 virtual void ReceivedBytes(HttpFetcher *fetcher,
170 const char* bytes, int length);
171 virtual void TransferComplete(HttpFetcher *fetcher, bool successful);
172
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700173 // Returns true if this is an Event request, false if it's an UpdateCheck.
174 bool IsEvent() const { return event_.get() != NULL; }
175
rspangler@google.com49fdf182009-10-10 00:57:34 +0000176 private:
177 // These are data that are passed in the request to the Omaha server
Darin Petkov6a5b3222010-07-13 14:55:28 -0700178 OmahaRequestParams params_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000179
Darin Petkov0dc8e9a2010-07-14 14:51:57 -0700180 // Pointer to the OmahaEvent info. This is an UpdateCheck request if NULL.
181 scoped_ptr<OmahaEvent> event_;
182
rspangler@google.com49fdf182009-10-10 00:57:34 +0000183 // pointer to the HttpFetcher that does the http work
184 scoped_ptr<HttpFetcher> http_fetcher_;
185
186 // Stores the response from the omaha server
187 std::vector<char> response_buffer_;
188
Darin Petkov6a5b3222010-07-13 14:55:28 -0700189 DISALLOW_COPY_AND_ASSIGN(OmahaRequestAction);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000190};
191
192} // namespace chromeos_update_engine
193
Darin Petkov6a5b3222010-07-13 14:55:28 -0700194#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H__