Network Working Group D. Turner
Internet-Draft J. Conlin
Intended status: Standards Track N. Marathe
Expires: November 15, 2014 Mozilla
May 14, 2014

WebPush Protocol
draft-turner-push-proto-latest

Abstract

This page describes the protocol used for communication by the WebPushServer and the UserAgent.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on November 15, 2014.

Copyright Notice

Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.


Table of Contents

1. Introduction

WebPush is a simple notification and small data delievery system designed to be easy to implement, scalable, and robust. The WebPush protocol enables application servers to delivery guarantees, minimal server state, and client driven recovery. It is a signaling and data carrying system.

[todo] integrate auth

2. Definitions

AppServer : The third-party server or application which will generate a Push Event by accessing the Endpoint.

[todo] Complete description of Application below

Application : A program which requires access to push notifications. The UserAgent acts on

Channel : The flow of information from AppServer through WebPushServer to UserAgent.

ChannelID : Unique identifier for a Channel. Generated by UserAgent for a particular application. Opaque identifier for both UserAgent and WebPushServer. This MUST NOT be exposed to an application.

Endpoint : A REST-ful HTTPS URL uniquely associated to a channel. Requests to this URL should update the WebPushServer state for the channel. MUST be exposed to third-party applications.

UAID : A globally unique UserAgent ID. Used by the WebPushServer to associate channelIDs with a client. Stored by the UserAgent, but opaque to it.

UserAgent : A device or program that implements the client side of the WebPush Protocol.

Version : Monotonically increasing 64-bit integer describing the application state. This holds meaning as a primary key or similar only to the AppServer. The WebPushServer and UserAgent and App should use this only for detecting changes. MUST be exposed to applications.

WebPushServer : A publicly accessible server that implements the server side of the WebPush Protocol and exposes an HTTPS API for AppServer’s to notify it.

3. Protocol Overview

The WebPush protocol defines how UserAgents and WebPushServers communicate to ensure reliable delivery of the latest version of a channel from the WebPushServer to the UserAgent.

The WebPush communication channel is WebSockets, and the wire protocol is JSON, with messages defined below. The WebSocket specific HTTP header Sec-WebSocket-Protocol MUST be set to push-notification by the UserAgent. The WebPushServer SHOULD reject the connection if the header is not set.

All messages MUST use TLS (wss:// protocol for WebSockets). In addition, Endpoints generated by WebPushServer’s MUST use HTTPS URLs.

4. Messages

All messages are encoded as JSON. All messages MUST have the following fields:

messageType (string)

Defines the message type

4.1. Handshake

After the WebSocket is established, including whatever optional WebPushServer authentication is required, the UserAgent begins communication by sending a hello message. The hello message contains the UAID of the UserAgent has one or returned by the server from an earlier handshake. The UserAgent may also transmit the channelIDs it knows so the server may synchronize its state.

The server MAY respect this UAID, but it is at liberty to ask the UserAgent to change its UAID in the response.

If the UserAgent receives a new UAID in the hello response, it MUST delete all existing channelIDs and their associated versions. It MAY then wake up all registered applications immediately or at a later date by sending them a push-register message.

The handshake is considered ‘‘complete’’, once the UserAgent has received a reply.

An UserAgent MUST transmit a hello message only once on its WebSocket. If the handshake is not completed in the first try, it MUST disconnect the WebSocket and begin a new connection.

NOTE: Applications may request registrations or unregistrations from the UserAgent, before or when the handshake is in progress. The UserAgent MAY buffer these or report errors to the application. But it MUST NOT send these requests to the WebPushServer until the handshake is completed.

4.1.1. UserAgent -> WebPushServer

messageType = “hello”
Begin handshake
uaid string (REQUIRED)
If the UserAgent has a previously assigned UAID, it should send it. Otherwise send an empty string.
channelIDs list of strings (REQUIRED)
If the UserAgent has a list of channelIDs it wants to be notified of, it may pass these, otherwise an empty list.

Extra fields: The UserAgent MAY pass any extra JSON data to the WebPushServer. For example, this data may include information required to wake up the UserAgent using out-of-band, proprietary methods, or contain the last time the UserAgent successfully connected. Fields prefixed by “wp-“ are reserved for future WebPush use. The WebPushServer MAY ignore this data.

4.1.1.1. Example

  {
    "messageType": "hello",
    "uaid": "fd52438f-1c49-41e0-a2e4-98e49833cc9c",
    "channelIDs": ["431b4391-c78f-429a-a134-f890b5adc0bb",
                   "a7695fa0-9623-4890-9c08-cce0231e4b36"],
    "lastAccess": 1399049780
  }

4.1.2. WebPushServer -> UserAgent

WebPushServers MUST only respond to a hello once. UserAgents MUST ignore multiple hello replies.

messageType = “hello”
Responses generally have the same messageType as the request
uaid string (REQUIRED)
If the UserAgent provides an empty or invalid UAID value, the WebPushServer will generate and return a new UAID value. If the UserAgent sent a valid UAID and the WebPushServer is now in sync with the UserAgent, return the UserAgent provided UAID. It is RECOMMENDED that a UAID be a UUIDv4 token.
status number (REQUIRED)
A HTTP compatible numeric code indicating the status of the request. For example; A 200 request indicates normal success, a 302 indicates a redirect request, a 500 indicates a server error has occurred, etc.)
redirect string (OPTIONAL)
The WebPushServer may optionally request that the UserAgent reconnect to a different URL. The UserAgent MUST disconnect on receiving this command and try reconnecting to the associated URL.

Extra fields: The WebPushServer MAY pass any extra JSON data back to the UserAgent. Fields prefixed by “wp-“ are reserved for future WebPush use. The UserAgent MAY ignore this data.

[todo] what kind of restrictions do we want to put on the redirect

4.1.2.1. Example

  {
    "messageType": "hello",
    "status": 200,
    "uaid": "fd52438f-1c49-41e0-a2e4-98e49833cc9c",
    "connected": 1399049780
  }

4.2. Register

The Register message is used by the UserAgent to request that the WebPushServer notify it when a channel changes. Since channelIDs are associated with only one UAID, this effectively creates the channel, while unregister destroys the channel.

The channelID is chosen by the UserAgent because it also acts like a nonce for the Register message itself. Because of this WebPushServers MAY respond out of order to multiple register messages or messages may be lost without compromising correctness of the protocol.

The request is considered successful only after a response is received with a status code of 200.

On success the UserAgent MUST:

NOTE: The register call is made by the UserAgent on behalf of an application. The UserAgent SHOULD have reasonable timeouts in place so that the application is not kept waiting for too long if the server does not respond or the UserAgent has to retry the connection.

4.2.1. UserAgent -> WebPushServer

messageType = “register”

registering
channelID string (REQUIRED)

A unique identifier generated by the UserAgent, distinct from any existing channelIDs it has registered. It is RECOMMENDED that this is a UUIDv4 token.

#### Example

  {
    "messageType": "register",
    "channelID": "d9b74644-4f97-46aa-b8fa-9393985cd6cd"
  }

4.2.2. WebPushServer -> UserAgent

messageType = “register”
registering
channelID string (REQUIRED)
This MUST be the same as the channelID sent by the UserAgent in the register request that this message is a response to.
status number (REQUIRED)
An HTTP compatible numeric value indicating the status of the request. used to indicate success/failure. MUST be one of: * 200 - OK. Success. Idempotent: If the WebPushServer receives a register for the same channelID from a UserAgent which already has a registration for the channelID, it should still respond with success. * 409 - Conflict. The chosen ChannelID is already in use and NOT associated with this UserAgent. UserAgent SHOULD retry with a new ChannelID as soon as possible. * 500 - Internal server error. Database out of space or offline. Disk space full or whatever other reason due to which the WebPushServer could not grant this registration. UserAgent SHOULD avoid retrying immediately.
pushEndpoint string (REQUIRED)
Should be the URL sent to the application by the UserAgent. AppServers will contact the WebPushServer at this URL to update the version of the channel identified by channelID.

4.2.2.1. Example

  {
    "messageType": "register",
    "channelID": "d9b74644-4f97-46aa-b8fa-9393985cd6cd",
    "status": 200,
    "pushEndpoint": "http://pushserver.example.org/d9b74644"
  }

4.3. Unregister

Unregistration is an optional procedure.

The unregister is required only between the App and the UserAgent, so that the UserAgent stops notifying the App when the App is no longer interested in a pushEndpoint.

The unregister is also useful to the AppServer, because it should stop sending notifications to an endpoint the App is no longer monitoring. Even then, it is really an optimization so that the AppServer need not have some sort of automatic deletion mechanism to clean up endpoints at later intervals of time.

Well-behaved AppServers will stop notifying it of unregistered endpoints automatically. Well behaved UserAgents won’t notify their apps of unregistered updates either. So the WebPushServer can continue to process notifications and pass them on to UserAgents, when it has not been told about the unregistration.

When an App calls unregister(endpoint) it is RECOMMENDED that the UserAgent follow these steps:

4.3.1. UserAgent -> WebPushServer

messageType = “unregister”
unregistering
channelID string (REQUIRED)
The previously registered ChannelID the UserAgent no longer wishes to receive updates for.

4.3.1.1. Example

  {
    "messageType": "unregister",
    "channelID": "d9b74644-4f97-46aa-b8fa-9393985cd6cd"
  }

4.3.2. WebPushServer -> UserAgent

messageType = “unregister”
unregistering
channelID string (REQUIRED)
This MUST be the same as the channelID sent by the UserAgent in the unregister request that this message is a response to.
status number (REQUIRED)
Used to indicate success/failure. MUST be one of: * 200 - OK. Success. Idempotent: If the WebPushServer receives a unregister * 500 - Internal server error. Database offline or whatever other reason due to which the WebPushServer could not grant this unregistration. UserAgent SHOULD avoid retrying immediately.

4.3.2.1. Example

  {
    "messageType": "unregister",
    "channelID": "d9b74644-4f97-46aa-b8fa-9393985cd6cd",
    "status": 200
  }

4.4. Ping

The connection to the WebPush Server may be lost due to network issues. When the UserAgent detects loss of network, it should reconnect. There are situations in which the TCP connection dies without either end discovering it immediately. The UserAgent should send a ping approximately every 30 minutes and expect a reply from the server in a reasonable time (The Mozilla UserAgent uses 10 seconds). If no data is received, the connection should be presumed closed and a new connection started.

The UserAgent should consider normal communications as an indication that the socket is working properly. It SHOULD send the ping packet only if no activity has occurred in the past 30 minutes.

4.4.1. UserAgent -> WebPushServer

An empty JSON object (The 2-character string {}) is sent. This object requires no alternative processing on the server, keeping transmission size small.

4.4.2. WebPushServer -> UserAgent

The WebPushServer may reply with any data. The UserAgent is only concerned about the state of the connection. It is RECOMMENDED that the WebPushServer either deliver pending notifications or an empty JSON object ({}).

4.5. Notification

4.5.1. AppServer -> WebPushServer

[todo] the push protocol needs to support data. We also need to talk about the lifetime of this data.

The AppServer MUST make a HTTP PUT request to the Endpoint received from the App.

If no request body is present, the server MAY presume the version to be the current server UTC.

If the request body is present, the Content-Type MUST be application/x-www-form-urlencoded and the request body MUST contain the string “version=N”.

Authentication is optional and left to the WebPushServer provider.

4.5.1.1. Example

 curl -X PUT -H "Content-Type: application/x-www-form-urlencoded" -d
"version=123" "https://push.example.com/endpoint/123abcd"

4.5.2. WebPushServer -> AppServer

The HTTP response status code indicates if the request was successful.

Additional status codes may be returned based on requirements of the WebPushServer provider. Please refer to the provider documentation.

The HTTP response body SHOULD be empty.

4.5.3. WebPushServer -> UserAgent

Notifications are acknowledged by the UserAgent. WebPushServers should retry unacknowledged notifications every 60 seconds. If the version of an unacknowledged notification is updated, the WebPushServer MAY queue up a new notification for this channelID and the new version, and remove the old notification from the pending queue.

The Notification message may contain additional data specific to the WebPushServer provider. This data may be safely ignored by the UserAgent. Please refer to the WebPushServer provider documentation for details regarding this data. Please note that fields prefixed by “wp-“ are considered reserved for future use by WebPush.

messageType: “notification”
notification
updates list REQUIRED
The list contains one or more {“channelID”: “id”, “version”: N } pairs.

4.5.3.1. Example

  {
    "messageType": "notification",
    "updates": [
      { "channelID": "431b4391-c78f-429a-a134-f890b5adc0bb",
        "version": 23,
        "data": "" },
      { "channelID": "a7695fa0-9623-4890-9c08-cce0231e4b36",
        "version": 42,
        "data": "Make the Internet work better" } ]
  }

4.5.3.2. UserAgent -> WebPushServer

It is RECOMMENDED that the UserAgent try to batch all pending acknowledgments into fewer messages. ACK messages do not require a response from the WebPushServer.

messageType =”ack”
ack
updates list
The list contains one or more {“channelID”: channelID, “version”: N} pairs.

[TODO] – ack does not require DATA response!

4.5.3.2.1. Example

  {
    "messageType": "ack",
    "updates": [
       { "channelID": "431b4391-c78f-429a-a134-f890b5adc0bb",
         "version": 23 },
       { "channelID": "a7695fa0-9623-4890-9c08-cce0231e4b36",
         "version": 42 } ]
  }

5. Synchronization of server and client state

6. Achieving reliable delivery

At any time, if the WebPushServer reaches an inconsistent condition, due to database failure, network failure, or any other reason, it MAY drop all state. It MUST then disconnect all active clients, forcing them to reconnect and begin a handshake to get synchronized.

7. WebPushServer Data Retention Policy

The Data Retention policy of the WebPushServer is determined by the provider of the service. It is RECOMMENDED that when data for a given UAID is expired without access, the UAID is marked as invalid, resulting in the UserAgent re-registering channels.

8. Alternative communication

In environments or devices where maintaining an always alive WebSocket is difficult, UserAgents and WebPushServers MAY implement alternative means to notify UserAgents about updates. This out of band notification SHOULD be restricted to request the UserAgent to establish the WebSocket. WebPush state SHOULD NOT be transmitted out of band, since reliable delivery may not be guaranteed.

9. Security Considerations

[TODO]

10. IANA Considerations

[TODO]

11. Normative References

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

Authors' Addresses

Douglas Turner II Mozilla EMail: dougt@mozilla.com
JR Conlin Mozilla EMail: jrconlin@mozilla.com
Nikhil Marathe Mozilla EMail: nmarathe@mozilla.com