Viewer Update Service/Protocol/v1.0

The Update Service Protocol is implemented in the API presented by the Viewer Update Service.
==Basics==
This design is the result of research and a whiteboard discussion followed by comparison with and extension by Google's Omaha update server protocol.
We chose XML as a format (rather than, say, just responding with a redirect to a download url) due to its extensibility. Example potential future uses include more granular updates, updates with dependencies, and more sophisticated user options and viewer behavior regarding updates.
Rather than there being one update server per grid, there will be a single production update server, and test update servers as needed entirely unassociated with any particular grid.
==Design==
Requests are made to: https://update.secondlife.com/update
===Request===
Perform an HTTP GET to a URL of this form:
https://<hostname>/update/<protocol version>/<channel>/<your version>/<platform>
Example
 GET https://update.secondlife.com/update/v1.0/Second%20Life%20Release/2.3.0.214726/win
The 'v1.0' string is the version of the update service protocol version being used. This will enable us to maintain compatibility with older viewers when we choose to make changes to this service.
===Response===
200 OK
Content example
<?xml version="1.0" encoding="UTF-8"?>
<llsd>
 <map>
 <key>url</key><string>http://download.cloud.secondlife.com/thisupdate</string> 
 <key>hash</key><string>12345ACDDEF9381</string>
 <key>version</key><string>2.1.0.207030</string>
 <key>required</key><boolean>False</boolean>
 <key>size</key><integer>23467421</integer>
 <key>channel</key><string>Second Life Release</string>
 <key>pony</key><string>myponyurl</string>
 <key>more_info</key><string>http://wiki.secondlife.com/thisinfo</string> 
 <key>error_url</key><string>http://wiki.secondlife.com/myerorpage</string>
 </map>
</llsd>
Response Fields
If no update is available, the response message body is an empty llsd container.
If there is an update, the response will be populated as follows:
* url: the url of the update to download
* hash: the md5sum of the download
* version: the version of the update linked to by the download url
* required: boolean indicating whether an update is required
* size (optional): the size in bytes of the download
* channel (optional): repeat back the channel for which the update was requested
* pony (optional): a link to a picture of a pony. Your reward for performing an update
* more_info (optional): a url containing information about the update
* error_url (optional): a url containing information about any error that may have occurred
Note: size may be removed, as we are getting this information from HTTP headers instead at the moment.
===Errors===
404 Not Found
If you request a url that is not part of the defined update service interface, you'll receive a 404. 
Also, if you request a URL which contains a channel or version number that aren't in our version database, you'll receive a 404. Our version database tracks all publicly released versions in the Second Life Beta Viewer and Second Life Release channels.
406 Not Acceptable
If a request provides an accept header which contains a format specification that the server is unable to satisfy, the server will respond with a 406.
500 Internal Server Error
If the service hits an unexpected exception, it will return a 500.
===Testing URLs===
The following URL paths are provided for testing:
 https://<hostname>/noupdate/v1.0/...
 https://<hostname>/updaterequired/v1.0/...
 https://<hostname>/updateoptional/v1.0/...
Where '...' is replaced with a normal request predicate. Responses indicating no update, update required, or update optional are returned as described by the path.
For each of these, special channels will return differently formed responses, e.g.:
 https://<hostname>/updateoptional/v1.0/Bad%20Hash/...
Available channels:
 Bad%20Hash
 No%20Hash
 No%20URL
 No%20Size
...where each channel returns a response with the characteristic described by the channel name. All other channels besides these will return generic data containing correct hashes and urls for the platform requested.
==Discussion==
===Why LLSD?===
We compared LLSD as a format to use against atom and straight XML. 
* Atom would be able to handle our current use-case, but would not handle the projected future use-case of more granular or dependency-driven updates as naturally.
* We have server and client infrastructure in place to suport LLSD. We don't have the same infrastructure to support atom or straight XML 
* On the other hand, atom is an industry standard, with many pre-built tools and pre-made solutions.
* Atom feeds already enjoy some industry adoption for udpater services, aka "appcasts".
The cost of integrating a new xml library into our set of supported technologies and the tight time budget for version 1.0 of our updater service make atom and straight xml less desirable choices than LLSD at this time.