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.

Introduction

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.

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.

Dependencies

This specification relies on several underlying specifications.

HTML5
The terms and algorithms event handlers, event handler event type, origin, same origin, fetching resources, browsing context, active document, child browsing context, application cache, application cache group, relevant application cache, master entries, application cache selection algorithm, cache host, manifest, explicit entries, HTTP GET equivalent, task, task source, and queue a task, storage mutex, the manifest attribute, and the Function and ApplicationCache interfaces are referenced in this specification and defined by the HTML 5 specification [[!HTML5]].
HTTP

A conforming user agent must support some version of the HTTP protocol [[!HTTP11]].

In order to protect against attacks, the use of the following headers is prohibited using interfaces defined in this specification.

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Authorization
  • Cache-Control
  • Connection
  • Content-Transfer-Encoding
  • Cookie
  • Date
  • Expect
  • Host
  • Keep-Alive
  • Origin
  • Range
  • Referer
  • Set-Cookie
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • User-Agent
  • Via
HTTP State Management

A conforming user agent must support storage and exchange of cookies as specified by HTTP State Management [[!COOKIES]].

File API
The term Blob is referenced by this specification and defined by the File API specification [[!FILE-API]].
DOM

A conforming user agent must define the exception codes INVALID_STATE_ERR and NOT_FOUND_ERR, and Event and DOMException interface defined in [[!DOM-LEVEL-3-CORE]] and referenced in this specification.

Terminology

A managed resource is one whose URI is dynamically captured in an application cache.

A resource is captured when it is dynamically added to an application cache.

A resource is released when it is dynamically removed from an application cache.

A static representation is one that is generated directly by the user agent from an application cache.

A dynamic representation is one that is generated programmatically by using application-supplied logic in an embedded local server.

Transparent off-line data access and manipulation means to locally generate a static or a dynamic response for HTTP requests to captured resources.

Programmable HTTP Caching and Serving

Programmable HTTP processing enables applications to identify managed resources to a user agent and to produce static and dynamic representations for responding to requests on these resources.

Introduction

A user agent processes network requests to managed resources in one of three ways:

  1. serve policy - respond with the static representation of the requested resource (for any safe HTTP methods) from the application cache.
  2. intercept policy - immediately invoke an embedded local server to obtain a dynamic representation (for any HTTP methods).
  3. 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.

Examples

An application can use an application cache to programmatically capture the representation of a resource, i.e., cache an off-line representation in the application cache.

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.

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]].

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

A dynamic representation is produced by using an embedded local server in conjunction with the application cache. An interceptor processes an HTTP request locally in an embedded local server without changing the network APIs used by applications. Thus even if a host is unreachable, applications can successfully make HTTP requests to a managed resource.

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.

var uri = ... var cache = window.applicationCache; var local = function(request, response) { response.setStatus(200, 'OK'); response.setResponseText('Hello World'); }; window.navigator.registerOfflineHandler(uri, local); var req = cache.offline(uri, '', null, ['GET']);

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 local off-line handler which produces a dynamic response.

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:

  • intercepted and served by an interceptor, when the user agent is off-line or
  • the server, when the user agent is online with a reviewer analyzing the result of the online request.

A user agent can switch between these two behaviors automatically based on system conditions.

For example, an application worker script that wishes to allow off-line updates to uri captures that resource in an application cache.

var uri = ... var cache = self.applicationCache; cache.immediate(uri, ['PUT']);

Another application in the same origin could then register an off-line handler for the same uri to serve off-line requests to that resource.

var cache = window.applicationCache; var intercept = function(request, response) { if (...) { // validation fails response.setStatus(400, 'Bad Request'); response.setResponseText('Request not understood'); return; } var type = request.headers['Content-Type'] || 'text/plain'; var req = cache.offline(request.targetURL, request.bodyText, type); req.onsuccess = function() { response.setResponseText(request.bodyText); response.setResponseHeader('Content-Type', type); response.setStatus(200, 'OK'); } }; var review = function(request, response) { var req = cache.offline(request.targetURL, response.bodyText, response.headers['Content-Type']); }; window.navigator.registerOfflineHandler(uri, intercept, review);

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.

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

If this application makes a GET request to uri, then its cached static representation is returned as the response regardless of whether the user agent is off-line.

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

Event summary

An application updates the managed resources of an application cache. During this update, the user agent will add or remove the representations of managed resources to and from the application cache.

As this is going on, a number of events get fired to keep the script updated as to the state of the cache transaction, so that the user can be notified appropriately. The events are as follows:

Event nameOccasionNext events
captured The user agent has finished fetching and storing the representation of a managed resource. captured, released, ready
released The user agent has released a managed resource and can no longer serve off-line requests to it. captured, released, ready
ready The user agent has finished capturing and releasing the requested resources and does not have any pending requests in this cache transaction. Last event in sequence.

Programmable HTTP Caching

This specification adds two new kinds of entries for application cache to the various kinds defined in [[!HTML5]]:

static entry
A managed resource whose representation is cached for off-line serving. A request to a static entry can only be used with the serve policy.
dynamic entry
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.
Only a document with a manifest can use managed resources.

Each application cache has a dynamic completeness flag, which is either incomplete or complete. Each application cache whose dynamic completeness flag is complete has a version. No two application caches in an application cache group may have the same version. A newer application cache has a larger version.

Each application cache group has a dynamic update status, which is one of the following: idle or updating.

Application scripts identify the resources managed by an application cache during a cache transaction, when applications may either capture or release its resources.

Each cache transaction has an application cache group and an application cache.

A cache transaction can be marked as off-line transaction.

Each cache transaction has a commit status, which can be either of pending, committed, or aborted.

When a cache transaction is started, the user agent must run the steps to create a cache transaction. When a resource is added to a transaction's list of captured resources, the user agent must run the steps to add a resource to be captured. When a resource is added to a transaction's list of released resources, the user agent must run the steps to add a resource to be released. When the transaction is finished, the user agent must run either the steps to commit a cache transaction or the steps to abort a cache transaction.

Starting a transaction

When the user agent is required to create a cache transaction given an application cache group and an off-line flag, the user agent must run the following steps:

  1. Let cache group be the application cache group passed to these steps.
  2. If cache group is marked obsolete, then set an error and abort these steps.
  3. Pick the appropriate steps:
    If the off-line flag passed to these steps is set.
    1. Create a new application cache, called cache, in cache group.
    2. Set the dynamic completeness flag of cache to incomplete.
    3. Create a new cache transaction called transaction and set cache to be its application cache.
    4. Mark transaction as off-line transaction.
    5. Return transaction.
    If the off-line flag passed to these steps is not set.
    1. Atomically, so as to avoid race conditions, perform the following sub-steps
      1. If the dynamic update status of cache group is updating, then set an error and abort these steps, as a cache transaction is already open on this application cache group.
      2. Set the dynamic update status of cache group to updating.
    2. Create a new application cache, called cache, in cache group which holds all the same resources as the relevant application cache of cache group.
    3. Set the dynamic completeness flag of cache to incomplete.
    4. Create a new cache transaction called transaction and set cache to be its application cache.
    5. Mark transaction as not off-line.
  4. Set transaction's commit status to pending.
  5. Return transaction.

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:

  1. Let transaction be the cache transaction passed to these steps.
  2. If transaction's commit status is not pending, then set an error and abort these steps.
  3. Pick the appropriate sub-steps:
    If the cache host passed to these steps is a Document object
    Let origin be the origin of the cache host passed to these steps.
    If the cache host passed to these steps is a WorkerGlobalScope object
    Let origin be the origin of the scripts in the worker for the cache host passed to these steps.
  4. Resolve the URI passed to these steps relative to base URI.
  5. If the resulting absolute URI has a different <scheme> component than the base URI (compared in an ASCII case-insensitive manner), then set an error and abort these steps.
  6. If the resulting absolute URI does not have the same origin as base URI, then set an error and abort these steps.
  7. Drop the <fragment> component of the resulting absolute URI, if it has one.
  8. Let cache be transaction's application cache.
  9. If the resulting absolute URI identifies an explicit entry or master entry or the manifest of cache, then set an error and abort these steps.
  10. If the resulting absolute URI identifies a managed resource that is already in cache, then remove that managed resource from cache.
  11. Pick the appropriate sub-steps:
    If transaction is not marked as off-line
    1. 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.
    2. 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.

    3. 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.

    4. 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 transaction is marked as off-line.
    1. 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.
    2. Let representation be the content passed to these steps.
    3. Let type be the content type passed to these steps.
    4. If type is empty or null, set it to text/plain.
    5. Store in cache a managed resource comprising the resulting absolute URI, representation, and the list of dynamic methods passed to these steps.
  12. 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:

  1. Discard cache.
  2. Set cache group's dynamic update status to idle.
  3. Pick the appropriate sub-steps:
    If the status code was not 404 or 410 or equivalent, then
    Skip this resource and release it from application cache.
    Otherwise
    Set the error code to the status code passed to these steps.
  4. Mark transaction's commit status as aborted.

Attempts to fetch resources as part of the steps to add a resource to be captured may be done with cache-defeating semantics, to avoid problems with stale or inconsistent intermediary caches.

Releasing resources

When the user agent is required to add a resource to be released, given the URI of the resource to release, and a cache transaction, the user agent must perform the following steps:

  1. Let transaction be the cache transaction passed to these steps.
  2. If transaction's commit status is not pending, then set an error and abort these steps.
  3. Pick the appropriate sub-steps:
    If the cache host passed to these steps is a Document object
    Let origin be the origin of the cache host passed to these steps.
    If the cache host passed to these steps is a WorkerGlobalScope object
    Let origin be the origin of the scripts in the worker for the cache host passed to these steps.
  4. Resolve the URI passed to these steps relative to base URI.
  5. If the resulting absolute URI has a different <scheme> component than the base URI (compared in an ASCII case-insensitive manner), then set an error and abort these steps.
  6. If the resulting absolute URI does not have the same origin as base URI, then set an error and abort these steps.
  7. Drop the <fragment> component of the resulting absolute URI, if it has one.
  8. Let cache be transaction's application cache.
  9. If the resulting absolute URI does not identify a managed resource that is already in cache, then set an error and abort these steps.
  10. Remove the managed resource for the resulting absolute URI from cache.
  11. Queue a task to fire an event at transaction for the URI passed to these steps with the name released, which does not bubble, is not cancelable, and which uses the CacheEvent interface.

Commiting a transaction

When the user agent is required to commit a cache transaction, given a cache transaction, it means that the user agent must run the following steps:

  1. Let transaction be the cache transaction passed to these steps.
  2. If transaction's commit status is not pending, then set an error and abort these steps.
  3. Let cache be transaction's application cache.
  4. Let cache group be the application cache group containing cache.
  5. Atomically, so as to avoid race conditions, perform the following sub-steps:
    1. Let cache group version be the version of the relevant application cache of cache group.
    2. Set cache's version to be higher than cache group version.
    3. Set the cache's dynamic completeness flag to complete.
    4. Obtain the storage mutex.
    5. If the host sets cookies in response to such a request, the user agent should update its cookie store accordingly.
    6. Release the storage mutex.
  6. Pick the appropriate sub-steps:
    If transaction is marked as off-line, then
    1. Make cache the effective application cache for cache group to the cache host passed to these steps.
    If transaction is not marked as off-line, then
    1. Set the dynamic update status of cache group to idle.
  7. Queue a task to fire an event at transaction with the name ready, which does not bubble, is not cancelable, and which uses the Event interface.
  8. Set transaction's commit status as committed.

Aborting a transaction

When the user agent is required to abort a cache transaction, given a cache transaction, it means that the user agent must run the following steps:

  1. Let transaction be the cache transaction passed to these steps.
  2. If transaction's commit status is not pending, then set an error and abort these steps.
  3. Discard transaction's application cache.
  4. Set transaction's commit status as aborted.

The API Entry Point

Here's how a shared worker opens an application cache group.

var cache = self.applicationCache;

Here's how a window opens an application cache group.

var cache = window.applicationCache;
attribute ApplicationCache2Request applicationCache

(In a window.) Returns the ApplicationCache2Request object that applies to the active document of that Window.

(In a shared worker.) Returns the ApplicationCache2Request object that applies to the current shared worker.

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:

Event nameDispatched when...
success The application cache request has been completed and its results are available.
error There was an error performing the application cache request.
void abort()
Discontinue the in-flight request and return the readyState to INITIAL. No result or error is set.
const unsigned short INITIAL = 0
This state indicates that a request has not been started.
const unsigned short LOADING = 1
This state indicates that a request has been started but its result is not yet available.
const unsigned short DONE = 2
This state indicates that a result to a previous request is available in the result or error attribute.
readonly attribute unsigned short readyState
The completion state of this request
readonly attribute any error
The error that occurred during the execution of this request
readonly attribute any result
The result of a successful completion of the request
attribute Function onsuccess
The event handler for the success event
attribute Function onerror
The event handler for the error event

Extending the ApplicationCache interface

Additional metadata is available about an application cache through the ApplicationCache2.

readonly attribute unsigned long version
The version of this application cache
readonly attribute unsigned long long size
The approximate number of bytes occupied by this application cache.
readonly attribute long long lastRefresh
The number of milliseconds since the midnight of January 1, 1970 that elapsed till the time this application cache was last refreshed
readonly attribute unsigned long pendingUpdates
A count of the approximate number of updates that are pending for the application
readonly attribute DOMString outbox
The URL for processing items in the outbox of the application using this application cache
Interactions with an application cache cause background network and storage processing. Since these actions can take time, an asynchronous request-based API is specified here.
AppCacheRequest setOutbox()
Set the
DOMString uri
identifying the resource to use as the URL for processing items in the outbox of the application using this application cache
AppCacheRequest immediate()
When this method is called, the user agent returns immediately with a new AppCacheRequest object called result and asynchronously performs the following steps:
  1. Perform the steps to create a cache transaction using this application cache group and an unset off-line flag. Call the returned cache transaction as transaction.
  2. If there was an error while starting a cache transaction, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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.
  3. Perform the steps to add a resource to be captured with the URI passed to these steps, transaction, and the dynamic methods passed to these steps.
  4. If there was an error while capturing, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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.
  5. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
  6. Switch to the newest application cache in this application cache group.
DOMString uri
identifying the resource to capture
optional DOMString dynamicMethods
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.
AppCacheRequest offline()
When this method is called, the user agent returns immediately with a new AppCacheRequest object called result and asynchronously performs the following steps:
  1. Perform the steps to create a cache transaction using this application cache group and a set off-line flag. Call the returned cache transaction as transaction.
  2. If there was an error while starting a cache transaction, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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.
  3. 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.
  4. If there was an error while capturing, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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.
  5. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
  6. Switch to the newest application cache in this application cache group.
DOMString uri
identifying the resource to capture
DOMString body
entity body for the resource
optional DOMString contentType
The MIME type of the entity body
optional DOMString dynamicMethods
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.
AppCacheRequest transaction()
When this method is called, the user agent returns immediately with a new AppCacheRequest object called result and asynchronously performs the following steps:
  1. If this application cache group has a cache transaction whose commit status is pending, then choose from the following:
    If the restart flag was passed to these steps and it is set
    Let transaction be that cache transaction.
    Otherwise
    Perform the steps to abort a cache transaction with that cache transaction.
  2. If transaction is not set, then perform the following sub-steps:
    1. Perform the steps to create a cache transaction with this application cache group and an unset off-line flag.
    2. If there was an error while starting a cache transaction, then perform the following sub-steps and skip the remaining steps:
      1. Set result's error to be the error of the previous step.
      2. 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.
    3. Call the returned cache transaction as transaction.
  3. Let txn be a new OnlineTransactionRequest object for transaction.
  4. Set result's result to be txn.
  5. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
optional boolean restart
This defaults to false. This flag specifies whether to continue a previously abandoned cache transaction.
AppCacheRequest offlineTransaction()
When this method is called, the user agent returns immediately with a new AppCacheRequest object called result and asynchronously performs the following steps:
  1. Perform the steps to create a cache transaction with this application cache group of this object and a set off-line flag.
  2. If there was an error while starting a cache transaction, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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
  3. Call the returned cache transaction as transaction.
  4. Let txn be a new OfflineTransactionRequest object for transaction.
  5. Set result's result to be txn.
  6. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
CacheCursorRequest openModifiedItemCursor()
When this method is called, the user agent performs the steps to create a cache cursor with this application cache and the version passed to these steps, and returns the result of those steps.
long version
Version of this application cache since which modifications are sought. A value 0 indicates that every modification since the first cache transaction of this application cache is sought.
The method must raise an INVALID_STATE_ERR if the version passed to these steps is not less than the version of this application cache.

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:

  1. Let additions be a list of entities with their URIs and let removals be a list of URIs.
  2. Let cache be the application cache passed to these steps.
  3. For each application cache belonging to cache's application cache group, starting from cache's version down to low watermark version, perform the following sub-steps:
    1. Let old cache be the application cache.
    2. Let old version be old cache's version.
    3. For the entity entity of each managed resource of old cache that was added in the old version, perform the following steps:
      1. Let id be the URI of the managed resource.
      2. If neither additions nor removals already includes id, then add id with entity to additions.
    4. For each managed resource of old cache that was removed in the old version, perform the following steps:
      1. Let id be the URI of the managed resource.
      2. If neither additions nor removals already includes id, then add id to removals.
  4. Prepare a list of items by appending removals to additions and set that list as cursor's item list.
  5. Set cursor's current position to the first item in item list.
  6. Set result's result to the item at cursor's current position in item list.
  7. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
void continue()
  1. If there are no more items past this object's current position, in item list, then skip the remaining steps and perform the following sub-steps:
    1. Set error to be 0.
    2. 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.
  2. If there is another item past this object's current position, in item list, then move this object's current position to the next in item list.
  3. Set result to the item at cursor's current position in item list.
  4. Queue a task to fire an event at this object with the name success, which does not bubble, is not cancelable, and which uses the Event interface
attribute Function oncaptured
The event handler for the captured event
attribute Function onreleased
The event handler for the released event
attribute Function onready
The event handler for the ready event
void resetPendingUpdates()
Set the count of pending updates for this application cache to 0
void incrementPendingUpdates()
Increment the count of pending updates for this application cache by 1
void decrementPendingUpdates()
Decrement the count of pending updates for this application cache by 1
AppCacheRequest getItem(in DOMString uri)
When called, this method must immediately return with a new AppCacheRequest object called result and asynchronously perform the following steps:
  1. If the resource identified by uri does not exist in this cache transaction's application cache, then skip the remaining steps and perform the following sub-steps:
    1. Set error to be NOT_FOUND_ERR.
    2. 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.
  2. Let item be the entity in this cache transaction's application cache.
  3. Create object, a new CacheItem object with the associated item.
  4. Set result's result to object.
  5. Queue a task to fire an event at this object with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
DOMString uri
identifying the resource
AppCacheRequest release(in DOMString uri)
When called, this method must immediately return with a new AppCacheRequest object called result and asynchronously perform the following steps:
  1. Perform the steps to add a resource to be released with the first argument being uri and the third being this cache transaction.
  2. If the steps raised an error, then skip the remaining steps and perform the following sub-steps:
    1. Set error to be the error set in the above steps.
    2. 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.
  3. Queue a task to fire an event at this object with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
DOMString uri
identifying the resource to release
AppCacheRequest abort()
When called, this method must immediately return with a new AppCacheRequest object called result and asynchronously perform the following steps:
  1. Execute the steps to abort a cache transaction with the this cache transaction.
  2. If the steps raised an error, then skip the remaining steps and perform the following sub-steps:
    1. Set error to be the error set in the above steps.
    2. 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.
  3. Queue a task to fire an event at this object with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
AppCacheRequest commit()
When called, this method must immediately return with a new AppCacheRequest object called result and asynchronously perform the following steps:
  1. Execute the steps to commit a cache transaction with the this cache transaction.
  2. If the steps raised an error, then skip the remaining steps and perform the following sub-steps:
    1. Set error to be the error set in the above steps.
    2. 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.
  3. Queue a task to fire an event at this object with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
AppCacheRequest capture()
When called, this method must immediately return with a new AppCacheRequest object called result and asynchronously perform the following steps:
  1. Perform the steps to add a resource to be captured with the URI passed to these steps, this cache transaction, and the dynamic methods passed to these steps.
  2. If there was an error while capturing, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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.
  3. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
DOMString uri
identifying the resource to capture
optional DOMString dynamicMethods
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.
AppCacheRequest capture()
When called, this method must immediately return with a new AppCacheRequest object called result and asynchronously perform the following steps:
  1. 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.
  2. If there was an error while capturing, then perform the following sub-steps and skip the remaining steps:
    1. Set result's error to be the error of the previous step.
    2. 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.
  3. Queue a task to fire an event at result with the name success, which does not bubble, is not cancelable, and which uses the Event interface.
DOMString uri
identifying the resource to capture
DOMString body
entity body for the resource
optional DOMString contentType
The MIME type of the entity body
optional DOMString dynamicMethods
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.
const unsigned short UNCACHED = 0
This CacheItem object is associated with a managed resource which has been added for capturing but has not yet been cached. There is no value available in body or headers.
const unsigned short FETCHING = 1
This CacheItem object is associated with a managed resource which is currently being fetched. There is no value available in body or headers.
const unsigned short CACHED = 2
This CacheItem object is associated with a managed resource which has been cached.
const unsigned short GONE = 3
This CacheItem object is associated with a managed resource which has been released. There is no value available in body, headers, or dynamicMethods.
readonly attribute unsigned short readyState
This attribute, on getting, must return the current state of the managed resource.
readonly attribute Blob body
This attribute, on getting, must return the entity body, if any, as a Blob object, of the managed resource associated with this CacheItem object.
readonly attribute DOMStringList dynamicMethods
This attribute, on getting, must return the list of protocol methods, if any, of the managed resource associated with this CacheItem object.
readonly attribute any headers
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.

The CacheEvent Interface

The task source for this task is the networking task source.

readonly attribute DOMString uri
This attribute, on getting, must return the URI of the managed resource for which this event is fired.
void initCacheEvent()
These methods must initialize the event in a manner analogous to the similarly named methods in the DOM Events interfaces. [[!DOM-LEVEL-3-EVENTS]]
optional DOMString uri
void initCacheEventNS()
These methods must initialize the event in a manner analogous to the similarly named methods in the DOM Events interfaces. [[!DOM-LEVEL-3-EVENTS]]
DOMString namespaceURI
optional DOMString uri

The following are the event handlers (and their corresponding event handler event types) that must be supported, as IDL attributes, by objects implementing the CacheTransaction interface and CacheTransactionRequest interface:

Event handler Event handler event type
onready ready
oncaptured captured
onreleased released

Programmable HTTP Serving

An embedded local server is an application script that generates dynamic responses to resource requests without making those requests to the origin server.

An embedded local server consists of an interceptor function and zero or one reviewer function.

An embedded local server serves requests to resources in its interception namespace.

A cache host can be associated with zero or more embedded local servers.

An resource request issued in a cache host can be an interceptible request if the resource is in the interception namespace of an embedded local server registered in the browsing context of the cache host and the resource is a dynamic entry in the application cache group associated with the cache host and the request method is identified as one of the dynamic entry's dynamic methods .

If an embedded local server can intercept a resource request, then it is called a candidate local server for that request.

Multiple embedded local servers can be the candidate local server for a given resource request. If a user agent is to select an embedded local server from a list of candidate local servers that can produce a dynamic representation of the requested resource, then the user agent must use the embedded local server that has the most specific interception namespace.

Local Server Interfaces

void registerOfflineHandler()
DOMString namespace
identifying the interception namespace for this embedded local server
InterceptHandler intercept
the interceptor function of this embedded local server
optional ReviewHandler review
the reviewer function of this embedded local server

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.

void removeOfflineHandler()
This method removes the registered embedded local server for the given namespace from the cache host, which is the active document of the browsing context of the window containing this Navigator object.
DOMString namespace
identifying the interception namespace for this embedded local server
The method must raise an NOT_FOUND_ERR if the version passed to these steps is not less than the version of this application cache.

void 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.

HttpRequest request
MutableHttpResponse response
void 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.

HttpRequest request
HttpResponse response
readonly attribute DOMString method
This attribute, on getting, must return the HTTP method, in upper-case characters, present on this HttpRequest object.
readonly attribute DOMString target
This attribute, on getting, must return the URI of this HttpRequest object.
readonly attribute DOMString bodyText
This attribute is a DOMString representing the request entity body, which on getting, must return the result of the following steps:
  1. If the request entity body is null, return the empty string and terminate these steps.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. If charset is null, then let charset be UTF-8.
  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.
readonly attribute any headers
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.
void setStatus(in unsigned short code, in DOMString message)
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.
void setResponseText(in DOMString text)
This method takes a single arguments - body of the response entity. Upon calling, this method must store the entity body in this MutableHttpResponse object, replacing any previous value.
void setResponseHeader(in DOMString name, in DOMString value)
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.
void delay()
Mark this response to be explicitly dispatched. This means that the InterceptHandler would need to explicitly call send() in order to mark the response as ready for being returned to the application.
void send()
Upon calling, this method must dispatch this MutableHttpResponse object. No further changes must be allowed to it.
readonly attribute unsigned short statusCode
This attribute, on getting, must return the status code of this HttpResponse object.
readonly attribute DOMString statusMessage
This attribute, on getting, must return the status message of this HttpResponse object.
readonly attribute DOMString bodyText
This attribute is a DOMString representing the response entity body, which on getting, must return the result of the following steps:
  1. If the response entity body is null, return the empty string and terminate these steps.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. If charset is null, then let charset be UTF-8.
  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.
readonly attribute any headers
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.

Changes to the networking model

When a cache host is associated with an application cache whose dynamic completeness flag is complete, any and all loads for resources related to that cache host other than those for child browsing contexts must go through the following steps prior to the the networking model for application caches defined in [[!HTML5]].

  1. Let request be the resource request for fetching the resource.
  2. If request includes the HTTP header Cache-Control with the value no-cache, then fetch the resource normally, and abort these steps.
  3. Let cache be the application cache for the cache host.
  4. Let resource be the resource to be fetched.
  5. If resource is not managed in cache, then fetch a representation of resource normally and abort these steps.
  6. 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.
  7. 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.
  8. 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.
  9. Perform the steps to select an embedded local server server.
  10. If server is not set, then fetch a representation of resource normally and abort these steps.
  11. Pick the appropriate steps:
    If the user agent is off-line
    1. Create a new response object to hold the dynamic response to request.
    2. Call the interceptor function of server passing as arguments request and response.
    3. Wait for the interceptor function to dispatch the dynamic response until the typical network timeout.
    4. If the dynamic response times out, then raise a time out error and abort these steps.
    5. Handle response as the dynamic response, and abort these steps.
    If the user agent is online
    1. If the reviewer function of server is not set, then abort these steps and perform the steps for the case when the user agent is off-line.
    2. Fetch a representation of resource normally and call it response.
    3. Call the reviewer function of server passing as arguments request and response.
    4. Handle response as the dynamic response, and abort these steps.

Security Considerations

This section is not complete.

Apart from requirements affecting security made throughout this specification implementations may, at their discretion, not expose certain headers, such as HttpOnly cookies.

Acknowledgements

The editor of this specification was employed by Oracle Corp during its early drafts.
Thanks to Garret Swart, Colm Divilly, Ashish Motivala, Joseph Pecoraro, and Mike Wilson for their useful comments that have led to improvements to this specification over time.