This spec is for review only! This specification is for review and not for implementation! For the latest updates, including important bug fixes, please look at the draft instead.

This specification defines the app: URL scheme.

The app: URL scheme can be used by packaged applications to obtain resources that are inside a container. These resources can then be used with web platform features that accept URLs.

Implementors should be aware that this specification is not stable. Implementors who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation stage should join the aforementioned mailing lists and take part in the discussions.

app: URL

An app: URL is a [[!URL]] used by a packaged application to address resources within its container (e.g., a .zip file).

Instance identifier

The instance identifier is a string that uniquely an instance of a packaged application.

When the instance identifier is not provided by the developer, a user agent MUST synthesize one. The structure and length of identifier represented by the authority is application specific, but it MUST be suitable to use as Document's origin. See also privacy and security considerations.

Privacy and Security Considerations

Using a unique identifier (e.g., a UUID) as instance identifier can be exploited by an adversary as a digital finger print. This can allow a developer to, for example, restore cookies even if the user has cleared cookies from a user agent. As such, if the user agent relies on unique identifiers as the host component, then it should provide end-users with a means of regenerating the authority component. For instance, a user agent can the reset instance identifier when the user clears the user agent's private data.

When fetching data from an app: URL, a user agent needs to make sure that only files that were in the container can be accessed (i.e. those files should be sand-boxed). User agents need to watch out for symbolic links (or similar) inside a container, which can attempt to trick the user agent into accessing files that are on other parts of the file system.

Fetching a resource from a container

Fetching is application specific. For instance, [[FETCH]] defines how to fetch resources for use with HTML.

Obtaining a resource

To obtain a resource using URL and origin, run the steps below.

  1. If origin does not match the instance identifier for this application, return failure and terminate this algorithm.
  2. Let path be the path of URL.
  3. Attempt to obtain the file at path within the container:
    1. If attempting to access the resource at path results in an error (e.g., not found, the file is corrupt, locked, etc.), return failure.
    2. Otherwise, return the data of the resource at path.

There is one class of product that can claim conformance to this specification: a user agent.

A user agent is an implementation of this specification.

Use Cases and examples

For developers, this specification attempts to address the following use cases:

  1. Provide a URL scheme that is compatible with the features and security model of [[HTML]], so that applications that are packaged can make full use of web platform's capabilities. For example, the app: URL scheme should be usable as a document's address so that it can serve as its origin, and it should be compatible with APIs like [[XHR]].
  2. Provide fetching model that constrains retrieval of files to a specific container.
  3. Provide an addressing scheme that is easy to work with - and that developers are already accustomed to working with. The developer should not be bothered as to whether they are using http:// or app:// - the Web's capabilities and APIs need to just work!

The following example shows [HTML]'s window.location using then app: URL.

<!doctype html>
<script>
//Example using HTML's Location object
var loc =  window.location; 
console.log(loc.protocol === "app:"); //true 
console.log(loc.host === "com.foo.bar"); //true 
console.log(loc.href === "app://com.foo.bar/index.html"); //true 
console.log(loc.origin === "app://com.foo.bar"); //true 
console.log(loc.pathname === "/index.html"); //true 
console.log(loc.hash === "#example"); //true 
console.log(loc.port === ""); //true
</script>

This example shows an app: URL being resolved in [[HTML]].

var img = document.createElement("img");

//the following setter triggers HTML's resolve algorithm 
img.src = "example.gif"; 

//and the expected output: 
console.log(img.src === "app://c13c6f30/example.gif") //true

//Append the image to the document
document.body.appendChild(img); 
</script>

This example shows a resource within a packaged application being retrieved over [[XHR]].

function process() {
  // process the resulting data 
}

var xhr = new XMLHttpRequest();
xhr.onload = () => process(this.responseText);
xhr.open( "GET", "playlist.json");
xhr.send();

Acknowledgments

The bulk of the text in this specifications was derived from the Widget URI scheme specification. The Systems Application working group acknowledge the hard work of the Web Applications Working Group in laying down the foundations for this specification.