- From: Marcos Caceres <marcosscaceres@gmail.com>
- Date: Wed, 28 May 2008 18:40:37 +1000
- To: "WAF WG (public)" <public-appformats@w3.org>
Taking into consideration the feedback we received last time, here is a new strawman proposal for automatic updates. The proposal provides four ways to do automatic updates: 1. Point directly to the resource on the web (and let HTTP headers and cache control take care of the update). 2. Point to an XML file written in our custom XML format (described below). 3. From local storage 4. API call Here is how it works in the case of 1: In the configuration document, the author provides an <update> element with a URL attribute that points to a widget resource. The author optionally includes an etag attribute that represents the ETag for that resource on the server: <widgets xmlns="..." id="http:/a.com/myWidget" > <update url="http:/a.com/myWidget.wgt" etag="36f4d2e876c5c51:b74"/> </widgets> If the author provides an etag attribute, then the widget user agent checks for a change in the ETag via a HEAD request (following any redirects). If the etag has not changed, the server responds with a 304. If the ETag has changed, then the user is asked if they want to download the new widget. If the user wants the new version, then a GET request is sent and the widget user agent stores the new ETag and other relevant caching information (just like a web browser would treat a resource). For future requests, the widget user agent can try If-Match or If-Modified-Since or If-None-Match. The widget engine accepts only "application/widget" as the content-type, though, as already stated, it can be redirected to reach the appropriate resource. If the configuration document of the newly acquired widget contains the same <update url> in canonical form, but a different etag attribute value from the ETag: header acquired over HTTP, then the etag attribute is in error and must be ignored. The ETag: value acquired from HTTP is used for all future requests until a new widget resource becomes available. (This is to stop the widget engine getting into an update loop). If the newly acquired resource contains a url attribute to a different update location, then the widget engine again informs the user that a new version is available... the process repeats until no more updates can be performed (or until the user gets bored of the update process:)). If no etag attribute is provided in the configuration document, the widget is run as normal. The widget user agent may eventually ask the the user if they want to update the widget. Once the first update is done, the widget user agent should have enough cached info to manage future updates. Note: In the absence of an etag attribute, an alternative could be to get the time of creation of the signature.xml or config.xml or a (default) start file inside the widget resource (denoted by the 'last mod file time/last mod file date' fields of a file entry), and use that value for If-Modified-Since... but that might be a bit messy. Issue: if upon download the server does not provide an etag (or other relevant cache info), then should the widget user agent stop attempting to download new versions? --- And here is how it works in the case of 2 (using a custom XML format): In the configuration document, the author provides an <update> element that points to some URL: <widgets xmlns="..." id="http:/a.com/myWidget" > <update url="http:/a.com/myWidget/updater.php?version=1.0"/> </widgets> The widget sends a request: GET /myWidget/update.php?version=1.0 Host: a.com User-Agent: SuperWidgetEngine Accept: text/xml; application/widget Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 If no update is available, server responds with a 304. Otherwise, server responds: HTTP/1.1 200 OK Date: Tue, 27 May 2008 06:02:05 GMT Content-Type: text/xml; Content-Length: 370 <?xml version="1.0" encoding="utf-8"?> <update xmlns="http://www.w3.com/ns/widget-updates" id="http:/a.com/myWidget" src="https://a.com/myWidget/v1.1b/awesome.wgt" version="1.1 beta (awesome edition)" bytes="1024"> <details>We fixed some bugs and added some new APIs!</details> OR <details url="http://www.bla.com/myWidget/1.1/whatsnew"/> <hash type="SHA1">e56b8ec42e1898559cc9f04dfe09f1b1663a4b97</hash> </update> So, the widget engine then checks that <update id> matches <widget id>and that <widget version> and <update version> are *different*. If so, then the user is informed that a new update is available by displaying the content of <details>, the new version number, and the value of the bytes attribute. If the user agrees to download the new widget, then the widget user agent attempts to retrieve the resource indicated by the src attribute of the update element. Once the new resource is downloaded, if the author provided the optional <hash> element, then the hash is calculated (using either MD5 or SHA1, as indicated by the type attribute). If all goes well, then the widget resource is processed as normal, checking that the <widget id> for the widget stays the same. If all goes the place, the old widget is either backed up or erased and the new widget takes its place. Any previously set preferences are kept. In the case of 3 (local storage), the widget user agent just needs to compare the id and version of the widget the new widget to the widget it is replacing. Lastly, in the case of 4 (API call), widgets can attempt to update themselves by calling the widget.update() method, which is defined in the Widgets API spec. The method takes no arguments, and uses the value of <update url> to ask the widget engine to attempt to perform an update. Widget engines can control the update process by making use of cache information or throttling, etc. -- Marcos Caceres http://datadriven.com.au
Received on Wednesday, 28 May 2008 08:41:23 UTC