diff --git a/bin/cros_image_to_target.py b/bin/cros_image_to_target.py
index bb497f9249..5f758f2c76 100755
--- a/bin/cros_image_to_target.py
+++ b/bin/cros_image_to_target.py
@@ -39,6 +39,42 @@ STATEFUL_FILENAME = 'stateful.tgz'
# How long do we wait for the server to start before launching client
SERVER_STARTUP_WAIT = 1
+UPDATE_RESPONSE = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """
+NO_UPDATE_RESPONSE = """
+
+
+
+
+
+
+
+ """
class Command(object):
"""Shell command ease-ups for Python."""
@@ -449,34 +485,6 @@ class StringUpdateResponse(UpdateResponse):
class PingUpdateResponse(StringUpdateResponse):
"""Respond to a client ping with pre-fab XML response."""
- app_id = '87efface-864d-49a5-9bb3-4b050a7c227a'
- xmlns = 'http://www.google.com/update2/response'
- payload_success_template = """
-
-
-
-
-
-
-
- """
- payload_failure_template = """
-
-
-
-
-
-
-
- """
-
def __init__(self):
self.content_type = 'text/xml'
@@ -486,25 +494,90 @@ class PingUpdateResponse(StringUpdateResponse):
PingUpdateResponse.file_sha256 = filesha256
PingUpdateResponse.file_size = filesize
+ def GetCommonResponseValues(self):
+ """Returns a dictionary of default values that'll be substituted in the
+ response irrespective of the protocol version."""
+ response_values = {}
+ response_values['appid'] = '87efface-864d-49a5-9bb3-4b050a7c227a'
+ response_values['time_elapsed'] = self.SecondsSinceMidnight()
+ return response_values
+
+ def GetSubstitutedResponse(self, response_template, response_values):
+ """Substitutes the response template with response_values.
+
+ Args:
+ response_dict: Canned response template
+ response_values: Values to be substituted in the canned template.
+ Returns:
+ Xml string to be passed back to client.
+ Raises:
+ AutoupdateError if required response values are not present.
+ """
+ try:
+ response_xml = response_template % response_values
+ return response_xml
+ except KeyError as e:
+ self.Fatal('Missing response value: %s' % e)
+
+ def GetUpdateResponse(self, sha1, sha256, size, url, is_delta_format):
+ """Returns a response to the client corresponding to a new update.
+
+ Args:
+ sha1: SHA1 hash of update blob
+ sha256: SHA256 hash of update blob
+ size: size of update blob
+ url: where to find update blob
+ is_delta_format: true if url refers to a delta payload
+ Returns:
+ Xml string to be passed back to client.
+ """
+ response_values = self.GetCommonResponseValues()
+ response_values['sha1'] = sha1
+ response_values['sha256'] = sha256
+ response_values['size'] = size
+ response_values['url'] = url
+ (codebase, filename) = os.path.split(url)
+ response_values['codebase'] = codebase
+ response_values['filename'] = filename
+ response_values['is_delta_format'] = is_delta_format
+ response_values['extra_attr'] = ''
+ response_xml = self.GetSubstitutedResponse(UPDATE_RESPONSE,
+ response_values)
+ return response_xml
+
+ def GetNoUpdateResponse(self):
+ """Returns a response to the client corresponding to no update."""
+ response_values = self.GetCommonResponseValues()
+ response_xml = self.GetSubstitutedResponse(NO_UPDATE_RESPONSE,
+ response_values)
+ return response_xml
+
+
def Reply(self, handler, send_content=True, post_data=None):
"""Return (using StringResponse) an XML reply to ForcedUpdate clients."""
if not post_data:
return UpdateResponse.Reply(self, handler)
- request_version = (minidom.parseString(post_data).firstChild.
- getElementsByTagName('o:app')[0].
- getAttribute('version'))
+ root = minidom.parseString(post_data)
+ protocol = root.firstChild.getAttribute('protocol')
+ if (protocol != '3.0'):
+ raise BaseException('You first need to update your device to a build '
+ 'that uses Omaha v3 protocol for the update_engine.')
+
+ app = root.firstChild.getElementsByTagName('app')[0]
+ request_version = app.getAttribute('version')
if request_version == 'ForcedUpdate':
host, pdict = cgi.parse_header(handler.headers.getheader('Host'))
- self.string = (self.payload_success_template %
- (self.xmlns, self.SecondsSinceMidnight(),
- self.app_id, 'http://%s/%s' % (host, UPDATE_FILENAME),
- self.file_hash, self.file_sha256, self.file_size))
+ url = 'http://%s/%s' % (host, UPDATE_FILENAME)
+ self.string = self.GetUpdateResponse(self.file_hash,
+ self.file_sha256,
+ self.file_size,
+ url,
+ False) # is_delta_format
else:
- self.string = (self.payload_failure_template %
- (self.xmlns, self.SecondsSinceMidnight(), self.app_id))
+ self.string = (self.GetNoUpdateResponse())
StringUpdateResponse.Reply(self, handler, send_content)