Abstract

This document defines APIs for off-line serving of requests to HTTP resources using
static and dynamic responses. It extends the function of application caches defined in
HTML5.

Status of This Document

Beware.
This specification is no longer in active maintenance and the
Web Applications Working Group does not intend to maintain it further.

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

Publication as a Working Group Note does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

1. Introduction

This section is non-normative.

The existing cache manifest [HTML5] statically identifies cached
resources to be stored in an application cache. The API introduced
in this document extends the application cache by allowing
applications to programmatically add other resources to the cache
which can then be served by the user agent when that resource is
requested. This API also extends the application cache to enable
applications to programmatically generate responses to requests for
resources that have been added to the application cache. As a result,
the application cache can now be used to satisfy unsafe HTTP methods
such as PUT and POST.

Using this application cache extension, applications can obtain locally
cached data or data produced locally by JavaScript servers and perform
requests on resources that can be served whether or not the user agent
is connected to a remote server. Applications can then save and replay
locally satisfied requests to the server when it is reconnected, thus
enabling responsive and robust Web applications in the presence of low
connectivity conditions.

This specification does not require a new programming model for Web
applications as application caches can be configured to be transparently
pressed into action by the user agent, depending on system conditions.
Such applications can seamlessly switch between on-line and off-line
operation without needing explicit user action. This also means that
existing applications can be used unchanged in many cases
once the application cache is configured. Applications only need to be
altered to use APIs specified in this document if they require more
complex synchronization.

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].

This specification defines one class of products:

conforming user agent

A user agent must behave as described in this specification
in order to be considered conformant.

User agents may implement algorithms given in this
specification in any way desired, so long as the end result is
indistinguishable from the result that would be obtained by the
specification's algorithms.

A conforming user agent must also be a
conforming implementation of the IDL fragments
of this specification, as described in the
Web IDL specification. [WEBIDL]

This specification uses both the terms "conforming user agent(s)"
and "user agent(s)" to refer to this product class.

review policy -
relay the request to the server to obtain a dynamic
representation and notify an embedded local server
when that representation is available (only for unsafe HTTP methods).

The serve policy applies only to resources that do not
require interception, whereas the intercept policy can only
be used for resources that require interception. Both policies
improve availability and responsiveness. However, both may affect
data freshness. The review policy
can only be used when the user agent is able to communicate with
the server. This policy improves data freshness at the cost of
reduced responsiveness. User agents may choose freely from among
these options, e.g., using information about the system condition,
network state or battery power level, or a user preference.

4.1.1 Examples

An application captures a resource as part of an atomic
cache transaction. Once the resource is captured
successfully, the application places the captured
representation in to service. This can be performed through a
single API call.

ECMAScript

var uri = ...
var cache = window.applicationCache;
// cache and immediately take advantage of the new stuff in the cache
cache.immediate(uri);

The user agent is able to then serve this static representation
when an application issues a GET request for
that resource either through page navigation or an XMLHttpRequest
[XMLHTTPREQUEST].

In this example, a local request handler can produce a dynamic
response to an application request when the network is not accessible.
The response can be prepared using the
application cache, for example. The benefit
of this technique is that applications don't need to alter their
applications to accommodate off-line use cases.
Instead, user agents can transparently introduce an application-specific
off-line handler to deal with situations when the network is not
available.

Later when that application issues a GET request for
the managed resource either through page navigation or an XMLHttpRequest
[XMLHTTPREQUEST], and the user agent is off-line, it invokes the
localoff-line handler which produces a dynamic
response.

ECMAScript

var req = new XMLHttpRequest();
req.open('GET', uri);
...
req.send();

Applications can also locally intercept requests that modify data,
e.g., unsafe HTTP requests such as PUT in an off-line
handler. Requests to resources that are managed in an
application cache can be either:

When the application makes a PUT request to
uri and the user agent is off-line,
the user agent asks the intercept function to
process the request and respond to it. If the user agent is online
when the request arrives, then it sends the request to
a host and asks the review function to process the
response received from it.

A managed resource whose representation is produced locally
by an application upon request. Each dynamic entry
identifies one or more dynamic methods
for which a response can be obtained locally using an
interceptor.

4.2.2 Capturing resources

When the user agent is required to add a resource to be
captured, given the URI of the resource to
capture, a cache transaction,
optionally a list of dynamic methods, optionally content to
serve as the static representation of that resource, and
optionally content type for that representation, the user agent
must perform the following steps:

If the list of dynamic methods passed to these steps
includes the method GET, then skip the
remaining sub-steps and store in cache a
managed resource comprising the resulting absolute
URI and the list of
dynamic methods passed to these steps.

Fetch the representation of the resource identified by the
absolute URI. Use the transaction's
application cache as an
HTTP cache, and honor HTTP caching semantics (such as expiration,
ETags, and so forth) with respect to that cache. User agents may also
have other caches in place that are also honored.

If the resource in question is already being fetched
for other reasons, then the existing download process can
sometimes be used for the purposes of this step.

If the previous step fails (e.g. the server returns a 4xx
or 5xx response or equivalent, or there is a DNS error, or
the connection times out, or the user cancels the download),
or if the server returned a redirect, then run the
capture failure steps with the status code of the
previous step and terminate these steps.

Redirects are fatal because they are either indicative of
a network problem (e.g. a captive portal); or would allow
resources to be added to the cache under URIs that differ
from any URI that the networking model will allow access
to, leaving orphan entries; or would allow resources to
be stored under URIs different than their true URIs. All
of these situations are bad.

Otherwise, the fetching succeeded.
Store in cache a
managed resource comprising the resulting absolute URI,
its fetched representation, and the list of
dynamic methods passed to these steps.

If the list of dynamic methods passed to these steps
includes the method GET, then skip the
remaining sub-steps and store in cache a
managed resource comprising the resulting absolute
URI and the list of
dynamic methods passed to these steps.

Let representation be the content passed
to these steps.

Let type be the content type passed to these steps.

If type is empty or null, set it to text/plain.

Store in cache a managed resource comprising
the resulting absolute URI, representation, and the list of
dynamic methods passed to these
steps.

Queue a task to fire an event at
transaction for the URI passed to these steps with the
name captured, which
does not bubble, is not cancelable, and which uses the
CacheEvent interface.

The capture failure steps are performed with a status
code as follows:

4.2.7 Asynchronous requests

Events are fired during asynchronous access as managed
resources are accessed and manipulated. As requests are made for
managed resources, the user agent processes them and saves
or retrieves data from the network or storage, and when the
required data is available, it alerts the application through the
firing of events. The events are as follows:

The dynamic methods that are applicable to the identified
resource. This parameter is a comma separated list of protocol
methods that can be intercepted for local processing. An empty
string is allowed for this parameter.

Queue a task to fire an event
at result with the name
error, which
does not bubble, is not cancelable, and which uses the
Event interface.

Perform the steps to add a resource to be captured
with the URI passed to these steps, transaction,
the dynamic methods passed to these steps, the body
passed to these steps, and the content type passed to
these steps.

If there was an error while capturing, then perform the
following sub-steps and skip the remaining steps:

The dynamic methods that are applicable to the identified
resource. This parameter is a comma separated list of protocol
methods that can be intercepted for local processing. An empty
string is allowed for this parameter.

When the user agent is required to create a cache cursor,
given the application cache and the
low watermark version, the user agent must return a new
CacheCursorRequest object, called result
and asynchronously perform the following steps:

Let additions be a list of entities with their URIs and
let removals be a list of URIs.

The dynamic methods that are applicable to the identified
resource. This parameter is a comma separated list of protocol
methods that can be intercepted for local processing. An empty
string is allowed for this parameter.

Methods

capture

When called, this method must immediately return with a new
AppCacheRequest object called result and
asynchronously perform the following steps:

Perform the steps to add a resource to be captured
with the URI passed to these steps, transaction,
the dynamic methods passed to these steps, the body
passed to these steps, and the content type passed to
these steps.

If there was an error while capturing, then perform the
following sub-steps and skip the remaining steps:

The dynamic methods that are applicable to the identified
resource. This parameter is a comma separated list of protocol
methods that can be intercepted for local processing. An empty
string is allowed for this parameter.

This attribute, on getting, must return the headers as a native ordered
dictionary data type from the managed resource associated
with this CacheItem object. In the ECMAScript
binding, this must be Object. Each header must have
one property (or dictionary
entry), with those properties enumerating in the order that the headers
were recorded in the managed resource. Each property must
have the name of the header and its value as recorded in the
managed resource.

Methods

registerOfflineHandler

This method allows applications to register possible handlers
for particular URI namespaces. Upon being invoked, this method
should create a new embedded local server called
server with its interceptor
function set to intercept handler and its
reviewer function set to review handler
and add server to the cache host, which is
the active document of the browsing context of the
window containing this Navigator object.
If a handler already exists for the given namespace,
the existing embedded local server is replaced with the
one created in this call.

Methods

callback

The user agent must invoke the InterceptHandler,
with an HttpRequest
object request based on the application's resource request and an
MutableHttpResponse
object response. If the delay() method is invoked on response,
then when the send() method is invoked on response, the
user agent must respond to request with the headers, body, and
status specified in response.
If the delay() method is not invoked on response
in this callback, then the user agent must respond to request
with the headers, body, and status, specified in response
when this function exits.

Methods

callback

The user agent must invoke the ReviewHandler,
with an HttpRequest
object request based on the application's resource request and an
HttpResponse
object response based on the host's response to that request.

Attributes

This attribute is a DOMString representing the request entity body,
which on getting, must return the result of the following steps:

If the request entity body is null, return the empty string and
terminate these steps.

Let charset be the value of the
charset parameter of the Content-Type
header or null if there was no charset
parameter or if the header could not be parsed properly or was
omitted.

Let mime be the MIME type the Content-Type
header contains without any parameters or null if
the header could not be parsed properly or was omitted.

If charset is null and mime
is text/xml,
application/xml, or ends in +xml
use the rules set forth in the XML specifications to determine
the character encoding. Let charset be the
determined character encoding.

If charset is null and mime is
application/json follow the rules set forth in the
[RFC4627] specification to determine the character encoding.
Let charset be the determined character encoding.

If charset is null and mime is
text/html follow the rules set forth in the [HTML5]
specification to determine the character encoding. Let
charset be the determined character encoding.

If charset is null, then let
charset be UTF-8.

Return the result of decoding the response entity body using
charset. Replace bytes or sequences of bytes that are
not valid accordng to the charset with a single
U+FFFD REPLACEMENT CHARACTER character.

This attribute, on getting, must return the headers as a native ordered
dictionary data type from this HttpRequest object.
In the JavaScript binding, this must be
Object. Each header must have one property (or dictionary
entry), with those properties enumerating in the order that the headers
were present in the request. Each property must have the name of the
header and its value as present in the request.

This method takes two arguments - name and value
of a response header. Upon calling, this method must store the header
with name and value in this
MutableHttpResponse
object. If a value is already associated with this header, then
this method must append value to it.

This method takes two arguments - code and message
of the response status. Upon calling, this method must store the status
with code and message in this
MutableHttpResponse
object, replacing any previous values for both.

Attributes

This attribute is a DOMString representing the response entity body,
which on getting, must return the result of the following steps:

If the response entity body is null, return the empty string and
terminate these steps.

Let charset be the value of the
charset parameter of the Content-Type
header or null if there was no charset
parameter or if the header could not be parsed properly or was
omitted.

Let mime be the MIME type the Content-Type
header contains without any parameters or null if
the header could not be parsed properly or was omitted.

If charset is null and mime
is text/xml,
application/xml, or ends in +xml
use the rules set forth in the XML specifications to determine
the character encoding. Let charset be the
determined character encoding.

If charset is null and mime is
application/json follow the rules set forth in the
[RFC4627] specification to determine the character encoding.
Let charset be the determined character encoding.

If charset is null and mime is
text/html follow the rules set forth in the [HTML5]
specification to determine the character encoding. Let
charset be the determined character encoding.

If charset is null, then let
charset be UTF-8.

Return the result of decoding the response entity body using
charset. Replace bytes or sequences of bytes that are
not valid accordng to the charset with a single
U+FFFD REPLACEMENT CHARACTER character.

This attribute, on getting, must return the headers as a native ordered
dictionary data type from this
HttpResponse object.
In the JavaScript binding, this must be
Object. Each header must have one property (or dictionary
entry), with those properties enumerating in the order that the headers
were present in the response. Each property must have the name of the
header and its value as present in the response.

If resource is not managed in cache, then
fetch a representation of resource
normally and abort these steps.

If request is using the HTTP GET mechanism
and resource is not defined in cache with a
dynamic GET method,
then get the entity for resource from cache
(instead of fetching it), and abort these steps.

If request is using the HTTP HEAD mechanism
and resource is not defined in cache with a
dynamic HEAD method,
then get the entity headers for resource from cache
(instead of fetching it), and abort these steps.

If resource is not defined in cache with the
dynamic method that
request is using, then fetch a
representation of resource normally and abort these steps.