Oracle

Web Interface To Synchronization (BITSY) API
Version 0.3.1

Working Draft 21 May 2008

Editor:
Nikunj Mehta <nikunj.mehta@oracle.com>

Abstract

BITSY enables offline access to Internet data from any application including Web browsers. BITSY is an interface to control synchronization of Internet Atom feeds with local storage for satisfying the off-line data needs of applications. BITSY is designed to make applications resilient to network fickleness and do so without requiring changes to the way applications are written.

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document.

This is a working draft of the Web Interface To Synchronization (BITSY) API. This document was produced by Oracle. Oracle seeks the experience of all those that synchronize data for off-line applications to improve this spec further. Implementations and improvements of this specification are expected and welcome.

Comments on this document are invited and are to be sent to the document editor.

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.

Table of contents

1 Introduction
1.1 Feeds For Off-Line Applications
1.2 Implementation Considerations
1.3 Terminology
1.4 Conformance
2 BITSY Interfaces
2.1 Subscription
2.1.1 SubscriptionBuilder
2.1.2 Subscription
2.1.3 Subscription State Transitions
2.1.4 Linked Resource Subscription
2.1.5 Subscription List
2.2 Events
2.2.1 Event
2.2.2 Event subtypes
2.2.3 ErrorList
2.3 Client Proxy Emulation
3 Off-line HTTP Methods
3.1 GET
3.1.1 Feed
3.1.2 Entry
3.1.3 Resource
3.2 POST
3.3 PUT
3.4 DELETE
3.5 Update Propagation Results
3.6 HTTP State Management
4 Security Considerations
4.1 Transport Layer Security
4.2 Data Integrity
4.3 Authentication
4.4 Confidentiality

Appendices

A References
A.1 Normative References
A.2 Other References
B IDL Definitions
C ECMAScript Definitions
D Relax NG Compact Schema for Client Proxy Emulation Configuration

1 Introduction

This section is non-normative.

Unlike client-server applications used from desktop computers, those used from mobile devices such as smartphones, PDAs, and laptops face challenges of network consistency - either network is not available in certain regions, or its latency/bandwidth are inadequate, or constant network usage drains too much device power [OMTP]. Such restricitons are at odds with commonly used network-based software architecture such as three-tier browser-delivered Web applications that rely on an always-on network. Typically this results in the development of special mobile applications for specific mobile device platforms in a fat client-server architecture that synchronizes data with a host on the network.

BITSY — Web Interface To Synchronization — is an interface to client-side technology for keeping local copies of network data synchronized with their source. BITSY arose out of the need to perform lightweight, secure data synchronization in robust mobile applications without causing significant changes in the application itself. These applications must be responsive even in high latency networks as well as tolerate unpredictable network failures. BITSY is based on the experience of mobile applications developed for large organizations. BITSY builds upon existing Internet standard technologies such as feeds [RFC4287] and HTTP [RFC2616]. BITSY is in the native style of the Web [WEBARCH]. By native style, we mean the use of URLs, uniform methods of accessing and manipulating data, and hypermedia — an information medium consisting of text, video, audio, graphics, and hyperlinks among them. Data managed by BITSY is identified using URLs just as it is on the Internet, thereby enabling its use across existing applications.

Existing technologies for off-line storage of network data used in Web applications require custom synchronization involving custom client and server software. This is not a sustainable approach as anyone designing large numbers of such applications prefers a consistent style and code reuse. By implementing a consistent synchronization protocol, BITSY assures applications of highly available synchronized data and frees up developer time for developing application data structures and logic. Of course, application developers cannot just wash their hands off the differences between on-line and off-line behavior. Still, by basing its synchronization protocol on time-tested approaches for mobile applications, it is capable of solving the 80% case without bothering the application developer with details of the synchronization protocol.

This version of BITSY does not include pushed updates from a server, although that is a distinct evolution path for the specification. As of this version, BITSY implementations operate on a simple polling and client-driven model.

1.1 Feeds For Off-Line Applications

This section is non-normative.

The main concept in BITSY is that an application consuming data feeds can work from an off-line copy of the feed's contents. A data feed is a collection of similar records, e.g., contacts in an address book or press releases in a news feed. Atom feeds are ideally suited for off-line applications for the following reasons:

Web feeds used in applications comprise XML entries (records) each of which contains a single coarse-grained entity such as a contact or an order, represented in any text or binary format including, but not limited to, XML. An application simply needs to know the URLs of Web feeds it needs and BITSY does the necessary work to manage all the records in those feeds and their supporting data for off-line use.

1.2 Implementation Considerations

This section is non-normative.

BITSY acts as a client-side interceptor for HTTP requests to resources that it manages and uses an off-line store to serve requests for such resources. BITSY intercepts requests to all managed resources even when the device is online. For all managed resources, BITSY supports the following HTTP methods: GET and HEAD. BITSY also supports the methods PUT, POST, and DELETE for resources governed by the Atom publishing protocol [RFC5023]. Additionally, only when operating in the off-line mode, BITSY responds to the HTTP OPTIONS method.

By responding to HTTP requests when the device is online, BITSY implementations boost the responsiveness of applications while at the same time reducing battery and network usage. This also leaves existing applications unchanged in how they access data from the cloud regardless of their connectivity. However, this does mean that applications receive somewhat stale data all the time. Success of various general mobile applications show that slight staleness is acceptable to users as long as they do not have to manually manage the connectivity state of the application and receive updates automatically.

This specification only lays down the expectations of BITSY implementations in terms of syntax and semantics. BITSY can be accessed using a number of different programming languages (e.g., JavaScript) and be delivered as part of various software systems (e.g., Web browser). In this specification, we refer to the programming language used to access BITSY as the client language and the application techonology hosting the BITSY implementation as the client platform.

Various binding aspects would be different in different programming languages. For example, certain programming languages such as Java natively offer a Unicode String type. [ECMAScript] applications encode DOMString using UTF-16. Moreover, the client language determines the level of strong typing. So for example, Javascript uses weak typing whereas Java requires strong typing. These aspects are fully illuminated in the normative binding specifications given in the appendices of this specification.

1.3 Terminology

An application using BITSY is considered to be off-line when either there is no data network available to perform HTTP messaging or when the device or its owner decides that network access is not in the best interest of the device user.

A subscribable resource is one whose HTTP [RFC2616] URL is identified in a link element inside an Atom feed or entry [RFC4287], but cannot be modified using Atompub [RFC5023].

A synchronizable resource is one whose HTTP [RFC2616] URL can be used, as defined in Atompub [RFC5023], to manipulate its representation. By definition every synchronizable resource is also a subscribable resource. The off-line semantics of Atompub implied in this specification are described in Section 3.

Subscription is the process of making requests to a feed's subscription URL and to linked URLs to retrieve the complete representation of that feed and its subscribable resources.

Update propagation occurs when locally modified representation of every synchronizable resource is communicated in the background to the server that owns that resource and the server reconciles the remote changes with its own to produce a new representation of that resource.

Synchronization is the combination of background subscription and update propagation so that eventually the local representation of every subscribable and synchronizable resource is the same as the its network representation.

Eventual consistency means that even though the state of the clients and servers may not be consistent now, if there are sufficiently long periods of correct operation, all valid updates made as of now any place, will eventually be reflected everywhere in the same way. A corollary is that if there is also a lull in performing new updates, then the state will be identical in every client connected to the server.

Off-line data access and manipulation means to manipulate representations of a resource locally based on a previous network representation of that resource.

There is a case-insensitive match of strings s1 and s2 if after uppercasing both strings (by mapping a-z to A-Z) they are identical.

Two URIs are same-origin if after performing scheme-based normalization on both URIs as described in section 5.3.3 of RFC 3987 the scheme, host and port components are identical. If either URI does not not have an host component the URIs must not be considered same-origin. [RFC3987]

To locally update a resource means to perform an update when the application is disconnected from the network and then propagate the change to the server when the connection is available.

The backing collection of a feed is that identified by the href attribute of the app:collection element in the feed's metadata [RFC5023]

The union of all synchronizable resources of an application is its off-line update domain.

Private resources are those that require authorization.

1.4 Conformance

Everything in this specification is normative except for diagrams, examples, notes and sections marked non-normative.

The DOMString type is used in this specification to convey a double byte text string (section 1.1.5 of [DOMCore]).

The DOMStringList type is used in this specification to convey a collection of double byte text strings (section 1.1.5 of [DOMCore]).

The DOMTimeStamp type is used in this specification to convey a number of milliseconds (Appendix B of [DOMCore]).

Some sections of this specification are illustrated with fragments of a non-normative RELAX NG compact schema [RELAX-NG]. However, the text of this specification provides the definition of conformance. A complete schema appears in Appendix D.

The key words must, must not, should and may in this document are to be interpreted as described in RFC 2119. [RFC2119]

Conforming implementation

An implementation must behave as described in this specification in order to be considered conformant .

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

This specification relies on several underlying specifications.

HTTP

A conforming implementation must support some version of the HTTP protocol [RFC2616] and must intercept:

  • the HEAD and GET methods as defined in [RFC2616] on all subscribable resources
  • the HEAD, GET, PUT, and DELETE methods as defined in [RFC5023] on all subscribed entries
  • the POST method as defined in [RFC5023] on all subscribed collections
  • the OPTIONS method as defined in [RFC5023] on all subscribable resources when the BITSY implementation is off-line.
Atompub

A conforming implementation must support some version of the Atom publishing protocol and must support its member entry resources. Other requirements regarding Atompub are made throughout the specification. [RFC5023]

2 BITSY Interface

In order to function while off-line, an application can use the BITSY registration interface to identify and subscribe to feeds that provide synchronizable and subscribable application data and resources. Once an application registers a feed, the BITSY implementation is responsible for subscribing to that feed and making available the off-line representation of the feed's subscribable resources. As long as the subscription is active, the BITSY implementation updates the local representation of the subscribable resources to mirror its network representation.

Applications can access and manipulate the data of subscribed feeds as well as the synchronizable and subscribable resources linked from the subscribed feed, using HTTP methods and URLs.

A BITSY implementation can be bootstrapped into an application using one of two mechanisms - a list of existing subscriptions or a builder for creating a new subscription. The following IDL defines the interface provided by BITSY implementations for using these mechanisms.

IDL definition
module bitsy { 
  SubscriptionList subscriptions;
  DOMStringList supportedProxies;
  boolean supportsProxy(DOMString style);
  SubscriptionBuilder subscriptionBuilder();
};	
subscriptions of type SubscriptionList, readonly
The currently active subscriptions that are available to the present application to use.
supportedProxies of type DOMStringList, readonly
The styles of proxies supported by this BITSY implementation.
subscriptionBuilder(), method
Returns a new SubscriptionBuilder object.
supportsProxy(DOMString style), method
Returns true if the BITSY implementation supports the named proxy.
Parameters
style of type DOMString
The identifier of the proxy style that is being verified for support.

2.1 Subscription

Subscription interface is used to access subscribed feeds and track the errors of synchronizations of the feed. Using this interface, an application can investigate the source of HTTP errors and correct authentication errors. The BITSY implementation also provides updates on the subscription status of subscribed feeds to applications using the Event interface.

2.1.1 SubscriptionBuilder

Applications identify a feed for subscription, through its URL and subscribe to the feed using a Subscription object. To obtain a Subscription object, an application may use a SubscriptionBuilder object. A new SubscriptionBuilder can be obtained using the global subscriptionBuilder() method.

Once the Subscription object is created, the BITSY implementation should immediately start caching the subscribed feed, unless the implementation faces severe resource issues. The resources of a feed may not be available immediately. If network connectivity is available, an application must be allowed to transparently access resources directly from the server. While the data is being stored for off-line use, loss of network connectivity while completing subscription may lead to data access problems if they go off-line without caching data locally. Therefore, application users may be recommended to remain connected while the BITSY implementation makes resources available for off-line access.

In ECMAScript this can be used as follows:

var builder = bitsy.subscriptionBuilder();
builder.setFeed("http://example.com/feed/");
var subscription = builder.build();

If a feed source requires authorization, then the application can supply the necessary information using the setRequestHeader() method. The section on Authentication provides details of this approach.

In ECMAScript this can be used as follows:

var builder = bitsy.subscriptionBuilder();
builder.setFeed("http://example.com/authenticated-feed/");
builder.setRequestHeader("Authorization", "Scheme token=\"secret\""); // use a session authorization token
var subscription = builder.build();

If a feed source requires a cookie for authorization, then the application can also supply the required cookie using the setRequestHeader() method.

In ECMAScript this can be used as follows:

var builder = bitsy.subscriptionBuilder();
builder.setFeed("http://example.com/authenticated-feed/");
builder.addRequestHeader("Cookie", "PREF=ID=28face613556316e"
builder.addRequestHeader("Cookie", "S=DkEaab7_F7PtM3ZX"); // pass a Cookie for relaying HTTP State
var subscription = builder.build();

If a feed URL uses the relative URL syntax, then the relative URL is resolved using the base URL of the document that subscribed to the feed. If the document does not have a URL, then relative URL syntax is not allowed.

IDL definition
interface SubscriptionBuilder { 
  void setFeed(in DOMString url);
  void setRequestHeader(in DOMString name, in DOMString value);
  void addRequestHeader(in DOMString name, in DOMString value);
  void setInterval(in short interval);
  void addFollow(in DOMString relation);
  void setProxy(in DOMString url);
  Subscription build();
};	
addFollow(relation), method
Fetch linked resources of the subscribed feed if the link relation is the relation parameter. If an application fetches a feed's linked resources, BITSY implementations should not provide any subscribed entry until the linked resources are locally stored.
Parameters
relation of type DOMString
The relation that is to be followed.
addRequestHeader(name, value), method
Register an HTTP request header that must be used when making any request on a resource linked to the subscribed feed. This method can be called multiple times to set different required headers. The value specified in this call is appended to any existing value for this header. Any application requests for the resources stored locally for this subscription must include the resulting header.BITSY implementations must accept request headers defined in section 5.3 of HTTP 1.1 [RFC2616] as well as the Cookie header [RFC2109].
Parameters
name of type DOMString
The name of the header that is to be sent in the request for this feed's resources according to the field-name production of HTTP 1.1 [ RFC2616 ].
value of type DOMString
The value of the header that is to be sent in the request according to the field-value production of HTTP 1.1 [ RFC2616 ].
build(), method
Build the Subscription object based on the parameters provided in this builder object. The BITSY implementation may reuse an existing matching object if it exists. This allows existing off-line data to be used for meeting the needs of a new subscription.
Return Value
A Subscription for the required feed.
setFeed(url), method
Sets the url of the feed to be subscribed.
Parameters
url of type DOMString
The url of the feed that is to be subscribed.
setInterval(minutes), method
Sets the feed's subscription interval in minutes. The value of this attribute is the minimum period between two consecutive subscriptions of a feed. A client platform specific default value is used if an application does not specify this value.
Parameters
interval of type unsigned short
A feed's subscription interval.
setProxy(url), method
Sets up a proxy used for juxtaposing a request and response transformation between an application and BITSY.
Parameters
url of type DOMString
Configuration for the proxy used for transforming requests
setRequestHeader(name, value), method
Register an HTTP request header that must be used when making a request on any resource linked to the subscribed feed. This method can be called multiple times to set different required headers. Any previously set value for this header will be removed by this call. Any application requests for the resources stored locally for this subscription must include the header specified here. BITSY implementations must accept request headers defined in section 5.3 of HTTP 1.1 [RFC2616] as well as the Cookie header [RFC2109].
Parameters
name of type DOMString
The name of the header that is to be sent in the request for this feed's resources according to the field-name production of HTTP 1.1 [ RFC2616 ].
value of type DOMString
The value of the header that is to be sent in the request according to the field-value production of HTTP 1.1 [ RFC2616 ].

2.1.2 Subscription

Subscription interface is used to access properties of feed subscriptions and track the errors encountered during background synchronization of the feed and its linked resources. An application may temporarily pause and subsequently resume the subscription of feeds using this object. Using this interface, an application can also investigate the source of errors that occur during background synchronization. Optionally, background errors and subscription status changes can also be conveyed to interested applications using the EventListener callback interface. Applications can register such EventListener objects for each URL being updated and for the progress of the subscription itself. BITSY implementations send Event notifications for success and Error notifications for failures through this EventListener interface. Moreover, once an application clears any accumulated errors, applications must resume the subscription in order to continue fetch updates to the subscribed resources.

The following ECMAScript illustrates the use of a Subscription alter synchronization properties, clear any synchronization errors, and, resume subscription of that feed.

var subscription = ...
var errors = subscription.errors;
  for (var i = 0; i < errors.length; i++) {
    var error = errors[i];
    ... // process the error
    error.clear(); // then clear the error
  }
  subscription.resume();
... // access feed data
					
IDL definition
interface Subscription { 
  // properties
  readonly attribute DOMTimeStamp lastUpdated;
  readonly attribute unsigned short state;
  attribute unsigned short interval;
  readonly attribute DOMString feed;
	  	  
  readonly attribute DOMStringList follows;	
  DOMStringList getRequestHeaders();
  DOMString getRequestHeader(DOMString name);

  // subscription control
  void addFollow(DOMString relation);
  void pause();
  void removeFollow(DOMString relation);
  void resume();
  void unsubscribe();

  // client proxy emulation
  attribute DOMString proxy;
  
  // event handling
  attribute ErrorList errors;	
  void addStateChangeEventListener(EventListener listener);
  void addSyncEventListener(EventListener listener);
  void removeStateChangeEventListener(EventListener listener);
  void removeSyncEventListener(EventListener listener);
};	
errors, of type ErrorList, readonly
Gets the a list of errors that have accumulated during the synchronization of the feed and its linked resources.
interval of type unsigned short
Attribute describing the feed's subscription interval in minutes. The value of this attribute is the minimum period between two consecutive subscriptions of a feed. A client platform specific default value is used if an application does not specify this value.
feed of type DOMString, readonly
A read-only attribute to retrieve the feed's normalized, absolute subscription URL.
follows of type DOMStringList, readonly
A read-only attribute to identify the link relations followed in the subscription of this feed.
lastUpdated, of type DOMTimeStamp, readonly
A read-only attribute to determine the feed server time when subscription was last performed. This might be earlier than the time when the individual linked resources of the feed were fetched from the server. This timestamp does not provide any indication of whether the subscription was actually completed successfully.
proxy, of type DOMString
Location of the configuration file that sets up a proxy used for juxtaposing a request and response transformation between an application and BITSY.
state, of type unsigned short, readonly
Gets the current state of the subscription. The return values are numeric representations of subscription states as defined below:
addFollow(relation), method
Subscribe to linked resources identified in the entries of this feed. If an application subscibes to a feed's linked resources, BITSY implementations may not provide any subscribed entry until its resources are locally stored.
Parameters
relation of type DOMString
The name of the relation that is to be subscribed.
addStateChangeEventListener(listener), method

Register a listener that will be notified whenever the state of this subscription changes. The registration is valid only for the duration of the life of this object , e.g., once the application process is shut down, the listener is no longer notified. Multiple listeners may be registered for the same subscription. In that case, each of these listeners will receive the same event.

Parameters
listener of type EventListener
The listener that receives events and errors.
addSyncEventListener(listener), method

Register a listener that will be notified whenever failure events occur during background subscription processing of a feed or its linked resources and when success or failure events occur during update propagation. The registration is valid only for the duration of the life of this object , e.g., once the application process is shut down, the listener is no longer notified. Multiple listeners may be registered for the same subscription and same url. In that case, each of these listeners will receive the same event.

Parameters
listener of type EventListener
The listener that receives events and errors.
getRequestHeader(name), method
Get the value of a registered HTTP request header that would be used during a feed's synchronization.
Parameters
name of type DOMString
The name of the header.
Return Value
A DOMString of the requested HTTP header's value.
getRequestHeaders(), method
Get the values of all the registered HTTP request headers that would be used during a feed's subscription.
Return Value
A DOMStringList of the all the registered HTTP headers and their values.
pause(), method
Stop fetching updates from the subscribed feed of this object. The BITSY implementation may not immediately halt any ongoing subscriptions of the affected feed.
removeFollow(relation), method
Unsubscribe from linked resources identified in the entries of this feed. BITSY implementations may keep representations of linked resources in storage even after an application unsubscribes from relations that create the links.
Parameters
relation of type DOMString
The name of the relation that is to be unsubscribed.
removeStateChangeEventListener(listener), method
Deregister a listener for the state change events on this subscription. The deregistered listener will no longer receive events.
Parameters
listener of type EventListener
The listener that receives events and errors.
removeSyncEventListener(listener), method
Deregister a listener for the events about background synchronization activity on this subscription. The deregistered listener will no longer receive events after a call to this method.
Parameters
listener of type EventListener
The listener that receives events and errors.
resume(), method
Continue fetching updates from the subscribed feed of this object. The BITSY implementation should treat the affected subscription a candidate for immediate refresh.
unsubscribe(), method
Unsubscribe the feed and discontinue synchronizing the feed. Any pending updates will still be attempted to be processed and synchronized. Once the subscription is unsubscribed, BITSY implementations may remove the feed and its records from storage. An application can also re-subscribe to a feed after unsubscribing from that feed. As an application may resume accessing the feed using a new Subscription, BITSY implementations may not remove the unsubscribed feed's data from storage. Applications should warn the user from unsubscribing to feeds that still hold pending updates since any errors that occur when these updates are propagated might be invisible to the user.

2.1.3 Subscription State Transitions

atomsync cluster1 Active paused PAUSED end paused->end unsubscribe() ready READY paused->ready resume() ready->end unsubscribe() subscribed FETCHING ready->subscribed scheduled subscribed->paused 202/4xx/5xx invalid response subscribed->paused pause() waiting WAITING subscribed->waiting 2xx/503 waiting->ready interval backoff

State transitions of Subscription

BITSY implementations should track the state of subscriptions for the purpose of interval-driven refresh of the feed's server state. When an application obtains a Subscription, it can be in any of the following: states PAUSED, FETCHING, WAITING, or READY. This state undergoes transitions as BITSY performs various subscription related activities described below.

The FETCHING state indicates that BITSY is connected to the feed source to fetch updates to the feed. In this state, a subscription is actively consuming network resources. If network connectivity is lost before all subscription related work is completed, then the Subscription stays in this state and subscription is continued as soon as network connectivity is reestablished. As part of subscription processing, BITSY implementations must follow specified link relations that an application has registered using the addFollow() method while in this state.

If a client error such as 401 Unauthorized or 404 Not Found or an irrecoverable server error such as 500 Internal Server Error or a deferred server response 202 Accepted occurs during subscription, then BITSY must record the the original HTTP request and the failure response as an Error of the Subscription. The response should also be recorded as the current representation of the resource involved in this error. The affected Subscription moves to the PAUSED state. BITSY implementations must also treat invalid responses from the server, such as lack of well-formedness of the Atom feed or entry documents as irrecoverable server errors. New requests to fetch updates for the affected Subscription should not be made when it is in this state.

If, on the other hand, a recoverable server error such as 503 Service Unavailable occurs when a BITSY implementation tries to fetch a new representation of the feed or its linked resources, then the subscription's readyState changes to WAITING. BITSY implementations must keep track of such resources and retry the request later using use the Retry-After header. If this header is unavailable, then the BITSY implementation should treat the response as a 500 Internal Server Error.

When a BITSY implementation successfully completes fetching the feed, its entries and other linked resources as described in Section 2.1.4, the Subscription moves to the WAITING state. Applications are usually interested in updating their interface when data changes occur and are alerted with an event when FETCHING state is exited. Applications can check the errors of the Subscription to see if any server errors were encountered during the subscription. Until the subscription interval completes, this feed shall not be further subscribed and will remain in the WAITING state.

The READY state indicates that subscription is about to begin as soon as network resources are available. Even though the network is available, BITSY implementations may reasonably delay network resource usage to optimally consume other resources such as device power and CPU time.

A subscription may enter the PAUSED state either due to an error or a voluntary action by the application to pause a subscription. In order for the application to continue receiving updates to subscribed resources, the application must resume the subscription at which point the subscription enters the READY state.

The terminal CLOSED state of a Subscription indicates that the feed in question will not be synchronized any further. In order to continue using the feed, an application must create a new Subscription object.

BITSY implementations must continue with pending update propagation requests during all of its states. Errors during update propagation are recorded in the same way as described earlier, but such errors do not change the state of the associated Subscription.

2.1.5 SubscriptionList

Applications can either create new subscriptions or use an existing one created earlier (either by the same application or another related application). BITSY provides a mechanism for applications to discover existing subscriptions available to them. An object of this interface must be provided to applications as a global object attribute subscriptions. A SubscriptionList is an immutable object, i.e., it does not change once it has been accessed. However, the global object used to obtain a SubscriptionList can change from time to time. Two successive retrievals of this global object may not produce identical results. Only Subscriptions that are not CLOSED SHOULD be included in a SubscriptionList. The Subscriptions in this list may be constrained by confidentiality practices described in Section 4.4.

The following example depicts using ECMAScript how an application can access a list of existing subscriptions:

var subscriptions = bitsy.subscriptions;
for (var i = 0; i < subscriptions.length; i++)
  alert(subscriptions[i].feed);
The SubscriptionList interface provides the abstraction of a collection of Subscriptions. The items in the SubscriptionList are accessible via an integral index, starting from 0.
IDL Definition
interface SubscriptionList { 
  // properties
  readonly attribute unsigned long length;
		
  // methods
  Subscription item(unsigned long index);
};
length of type unsigned long, readonly
The number of subscriptions in the list. The range of valid subscription indices is 0 to length-1 inclusive.
item(index), method
Returns the indexth Subscription in the collection. If index is greater than or equal to the number of subscriptions in the list, this returns null.

2.2 Events

Events represent one of three distinct phenomena that occur during background synchronization:

  1. change in the state of a subscription
  2. a failure during subscription processing
  3. completion of update propagation

Using this event dispatching style, applications can stay up-to-date the results of synchronization. Any number of listeners may be registered for an event type since there might be multiple applications working with a single Subscription object. BITSY implementations do not dispatch events to listeners if the application that registered the listeners is not running at the time an event occurs.

In this ECMAScript example, we illustrate the state change events and processing errors generated during subscription processing.


const feed = "http://www.example.com/feed";
const WAITING = 2;
const HTTP_SERVER_ERROR = 500;
const HTTP_BAD_REQUEST = 400;

function subscription(event) {
  if (event.status == WAITING)
    console.log("Completed subscription to " + event.location);
  else (event.status == PAUSED)
    console.log("Error subscribing to " + event.location);
}

function resource(event) {
  if (event.status >= HTTP_BAD_REQUEST && event.status < HTTP_SERVER_ERROR) 
    console.log("Error when fetching " + event.location + " with code " + event.status);
  if (event.status >= HTTP_SERVER_ERROR) 
    console.log("Server error when fetching " + event.location + " with code " + event.status);
}

var builder = bitsy.subscriptionBuilder();
builder.setFeed(feed);
var sub = builder.build();
sub.addStateChangeEventListener(subscription);
sub.addSyncEventListener(resource);

If the feed document is successfully retrieved and the links within this feed are successfully fetched, then the console would read like the following:

Completed subscription to http://www.example.com/feed

If the feed document is successfully retrieved but a link in this feed fails to load due to an invalid URL, then the console would read like the following:

Error when fetching http://www.example.com/feed/invalid with code 404
Error subscribing to http://www.example.com/feed

If the feed document is successfully retrieved but a link in this feed fails to load due to a server error, then the console would read like the following:

Server error when fetching http://www.example.com/feed/invalid with code 503
Completed subscription to http://www.example.com/feed

Events generated at the completion of background update propagation are relayed in the same way as subscription state change and processing failure events.

In this ECMAScript example, we illustrate the way update propagation events are generated.


const feed = "http://www.example.com/feed";
const entry = "http://www.example.com/feed/entry";
const HTTP_OK = 200;
const HTTP_BAD_REQUEST = 400;

function resource(event) {
  if (event.status == HTTP_OK)
    console.log("Updated entry at " + event.location + " with headers: " + event.headers);
  else if (event.status >= HTTP_BAD_REQUEST) 
    console.log("Error when updating " + event.location + " code " + event.status);
}

var builder = bitsy.subscriptionBuilder();
builder.setFeed(feed);
var sub = builder.build();
sub.addSyncEventListener(resource);
...
var req = new XmlHttpRequest();
req.open("PUT", entry, false);
req.send(...);

If the request was initially processed offline and later propagated to the server, and if the server accepts the changes, then the console would read like the following:

Updated entry at http://www.example.com/feed/entry with headers: Content-Type: application/atom+xml
Content-Length: 1283

If the request was initially processed offline and later propagated to the server, and if the server rejects the changes, then the console would read like the following:

Error when updating http://www.example.com/feed with code 409

2.2.1 Event

An Event is a notification from BITSY to applications.
IDL Definition
interface Event { 
 // properties
  readonly attribute unsigned integer status;
  readonly attribute DOMTimeStamp timeStamp;
};	
status of type unsigned short, readonly
If this Event is a notification for the completion of an off-line request to this object's location, then the status attribute is the status code of the HTTP response. If this Event signifies the change of the state of a Subscription for this Event's location, then the status attribute is the new state of the Subscription.
timeStamp of type DOMTimeStamp, readonly
A read-only attribute containing the timestamp of when the was event was generated.

EventListener is an interface for notifying an Event to applications for processing the event. Any number of Event objects may be dispatched in parallel to an EventListener.

IDL Definition
interface EventListener {
    void  handleEvent(Event evt);
};		
handleEvent(evt), method
This method is called whenever an event occurs for which the EventListener interface was registered .
Parameters
evt of type Event
The Event contains contextual information about this event.
This specification encourages the EventListener type to be bound directly to a function reference if the implementation language allows that. If a direct function reference is used as an EventListener, the the handle method is not required and the referenced function is directly invoked with the Event as the argument.

In this ECMAScript example, we can bind EventListener to a function reference.

function subscription(event) {
...
}

function resource(event) {
...
}

var builder = bitsy.subscriptionBuilder();
...
var sub = builder.build();
sub.addStateChangeEventListener(subscription);
sub.addSyncEventListener(resource);

2.2.2 Event subtypes

A StateChangeEvent indicates the change of a subscription's state. Applications receive StateChangeEvent notifications by registering to a Subscription using addStateChangeEventListener.
IDL Definition
interface StateChangeEvent : Event { 
 // properties
  readonly attribute Subscription subscription;
};	
subscription of type Subscription, readonly
A read-only attribute containing the subscription that is the subject of this event.

An SyncEvent is the result of offline processing, either a failure during subscription or for completion of update propagation. Each such object represents a completed server interaction and includes the original request and the server error response. Note that a network failure cannot be considered as an SyncEvent. An application can use SyncEvent notifications to communicate changes to the user or to take corrective steps. Applications receive SyncEvent notifications by registering to a Subscription using addSyncEventListener.

IDL Definition
interface SyncEvent : Event { 
  // properties
  readonly attribute DOMString location;
  readonly attribute DOMString method;
  readonly attribute DOMString requestText;
  readonly attribute DOMString requestHeaders;
  readonly attribute DOMString responseText;
  readonly attribute DOMString responseHeaders;
};		
location of type DOMString, readonly
A read-only attribute containing the URL where the request was made that produced this event.
method of type DOMString, readonly
A read-only attribute containing the HTTP request method that produced this event.
requestHeaders of type DOMString, readonly
Provides the headers from the request to this object's location.
requestText of type DOMString, readonly
Provides the entity body from the request to this object's location.
responseHeaders of type DOMString, readonly
Provides the headers from the error HTTP response to a request to this object's location.
responseText of type DOMString, readonly
Provides the entity body from the error HTTP response to a request to this object's location.

Each indexed object in the errors attribute represents an error during a server interaction. An Error indicates a problem that BITSY cannot automatically recover by itself. When an application calls clear() on an Error obejct, that error is not included in future values of the errors attribute of the affected Subscription. If a Subscription is in the PAUSED state, then an application should process each of the errors of that Subscription by clear()ing them, and then call resume() on that Subscription in order to continue getting updates from the server. BITSY implementations may remove old Errors from a resource when an application creates new update requests for that resource.

IDL Definition
interface Error : SyncEvent { 
  // status
  void clear();
};		
clear(), method
Clear this error from the Subscription where it occurred. This Error object will not be included in the errors list anymore.

2.2.3 ErrorList

The ErrorList interface provides the abstraction of an sequence of Errors, without defining or constraining how this collection is implemented. The items in the ErrorList are accessible via an integral index, starting from 0.
IDL Definition
interface ErrorList { 
// properties
readonly attribute unsigned long length;
	
// methods
Error item(unsigned long index);
};				
length of type unsigned long, readonly
The number of errors in the list. The range of valid error indices is 0 to length-1 inclusive.
item(index), method
Returns the indexth Error in the collection. If index is greater than or equal to the number of errors in the list, this returns null.

2.3 Client Proxy Emulation

An important class of applications cannot make requests directly to the Atompub server that holds the data being manipulated. This class of applications includes client-side mashups that combine data from a different server than the one that serves up the mashup application. Such applications may make a request to an Atompub proxy, which in turn forwards the requests to the Atompub server, translating both the request and response in the process. The Atompub proxy mimics the Atompub protocol semantics, such as adding entries, even though the exact message exchange is not as per Atompub specifications. In any case, the proxy server is unavailable when the application is off-line. The emulation of such proxy behavior within BITSY is called client proxy emulation aka CPE. CPE enables applications dependent on Atompub proxies to function when they are off-line. BITSY implementations may implement the CPE functionality.

CPE does not change the URL to which applications make their requests nor does it alter the structure of data sent or received by the application. In any case, a BITSY implementation interacts directly with the Atompub server as opposed to the proxy. In order to use a CPE, an application must provide the URL of the proxy configuration document using the proxy attribute of the proxied Subscription.

This specification describes the BITSY proxy configuration document whose root is the bitsy:proxy element.

namespace bitsy = "http://www.purl.org/BITSY"
start = bitsy:proxy

The BITSY proxy configuration document is specified in terms of the XML Information Set, serialized as XML 1.0 [XML] and identified with the application/x-bitsy-proxy-config+xml media type. BITSY proxy configuration documents must be well-formed XML. This specification does not define a DTD for BITSY proxy configuration documents, and hence does not require them to be valid (in the sense used by XML).

The bitsy:proxy element is the document element of a BITSY proxy configuration document, acting as a container for metadata associated with the proxying needs of an application. Its element children consist of metadata followed by one or more bitsy:namespace elements.

bitsyProxy = 
  element bitsy:proxy {
    extensionElement*,
    bitsyNamespace+
  }

This specification assigns no significance to the order of the bitsy:namespace elements with the proxy configuration. It is an error to have multiple bitsy:namespace elements with the same or overlapping urlPrefix values in a BITSY proxy configuration document.

Each bitsy:namespace element identifies the proxy behavior of the resources that are managed by a proxy server. The bitsy:namespace element is open for extension and the contents are specific to the kind of proxying behavior required. The contents of the bitsy:namespace element identify the proxy styles supported and provide any required configuration for the chosen proxy style. Any element or attribute from any namespace can be created in the bitsy:namespace element.
bitsyNamespace = 
  element bitsy:namespace {
    attribute urlPrefix { bitsyUri },
    extensionElement+
  }

# Any IRI can be a bitsyUri
bitsyUri = text

Under the following proxy configuration, an application is saying that all requests containing the URL prefix http://www.google.com/calendar/private/full are to be handled through CPE:

<proxy xmlns="http://purl.org/BITSY">
  <namespace urlPrefix="http://www.google.com/calendar/private/full" >
  ...
  </namespace>
</proxy>

BITSY implementations must provide a global DOMStringListobject that lists the styles of proxies it supports. Applications can introspect the supported proxies using the global supportedProxies attribute. The proxy style is a fully qualified XML name, i.e., a namespaced name where the namespace is enclosed inside { and } characters.

The following ECMAScript code illustrates how an application can verify whether a particular proxy style is supported in the BITSY implementation:

var styles = bitsy.supportedProxies;
var xdp = "{http://purl.org/BITSY/xdp}xd";
if (bitsy.supportsProxy(xdp)) {
  // proxy is supported - we can work offline
  var builder = bitsy.subscriptionBuilder();
  ...
  builder.setProxy(...);
  var sub = builder.build();
} else {
  alert("Cannot work off-line due to missing CPE support for " + xdp);
}

The following ECMAScript code illustrates how an application can introspect the implementation to determine all the proxy styles supported in the BITSY implementation:

var styles = bitsy.supportedProxies;
var xdp = "{http://purl.org/BITSY/xdp}xd";
var xdpSupported = false;
for (var i = 0; i < styles.length; i++) 
  if (styles[i] == xdp) {
    xdpSupported = true
    break;
  }
if (xdpSupported) {
  // proxy is supported - we can work offline
  var builder = bitsy.subscriptionBuilder();
  ...
  builder.setProxy(...);
  var sub = builder.build();
} else {
  alert("Cannot work off-line due to missing CPE support for " + xdp);
}

If a BITSY implementation supports a particular proxy style, then it must intercept requests whose URL prefix is identified in the proxy configuration.

For example, under the following proxy configuration, an application is using the {http://purl.org/BITSY/xdp}xd CPE style:

<proxy xmlns="http://purl.org/BITSY">
  <namespace urlPrefix="http://www.google.com/calendar/private/full" >
    <xd xmlns="http://purl.org/BITSY/xdp" />
  </namespace>
</proxy>

CPE works by intercepting the requests even before the regular non-CPE interception occurs. This allows CPE to provide the additional Atompub proxying behavior that is performed on the proxy server. BITSY implementations may support any number of proxy styles each of which requires that the BITSY implementation understand the corresponding contents of the namespace elements.

3 Off-line HTTP Methods

BITSY implementations intercept HTTP requests to off-line resources and respond using locally stored data. The BITSY specification requires Atom Publishing Protocol [RFC5023] semantics for the off-line client emulation of server behavior specifically in the context of Atompub managed resources. By doing this, BITSY offers higher availability for such resources at the cost of short-term inconsistency. Any behavior not specified here is not required for interoperation. Specific overrides of HTTP caching behavior are as follows:

  1. BITSY overrides the mandatory write-through requirement of HTTP (section 13.11 of [RFC2616]).
  2. BITSY implementations ignore the following cache response directives (section 14.9 [RFC2616]):
    • no-cache
    • no-store
    • must-revalidate
    • proxy-revalidate
    • max-age
    • s-maxage
  3. BITSY implementations ignore the following cache request directives (section 14.9 [RFC2616]):
    • max-age
    • max-stale
    • min-fresh
    • no-cache
    • no-store
  4. When intercepting requests, BITSY implementations should add a Warning header with the 112 Disconnected operation value to alert the application about likely inconsistency with the origin server on the response entity.

BITSY implementations may not negotiate content using headers different from those that are specified during the subscription setup. For example, if the subscription is set up using the header Accept-Language: en-US;q=0.8 and the GET request contains a header Accept-Language: da, then the request cannot be satisfied and the BITSY implementation may produce a 406 Not Acceptable.

3.1 GET

When an application requests the representation of a subscribable resource by making a GET or HEAD request, BITSY implementations should respond in the following manner:
  1. If the resource has been locally updated, use the latest updated representation of that resource.
  2. Otherwise, use a previously stored representation of that resource's URL.

3.1.1 Feed

BITSY implementations should derive the latest updated representation of a feed in the following manner:

  1. If a subscribed feed uses a backing collection, then an application may add entries to it and modify the feed. Therefore, any new entries created in the backing collection by an HTTP POST operation should be added to the latest updated representation of the subscribed feed in the following manner:
    • The new entry representation must match the modified XML representation provided by the application in the POST request.
    • Its character encoding must match the encoding used in the feed document.
    • The new entry must precede any existing entries in the feed document.
  2. The response entity body should suppress any entry in the feed that is deleted through an HTTP DELETE operation on the entry's edit link URL as defined in [RFC5023].
  3. The response entity body should include the updated representation of any entry in the feed that is updated through an HTTP PUT operation on the entry's edit link URL as defined in [RFC5023]. The updated representation must match the entity body provided by the application in the latest PUT request, except that its character encoding must match the encoding used in the feed document.

3.1.2 Entry

BITSY implementations should derive the latest updated representation of an entry in the following manner:
  1. If an entry is deleted through an HTTP DELETE operation on the entry's edit link URL as defined in [RFC5023], then the updated representation should be 410 Deleted with an empty entity.
  2. If an entry is updated through an HTTP PUT operation on the entry's edit link URL as defined in [RFC5023], then the updated representation should use the entity provided by the application in the latest PUT request to that URL.

3.1.3 Resource

BITSY implementations should derive the latest updated representation of a media resource in the following manner:
  1. If the media link entry for the resource is deleted through an HTTP DELETE operation on the entry's edit link URL as defined in [RFC5023], then the updated representation should be 410 Deleted with an empty entity.
  2. If the resource is deleted through an HTTP DELETE operation on its URL, then the updated representation should be 410 Deleted with an empty entity.
  3. If the resource is updated through an HTTP PUT operation on its URL, then the updated representation should use the entity provided by the application in the latest PUT request to that URL.
  4. If the resource is not managed through any media link entry, then the original subscribed resource representation must be used.

3.2 POST

Applications may make POST requests to the URL of the backing collection of a subscribed feed. Off-line response to such requests should include the entity provided in the request and may not include Location or Content-Location headers. POST requests must not be rejected for any reason other than authentication errors as described in Section 4.3.

3.3 PUT

Applications may make PUT requests to an entry's edit link URL or to an entry's edit-media link URL as defined in [RFC5023]. Off-line response to such requests should include the entity provided in the request. Sufficiently authorized PUT requests must not be rejected for any reason, except if the entry or resource is previously deleted.

3.4 DELETE

Applications may make DELETE requests to an entry's edit link URL or to an entry's edit-media link URL as defined in [RFC5023]. Off-line response to such requests should produce the HTTP response 204 No Content. Sufficiently authorized DELETE requests must not be rejected for any reason.

3.5 Update Propagation Results

When an application makes PUT, DELETE, and POST requests to synchronizable resources, BITSY implementations provide off-line responses. The updates are propagated to the server as the original requests are replayed at a time when network connectivity is available. As each request is propagated to the server, the response from the server is used to change local representations of the affected resources in the following manner:
  1. If the request URL identifies an entry or media resource, and the response is 200 OK, then:
    1. Record the response entity as the representation for the requested URL
    2. Mark the request as completed successfully.
  2. If the request URL identifies a collection and the response is 201 Created, then:
    1. If the response includes a Content-Location header, replace the entry's representation with the entity body received in the response and assign it to the Content-Location URL
    2. If the response includes a Location header, record the response entity as the representation for the Location URL
    3. Mark the request as completed successfully.
  3. If the response is 302 Found or 303 See Other or 307 Temporary Redirect, then:
    1. Make a new request to the URL in the Location header and follow this entire procedure from the beginning.
    2. Mark the request as completed successfully.
  4. If the response is 4xx or 5xx, then
    1. Store the response for the request.
    2. Revert the representation of the affected resource to its previous online state.
    3. Mark the request as completed in error
  5. BITSY's behavior is undefined if the response is not defined above or the requested URL does not fall in to one of the above categories.
  6. Fire events as described in Section 2.3 based on the request status.

4 Security Mechanisms

Applications delegate server interaction to BITSY, which effectively stores data on behalf of those applications. BITSY also makes requests to a server on behalf of the application. However, BITSY does not create a new mechanisms for users to access data and does not require any new allowances from the server. Therefore, BITSY does not introduce any new security threats. A description of the HTTP security mechanisms as applicable to BITSY enabled applications as a combination of access authentication and transport security is provided here.

4.1 Encryption

Applications communicate with servers using either clear text or encrypted messages. HTTP communication is in clear text. TLS [RFC4346] can be used for industry-grade encryption of HTTP interaction. This would require that any resources requiring encryption be identified in the https scheme. An alternative is to access the application over a virtual private network (VPN) such using IPSec [RFC2401].

4.2 Integrity

Digital signatures provide message integrity, non-repudiation, and proof of origin. Atom documents can be signed and encrypted for message integrity [RFC4287].

4.3 Authentication

Most applications need to verify the identity of their users before allowing access to private resources they manage. Typically a server verifies the identity of its users by checking whether the user possesses valid credentials including a shared secret, e.g., a password. Applications design their own user interface to provide a means for users to supply their credentials for authentication. In Web applications, this is typically performed using HTML forms and it provides applications with a great deal of control over the authentication user interface. Also, applications typically do not verify the user's credentials for every request. Instead, applications verify a token stored on the client as a result of authentication. This token is a session identifier stored in either an HTTP session cookie [RFC2109] or URL query parameters. This approach is highly scalable since just the session identifier and not credentials are validated for every HTTP request. Use of session identifiers gives the data source wide latitude over terminating the authorization and restricting access to certain scopes. It also allows users to share authorization but not their credentials with a variety of less-trustworthy applications.

The token approach also enables off-line authentication without storing any credentials locally. The same token used by BITSY to authenticate requests to a server is also used by an application to authenticate to BITSY. As part of the set up, the application typically requires a user to performs on-line authentication to obtain an authorization token. The application then supplies this token to BITSY in the form of authorization headers passed through the setRequestHeader() method while setting up the subscription. If an application needs to access private resources, then it must pass the same authorization headers as supplied in the subscription set up.

This specification considers application provided Cookie and Authorization headers as authorization headers. The authorization token may be locally stored as a session cookie [RFC2109]. Subsequently, an application may either use the cookie directly or in the form of an Authorization header when requesting data. The data access may take the form of a programmatic request such as XMLHttpRequest [XMLHttpRequest] or a simple user agent retrieval of a linked resource, through, say, an <img> tag. Note that this specification does not require support for dynamically changing authorization headers such as those that involve nonces.

Whenever an application accesses private resources, BITSY must perform off-line authentication. That implies comparison of the authorization headers in the request with those provided by the application during the subscription setup to setRequestHeader(). The comparison must proceed in the following manner:

Failing this, BITSY must produce a 401 Unauthorized response as described below. Also, if during the subscription process the server deems a request's authorization headers invalid and produces a 401 Unauthorized response, then BITSY implementations must respond to any future application requests to that resource using those invalid authorization headers in the following manner:

  1. 401 Unauthorized status
  2. WWW-Authenticate challenge header
  3. A text entity explaining why the unauthenticated request is not acceptable.

If the error is a result of server error, then the parts 2 and 3 above must be the values returned from the server. If the error is a result of off-line authentication failire, then part 2 must include the authentication scheme if that is not successfully matched.

Applications may perform an on-line "log out" thereby instructing the data source to treat the existing authorization headers as invalid. Alternately, if the server revokes validity of these authorization headers, it effectively revokes access to resources obtained using those authorization headers.

4.4 Confidentiality

BITSY does not allow any sharing of data contrary to what is allowed by its source. Therefore, the server has complete control over the applications to which data is provided. If a server treats data as public and does not require any authorization, then BITSY lets any interested application share this data as well as changes to it. On the other hand, if data is accessed using either cookie or HTTP authorization as described above, then only an application that has access to the same cookies and authorization headers is allowed to see that data. Thus two different applications interested in the same resource, but using different authorization headers do not see each other's data or changes made by those applications. In this way, BITSY guarantees that information is accessible only to the applications and users authorized to have access.

BITSY also provides an enumeration of existing subscriptions to applications. A BITSY implementation must limit these subscriptions to only those whose servers would trust the application, either based on application and data domain or based on explicit authentication. For an example of domain based trust, a subscription on data provided by domain X would not be visible to an application served by domain Y, unless Y is a container of domain X. If the application does not have any domain, i.e., is locally installed or deemed trustworthy of accessing every domain, then a BITSY implementation should provide enumerate all active and paused subscriptions to that application.


Appendix A: References

A.1 Normative References

[DOMCore]
Document Object Model (DOM) Level 2 Core Specification, A. Hors, et al. W3C, November 2000.
[RFC2109]
HTTP State Management Mechanism, D. Kristol and L. Montulli. IETF, February 1997.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997.
[RFC2401]
Security Architecture for the Internet Protocol (IPsec overview), S. Kent and P. Atkinson. IETF, November 1998.
[RFC2616]
Hypertext transfer protocol -- HTTP 1.1, R. Fielding et al. IETF RFC 2616, June 1999.
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax, T. Berners-Lee, R. Fielding, L. Masinter, editors. IETF, January 2005.
[RFC3987]
Internationalized Resource Identifiers (IRIs), M. Duerst, M. Suignard, editors. IETF, January 2005.
[RFC4287]
The Atom Syndication Format, M. Nottingham and R. Sayre. IETF, December 2005.
[RFC4346]
The Transport Layer Security (TLS) Protocol, Version 1.1, T. Dierks and E. Rescorla. IETF, April 2006.
[RFC5023]
The Atom Publishing Protocol, J. Gregorio and B. de hOra. IETF, October 2007.
[XML]
Extensible Markup Language (XML) 1.0 (Third Edition), F. Yergeau, J. Paoli, C. Sperberg-McQueen, T. Bray, and E. Maler. W3C, February 2004.

A.2 Other References

[ECMAScript]
ECMAScript Language Specification (Third Edition) , ECMA, December 1999.
[GData]
Google Data APIs, Google
[OMGIDL]
OMG (Object Management Group) IDL (Interface Definition Language) defined in The Common Object Request Broker: Architecture and Specification, version 2.3.1, OMG, October 1999.
[OMTP]
OMTP Recommendations for Connected Applications, OMTP, October 2007.
[RELAX-NG]
RELAX NG Compact Syntax, J. Clark. December 2001.
[RFC4685]
Atom Threading Extensions, J. Snell. IETF, September 2006.
[WEBARCH]
Architecture of the World Wide Web, Volume One , I. Jacobs and N. Walsh, editors. W3C, December 2004.
[XMLHttpRequest]
The XMLHttpRequest Object, A. van Kesteren. W3C Working Draft, October 2007.

Appendix B: IDL Definitions

This appendix contains the complete OMG IDL [OMGIDL] for the BITSY definitions.
// File: bitsy.idl

#ifndef _BITSY_IDL_
#define _BITSY_IDL_

#include dom.dll
module bitsy {
  interface Event { 
    // properties
    readonly attribute unsigned integer status;
    readonly attribute DOMTimeStamp      timeStamp;
  };  
  
  interface StateChangeEvent : Event { 
    // properties
    readonly attribute Subscription      subscription;
  };  
  
  interface SyncEvent : Event { 
    // properties
    readonly attribute DOMString         location;
    readonly attribute DOMString         method;
    readonly attribute DOMString         requestText;
    readonly attribute DOMString         requestHeaders;
    readonly attribute DOMString         responseText;
    readonly attribute DOMString         responseHeaders;
  };
  
  interface Error : SyncEvent {		
    // status
    void               clear();
  };

  interface EventListener {
    void              handleEvent(in Event evt);
  };
  
  interface ErrorList { 
    // length
   readonly attribute unsigned long      length;
	
   // accessor
   Error              item(in unsigned long index);
  };
    
  interface Subscription { 
    // properties
             attribute unsigned short    interval;
    readonly attribute DOMString         feed;
    readonly attribute DOMTimeStamp      lastUpdated;
    readonly attribute unsigned short    state;
	  	  
    // subscription 
    void               pause();
    void               resume();
    void               unsubscribe();

    DOMStringList      getRequestHeaders();
    DOMString          getRequestHeader(in DOMString name);
    readonly attribute DOMStringList     follows;
    void               addFollow(in DOMString relation);
    void               removeFollow(in DOMString relation);
    // client proxy emulation
             attribute DOMString         proxy;
  
    // event handling
             attribute ErrorList errors;	
    void               addStateChangeEventListener(in EventListener listener);
    void               addSyncEventListener(in EventListener listener);
    void               removeStateChangeEventListener(in EventListener listener);
    void               removeSyncEventListener(in EventListener listener);  
  };
  
  interface SubscriptionBuilder { 
    // mutators 
    SubscriptionBuilder setFeed(in DOMString url);
    SubscriptionBuilder setRequestHeader(in DOMString name, 
                                              in DOMString value);
    SubscriptionBuilder setInterval(in short interval);
    SubscriptionBuilder addFollow(in DOMString relation);
    Subscription        build();
  };	  

  interface SubscriptionList { 
    // length
    readonly attribute unsigned long     length;
		
    // accessor
    Subscription        item(in unsigned long index);
  };	  
  
  // properties
  readonly attribute SubscriptionList subscriptions;
  readonly attribute DOMStringList supportedProxies;
	
  // methods
  SubscriptionBuilder subscriptionBuilder();
  DOMString          supportsProxy(in DOMString style);
};
#endif // _BITSY_IDL_

Appendix C: ECMAScript Language Binding

This appendix contains the complete ECMAScript [ECMAScript] binding for the BITSY definitions.

Object bitsy

The bitsy object has the properties and methods defined below:

The bitsy object has the following properties:

subscriptions

This read-only property is of type SubscriptionList.

supportedProxies

This read-only property is of type DOMStringList.

The bitsy object has the following method:

subscriptionBuilder()

This method returns a SubscriptionBuilder object.

supportsProxy(style)

This method returns a boolean object.

The style parameter is of type String.

Object Event

The Event object has the following properties:

status

This read-only property is of type Number.

timeStamp

This read-only property is of type DOMTimeStamp.

Object StateChangeEvent

The StateChangeEvent object has all the properties of the Event object as well as the following properties:

subscription

This read-only property is of type Subscription.

Object SyncEvent

The SyncEvent object has all the properties of the Event object as well as the properties defined below:

location

This read-only property is of type String.

method

This read-only property is of type String.

requestHeaders

This read-only property is of type String.

requestText

This read-only property is of type String.

responseHeaders

This read-only property is of type String.

responseText

This read-only property is of type String.

Object Error

The Error object has all the properties of the SyncEvent object as well as the methods defined below:

clear()

This method does not return a value.

Object EventListener

This is an ECMAScript function reference. This method has no return value. The parameter is a Event object.

Object ErrorList

The ErrorList object has the following properties:

length

This read-only property is of type Number.

The ErrorList object has the following methods:

item(index)

This method returns a Error object.

The index parameter is of type Number.

Note: This object can also be dereferenced using square bracket notation (e.g. obj[1]). Dereferencing with an integer index is equivalent to invoking the item method with that index.

Object Subscription

The Subscription object has the following properties:

errors

This read-only property is of type ErrorList.

feed

This read-only property is of type String.

follows

This read-only property is of type DOMStringList.

interval

This property is of type Number.

lastUpdated

This read-only property is of type DOMTimeStamp.

proxy

This property is of type String.

state

This property is of type Number.

The Subscription object has the following methods:

addStateChangeEventListener(listener)

This method does not return a value.

The listener parameter is of type EventListener.

addSyncEventListener(listener)

This method does not return a value.

The listener parameter is of type EventListener.

addFollow(relation)

This method does not return a value.

The relation parameter is of type String.

getRequestHeader(name)

This method returns a String.

The name parameter is of type String.

getRequestHeaders()

This method returns a DOMStringList object.

removeFollow(relation)

This method does not return a value.

The relation parameter is of type String.

removeStateChangeEventListener(listener)

This method does not return a value.

The listener parameter is of type EventListener.

removeSyncEventListener(listener)

This method does not return a value.

The listener parameter is of type EventListener.

unsubscribe()

This method does not return a value.

Object SubscriptionBuilder

The Subscription object has the following methods:

build()

This method returns a Subscription object.

addFollow(relation)

This method returns a SubscriptionBuilder object.

The relation parameter is of type String.

setFeed()

This method returns a SubscriptionBuilder object.

The url parameter is of type String.

setInterval(minutes)

This method returns a SubscriptionBuilder object.

The minutes parameter is of type Number.

setRequestHeader()

This method returns a SubscriptionBuilder object.

The name parameter is of type String.

The value parameter is of type String.

Object SubscriptionList

The SubscriptionList object has the following properties:

length

This read-only property is of type Number.

The SubscriptionList object has the following methods:

item(index)

This method returns a Subscription object.

The index parameter is of type Number.

Note: This object can also be dereferenced using square bracket notation (e.g. obj[1]). Dereferencing with an integer index is equivalent to invoking the item method with that index.

Appendix D: Relax NG Compact Schema for Client Proxy Emulation Configuration

This appendix is informative. At present the BITSY proxy configuration defines only one concrete element and attribute leaving the rest to future versions of the specification.
namespace bitsy = "http://www.purl.org/BITSY"
			
start = bitsyProxy

# bitsy:proxy
bitsyProxy = 
  element bitsy:proxy {
    extensionElement*,
    bitsyNamespace+
  }

# bitsy:namespace  
bitsyNamespace = 
  element bitsy:namespace {
    attribute urlPrefix { bitsyUri },
    extensionElement+
  }
  
# Any IRI can be a bitsyUri
bitsyUri = text

# Simple Extension
simpleExtensionElement = 
  element * - bitsy:* {
    text
  }
  
# Structured Extension  
structuredExtensionElement = 
  element * - bitsy:* {
    (attribute * { text }+,
       (text|anyElement)*)
    | (attribute * { text }*,
       (text?, anyElement+, (text|anyElement)*))
  }
  
# Extension
extensionElement = simpleExtensionElement | structuredExtensionElement
  
anyElement = 
  element * {
    (attribute * { text }
     | text
     | anyElement)* 
  }