XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH)

This specification defines a transport protocol that emulates a bidirectional stream between two entities (such as a client and a server) by efficiently using multiple synchronous HTTP request/response pairs without requiring the use of polling or asynchronous chunking.


NOTICE: The protocol defined herein is a Draft Standard of the XMPP Standards Foundation. Implementations are encouraged and the protocol is appropriate for deployment in production systems, but some changes to the protocol are possible before it becomes a Final Standard.


Document Information

Series: XEP
Number: 0124
Publisher: XMPP Standards Foundation
Status: Draft
Type: Standards Track
Version: 1.6
Last Updated: 2007-02-21
Approving Body: XMPP Council
Dependencies: RFC 1945, RFC 2616, RFC 3174
Supersedes: None
Superseded By: None
Short Name: bosh
Schema: <http://www.xmpp.org/schemas/httpbind.xsd>
Wiki Page: <http://wiki.jabber.org/index.php/Bidirectional-streams Over Synchronous HTTP (BOSH) (XEP-0124)>


Author Information

Ian Paterson

Email: ian.paterson@clientside.co.uk
JabberID: ian@zoofy.com

Dave Smith

Email: dizzyd@jabber.org
JabberID: dizzyd@jabber.org

Peter Saint-Andre

JabberID: stpeter@jabber.org
URI: https://stpeter.im/


Legal Notices

Copyright

This XMPP Extension Protocol is copyright (c) 1999 - 2008 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at <http://www.xmpp.org/extensions/ipr-policy.shtml> or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).

Discussion Venue

The preferred venue for discussion of this document is the Standards discussion list: <http://mail.jabber.org/mailman/listinfo/standards>.

Given that this XMPP Extension Protocol normatively references IETF technologies, discussion on the XSF-IETF list may also be appropriate (see <http://mail.jabber.org/mailman/listinfo/jsf-ietf> for details).

Errata may be sent to <editor@xmpp.org>.

Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Conformance Terms

The following keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".


Table of Contents


1. Introduction
2. Requirements
3. Architectural Assumptions
4. The BOSH Technique
5. HTTP Overview
6. <body/> Wrapper Element
7. Initiating a BOSH Session
    7.1. Session Creation Request
    7.2. Session Creation Response
8. Sending and Receiving XML Stanzas
9. Acknowledgements
    9.1. Request Acknowledgements
    9.2. Response Acknowledgements
10. Inactivity
11. Overactivity
12. Polling Sessions
13. Terminating the HTTP Session
14. Request IDs
    14.1. Generation
    14.2. In-Order Message Forwarding
    14.3. Broken Connections
15. Protecting Insecure Sessions
    15.1. Applicability
    15.2. Introduction
    15.3. Generating the Key Sequence
    15.4. Use of Keys
    15.5. Switching to Another Key Sequence
16. Multiple Streams
    16.1. Introduction
    16.2. Discovery
    16.3. Adding Streams To A Session
    16.4. Transmitting Stanzas
    16.5. Closing a Stream
    16.6. Error Conditions
17. Error and Status Codes
    17.1. HTTP Conditions
    17.2. Terminal Binding Conditions
    17.3. Recoverable Binding Conditions
    17.4. XML Stanza Conditions
18. Alternative Script Syntax
    18.1. Introduction
    18.2. Changes to the Request Syntax
    18.3. Changes to the Response Syntax
19. Security Considerations
    19.1. Encryption
    19.2. Unpredictable SID and RID
    19.3. Script Syntax
20. IANA Considerations
21. XMPP Registrar Considerations
    21.1. Protocol Namespaces
22. XML Schema
Notes
Revision History


1. Introduction

Certain applications often find that arbitrary TCP connections (see RFC 793 [1]) cannot be established (e.g., applications that are restricted either by their runtime environments or by firewalls permitting only Web browsing). BOSH, the protocol described in this document, may be used as a "drop-in" alternative to a bidirectional TCP connection. It is a mature, fully-featured protocol that has been in use for many years with many open source and commercial implementations. It overcomes common communication constraints by employing fully-compliant "cookie-free" [2] HTTP 1.0 or HTTP 1.1 as a transport (see RFC 1945 [4] and RFC 2616 [5]).

BOSH can transport any data efficiently and with minimal latency in both directions. For applications that require both "push" and "pull" communications, BOSH is significantly more bandwidth-efficient and responsive than most other bidirectional HTTP-based transport protocols (e.g. Jabber HTTP Polling [6]) and techniques now commonly known as AJAX.

BOSH achieves this efficiency and low-latency by avoiding polling without resorting to chunked HTTP responses (i.e. without using the technique which is now commonly known as "Comet"). The protocol employs multiple synchronous HTTP request/response pairs. This technique allows it to pass through even those proxies that buffer partial HTTP responses before forwarding the full responses only once they are available.

Note: Although the XML being transported in the examples herein is XMPP (see RFC 3920 [7]), this transport is not part of XMPP. In fact, from its conception the intention of the primary author was that it could be used to implement any bidirectional XML stream transporting a mixture of elements qualified by namespaces defined by different protocols (e.g., both XMPP and JSON). This mix is necessary since some connection managers may not support Multiple Streams and constrained clients often have no access to HTTP Pipelining (which limits them to one BOSH session at a time). BOSH connection managers are generally not required to understand anything about the XML content that they transport beyond perhaps ensuring that each XML stanza is qualified by the correct namespace. XMPP Over BOSH [8] documents some XMPP-specific extensions of this protocol that were formerly included in this document.

Note: This document inherits terminology regarding the Hypertext Transport Protocol from RFC 1945 and RFC 2616.

2. Requirements

The following design requirements reflect the need to offer performance as close as possible to a standard TCP connection.

  1. Compatible with constrained runtime environments** (e.g., mobile and browser-based clients).
  2. Enable browser-based clients to make bidirectional cross-domain connections.*
  3. Compatible with proxies that buffer partial HTTP responses.*
  4. Efficient through proxies that limit the duration of HTTP responses.*
  5. Fully-compatible with HTTP/1.0.*
  6. Compatible with restricted network connections (e.g., firewalls, proxies, and gateways).
  7. Fault tolerant (e.g., session recovers after an underlying TCP connection breaks at any stage during an HTTP request).
  8. Extensible.
  9. Consume significantly less bandwidth than polling-based protocols.
  10. Significantly more responsive (lower latency) than polling-based protocols.
  11. Support for polling (for clients that are limited to a single HTTP connection at a time).
  12. In-order delivery of data.
  13. Guard against unauthorized users interjecting HTTP requests into a session.
  14. Protect against denial of service attacks.
  15. Multiplexing of data streams

*Not possible to fulfill these requirements with the Comet technique.

**Compatibility with constrained runtime environments implies the following restrictions:

  1. Clients should not be required to have programmatic access to the headers of each HTTP request and response (e.g., cookies or status codes).
  2. The body of each HTTP request and response may be parsable XML with a single root element.
  3. Clients should be able to specify the Content-Type of the HTTP responses they receive.

3. Architectural Assumptions

This document assumes that most implementations will utilize a specialized "connection manager" to handle HTTP connections rather than the usual TCP connections. Effectively, such a connection manager will be a specialized HTTP server that translates between the HTTP requests and responses defined herein and the data streams (or API) implemented by the server or servers with which it communicates, thus enabling an HTTP client to connect to a server. We can illustrate this graphically as follows:

    Server
      |
      |  [unwrapped data streams]
      |
Connection Manager
      |
      |  [HTTP + <body/> wrapper]
      |
  HTTP Client
    

BOSH addresses communications between an HTTP client and the connection manager only. It does not address communications between the connection manager and the server, since such communications are implementation-specific (e.g., the server may natively support this HTTP binding, in which case the connection manager will be a logical entity rather than a physical entity; alternatively the connection manager may be an independant translating proxy such that the server may believe it is talking directly to the client over TCP; or the connection manager and the server may use a component protocol or an API defined by the server implementation).

Furthermore, no aspect of this protocol limits its use to client-to-server communications. It could be used for server-to-server or component-to-server communications as well. However, this document focuses exclusively on use of the transport by clients that cannot maintain arbitrary persistent TCP connections with a server. We assume that servers and components are under no such restrictions and thus would use TCP.

4. The BOSH Technique

Since HTTP is a synchronous request/response protocol, the traditional solution to emulating a bidirectional-stream over HTTP involved the client intermittently polling the connection manager to discover if it has any data queued for delivery to the client. This naive approach wastes a lot of network bandwidth by polling when no data is available. It also reduces the responsiveness of the application since the data spends time queued waiting until the connection manager receives the next poll (HTTP request) from the client. This results in an inevitable trade-off between responsiveness and bandwidth, since increasing the polling frequency will decrease latency but simultaneously increase bandwidth consumption (or vice versa if polling frequency is decreased).

The technique employed by this protocol achieves both low latency and low bandwidth consumption by encouraging the connection manager not to respond to a request until it actually has data to send to the client. As soon as the client receives a response from the connection manager it sends another request, thereby ensuring that the connection manager is (almost) always holding a request that it can use to "push" data to the client.

If the client needs to send some data to the connection manager then it simply sends a second request containing the data. Unfortunately most constrained clients do not support HTTP Pipelining (concurrent requests over a single connection), so the client typically needs to send the data over a second HTTP connection. The connection manager always responds to the request it has been holding on the first connection as soon as it receives a new request from the client - even if it has no data to send the client. It does that to make sure the client can send more data immediately if necessary. (The client SHOULD NOT open more than two HTTP connections to the connection manager at the same time, [9] so it would otherwise have to wait until the connection manager responds to one of the requests.)

BOSH works reliably even if network conditions force every HTTP request to be made over a different TCP connection. However, if as is usually the case, the client is able to use HTTP/1.1, then (assuming reliable network conditions) all requests during a session will pass over the same two persistent TCP connections. Almost all of the time (see below) the client is able to push data on one of the connections, while the connection manager is able to "push" data on the other (so latency is as low as a standard TCP connection). It's interesting to note that the roles of the two connections typically switch whenever the client sends data to the connection manager.

If there is no traffic in either direction for an agreed amount of time (typically a couple of minutes), then the connection manager responds to the client with no data, and that response immediately triggers a fresh client request. The connection manager does that to ensure that if a network connection is broken then both parties will realise within a reasonable amount of time. This exchange is similar to the "keep-alive" or "ping" that is common practice over most persistent TCP connections. Since the BOSH technique involves no polling, bandwidth consumption is not significantly greater than a standard TCP connection. [10]

Most of the time data can be pushed immediately. However, if one of the endpoints has just pushed some data then it will usually have to wait for a network round trip until it is able to push again. If HTTP Pipelining is available to the client then multiple concurrent requests are possible. So the client can always push data immediately. It can also ensure the connection manager is always holding enough requests such that even during bursts of activity it will never have to wait before pushing data. Furthermore, if the pool of requests being held by the connection manager is large enough, then the client will not be under pressure to send a new empty request immediately after receiving data from the connection manager. It can instead wait until it needs to send data. So, if over time the traffic to and from the client is balanced, bandwidth consumption will be about the same as if a standard TCP connection was being used.

Each block of data pushed by the connection manager is a complete HTTP response. So, unlike the Comet technique, the BOSH technique works through intermediate proxies that buffer partial HTTP responses. It is also fully compliant with HTTP/1.0 - which does not provide for chunked transfer encoding. Also unlike Comet, Web clients can use BOSH to make cross-domain connections.

5. HTTP Overview

All information is encoded in the body of standard HTTP POST requests and responses. Each HTTP body contains a single <body/> wrapper which encapsulates the XML elements being transferred (see <body/> Wrapper Element).

Clients SHOULD send all HTTP requests over a single persistent HTTP/1.1 connection using HTTP Pipelining. However, a client MAY deliver its POST requests in any way permited by RFC 1945 or RFC 2616. For example, constrained clients can be expected to open more than one persistent connection instead of using Pipelining, or in some cases to open a new HTTP/1.0 connection to send each request. However, clients and connection managers SHOULD NOT use Chunked Transfer Coding, since intermediaries may buffer each partial HTTP request or response and only forward the full request or reponse once it is available.

Clients MAY include an HTTP Accept-Encoding header in any request. If the connection manager receives a request with an Accept-Encoding header, it MAY include an HTTP Content-Encoding header in the response (indicating one of the encodings specified in the request) and compress the response body accordingly.

Requests and responses MAY include HTTP headers not specified herein. The receiver SHOULD ignore any such headers.

Each BOSH session MAY share the HTTP connection(s) it uses with other HTTP traffic, including other BOSH sessions and HTTP requests and responses completely unrelated to this protocol (e.g., web page downloads). However, the responses to requests that are not part of the session sent over the same connection using HTTP pipelining (or queued to be sent over the same connection) may be delayed if they were sent while a request that is part of the session is being held (since the connection manager MUST send its responses in the same order that the requests were received, and the connection manager typically delays its responses).

The HTTP Content-Type header of all client requests SHOULD be "text/xml; charset=utf-8". However, clients MAY specify another value if they are constrained to do so (e.g., "application/x-www-form-urlencoded" or "text/plain"). The client and connection manager SHOULD ignore all HTTP Content-Type headers they receive.

6. <body/> Wrapper Element

The body of each HTTP request and response contains a single <body/> wrapper element qualified by the 'http://jabber.org/protocol/httpbind' namespace. The content of the wrapper is the data being transfered. The <body/> element and it's content together MUST conform to the specifications set out in XML 1.0 [11]. They SHOULD also conform to Namespaces in XML [12]. The content MUST NOT contain any of the following (all defined in XML 1.0):

The <body/> wrapper MUST NOT contain any XML character data, although its child elements MAY contain character data. The <body/> wrapper MUST contain zero or more complete XML immediate child elements (called "stanzas" in this document, e.g., XMPP stanzas, or elements containing XML character data that represents objects using the JSON data interchange format - see RFC 4627 [13]). Each <body/> wrapper MAY contain stanzas qualified under a wide variety of different namespaces.

The <body/> element of every client request MUST possess a sequential request ID encapsulated via the 'rid' attribute; For details, refer to the Request IDs section of this document.

7. Initiating a BOSH Session

7.1 Session Creation Request

The first request from the client to the connection manager requests a new session.

The <body/> element of the first request SHOULD possess the following attributes (they SHOULD NOT be included in any other requests except as specified in Adding Streams To A Session):

Note: Clients that only support Polling Sessions MAY prevent the connection manager from waiting by setting 'wait' or 'hold' to "0". However, polling is NOT RECOMMENDED since the associated increase in bandwidth consumption and the decrease in responsiveness are both typically one or two orders of magnitude!

A connection manager MAY be configured to enable sessions with more than one server in different domains. When requesting a session with such a 'proxy' connection manager, a client SHOULD include a 'route' attribute that specifies the protocol, hostname, and port of the server with which it wants to communicate, formatted as "proto:host:port" (e.g., "xmpp:jabber.org:9999"). [15] A connection manager that is configured to work only with a single server (or only with a defined list of domains and the associated list of hostnames and ports that are serving those domains) MAY ignore the 'route' attribute. (Note that the 'to' attribute specifies the domain being served, not the hostame of the machine that is serving the domain.)

A client MAY include a 'from' attribute to enable the connection manager to forward its identity to the server.

A client MAY include an 'ack' attribute (set to "1") to indicate that it will be using acknowledgements throughout the session and that the absence of an 'ack' attribute in any request is meaningful (see Acknowledgements).

A client MAY include a 'secure' attribute to specify that communications between the connection manager and the server must be "secure". (Note: The 'secure' attribute is of type xs:boolean (see XML Schema Part 2 [16]) and the default value is "false". [17]) If a connection manager receives a session request with the 'secure' attribute set to "true" or "1", then it MUST respond to the client with a remote-connection-failed error as soon as it determines that it cannot communicate in a secure way with the server. A connection manager SHOULD consider communications with the server to be "secure" if they are encrypted using SSL or TLS with verified certificates, or if it is running on the same physical machine as the server. A connection manager MAY consider communications over a "private" network to be secure, even without SSL or TLS; however, a network SHOULD be considered "private" only if the administrator of the connection manager is sure that unknown individuals or processes do not have access to the network (i.e., individuals or processes who do not have access to either the connection manager or the server). The connection manager SHOULD try to establish a secure connection with the server even if the client does not specifically require it.

Some clients are constrained to only accept HTTP responses with specific Content-Types (e.g., "text/html"). The <body/> element of the first request MAY possess a 'content' attribute. This specifies the value of the HTTP Content-Type header that MUST appear in all the connection manager's responses during the session. If the client request does not possess a 'content' attribute, then the HTTP Content-Type header of responses MUST be "text/xml; charset=utf-8".

Example 1. Requesting a BOSH session

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104

<body content='text/xml; charset=utf-8'
      hold='1'
      rid='1573741820'
      to='jabber.org'
      route='xmpp:jabber.org:9999'
      secure='true'
      ver='1.6'
      wait='60'
      ack='1'
      xml:lang='en'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: All requests after the first one MUST include a valid 'sid' attribute (provided by the connection manager in the Session Creation Response). The initialization request is unique in that the <body/> element MUST NOT possess a 'sid' attribute.

7.2 Session Creation Response

After receiving a new session request, the connection manager MUST generate an opaque, unpredictable session identifier (or SID). The SID MUST be unique within the context of the connection manager application. The <body/> element of the connection manager's response to the client's session creation request MUST possess the following attributes (they SHOULD NOT be included in any other responses):

The <body/> element SHOULD also include the following attributes (they SHOULD NOT be included in any other responses):

The connection manager MAY include an 'accept' attribute in the session creation response element, to specify the content encodings it can decompress. After receiving a session creation response with an 'accept' attribute, clients MAY include an HTTP Content-Encoding header in subsequent requests (indicating one of the encodings specified in the 'accept' attribute) and compress the bodies of the requests accordingly.

A connection manager MAY include an 'ack' attribute (set to the value of the 'rid' attribute of the session creation request) to indicate that it will be using acknowledgements throughout the session and that the absence of an 'ack' attribute in any response is meaningful (see Acknowledgements).

If the connection manager supports session pausing (see Inactivity) then it SHOULD advertise that to the client by including a 'maxpause' attribute in the session creation response element. The value of the attribute indicates the maximum length of a temporary session pause (in seconds) that a client MAY request.

For both requests and responses, the <body/> element and its content SHOULD be UTF-8 encoded. If the HTTP Content-Type header of a request/response specifies a character encoding other than UTF-8, then the connection manager MAY convert between UTF-8 and the other character encoding. However, even in this case, it is OPTIONAL for the connection manager to convert between encodings. The connection manager MAY inform the client which encodings it can convert by setting the optional 'charsets' attribute in the session creation response element to a space-separated list of encodings. [18]

As soon as the connection manager has established a connection to the server and discovered its identity, it MAY forward the identity to the client by including a 'from' attribute in a response, either in its session creation response, or (if it has not received the identity from the server by that time) in any subsequent response to the client. If it established a secure connection to the server (as defined in Initiating a BOSH Session), then in the same response the connection manager SHOULD also include the 'secure' attribute set to "true" or "1".

Example 2. Session creation response

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128

<body wait='60'
      inactivity='30'
      polling='5'
      requests='2'
      hold='1'
      ack='1573741820'
      accept='deflate,gzip'
      maxpause='120'
      sid='SomeSID'
      charsets='ISO_8859-1 ISO-2022-JP'
      ver='1.6'
      from='jabber.org'
      secure='true'
      xmlns='http://jabber.org/protocol/httpbind'/>

Example 3. Subsequent response with 'from' and 'secure' attributes

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128

<body from='jabber.org'
      secure='true'
      xmlns='http://jabber.org/protocol/httpbind'/>

8. Sending and Receiving XML Stanzas

After the client has successfully completed all required preconditions, it can send and receive XML stanzas via the HTTP binding.

Example 4. Transmitting stanzas

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188

<body rid='1249243562'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message to='contact@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
  <message to='friend@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
</body>

Upon receipt of a request, the connection manager SHOULD forward the content of the <body/> element to the server as soon as possible. In any case it MUST forward the content from different requests in the order specified by their 'rid' attributes.

The connection manager MUST also return an HTTP 200 OK response with a <body/> element to the client. Note: This does not indicate that the stanzas have been successfully delivered to the server.

It is RECOMMENDED that the connection manager not return an HTTP result until a stanza has arrived from the server for delivery to the client. However, the connection manager SHOULD NOT wait longer than the time specified by the client in the 'wait' attribute of its Session Creation Request, and it SHOULD NOT keep more HTTP requests waiting at a time than the number specified in the 'hold' attribute of the session creation request. In any case it MUST respond to requests in the order specified by their 'rid' attributes.

If there are no stanzas waiting or ready to be delivered within the waiting period, then the connection manager SHOULD include an empty <body/> element in the HTTP result:

Example 5. Empty response

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 64

<body xmlns='http://jabber.org/protocol/httpbind'/>

If the connection manager has received one or more stanzas from the server for delivery to the client, then it SHOULD return the stanzas in the body of its response as soon as possible after receiving them from the server. The example below includes stanzas qualified by different namespaces:

Example 6. Response with queued stanza

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 185

<body xmlns='http://jabber.org/protocol/httpbind'
      xmlns:json='http://json.org/'>
  <message from='contact@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>Hi yourself!</body>
  </message>
  <message from='friend@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>Hi yourself!</body>
  </message>
  <json:json>
  [
    {
      "precision": "zip",
      "Latitude":  37.7668,
      "Longitude": -122.3959,
      "Address":   "",
      "City":      "SAN FRANCISCO",
      "State":     "CA",
      "Zip":       "94107",
      "Country":   "US"
    },
    {
      "precision": "zip",
      "Latitude":  37.371991,
      "Longitude": -122.026020,
      "Address":   "",
      "City":      "SUNNYVALE",
      "State":     "CA",
      "Zip":       "94085",
      "Country":   "US"
    }
  ]
  </json:json>
</body>

The client MAY poll the connection manager for incoming stanzas by sending an empty <body/> element.

Example 7. Requesting XML Stanzas

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 88

<body rid='1249243563'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'/>

The connection manager MUST wait and respond in the same way as it does after receiving stanzas from the client.

9. Acknowledgements

9.1 Request Acknowledgements

When responding to a request that it has been holding, if the connection manager finds it has already received another request with a higher 'rid' attribute (typically while it was holding the first request), then it MAY acknowledge the reception to the client. The connection manager MAY set the 'ack' attribute of any response to the value of the highest 'rid' attribute it has received where it has also received all requests with lower 'rid' values.

Example 8. Response with request acknowledgement

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 64

<body ack='1249243564'
      xmlns='http://jabber.org/protocol/httpbind'/>

If the connection manager will be including 'ack' attributes on responses during a session then it MUST include an 'ack' attribute in its session creation response, and set the 'ack' attribute of responses throughout the session. Except that, after its session creation response, the connection manager SHOULD NOT include an 'ack' attribute in any response if the value would be the 'rid' of the request being responded to.

If the connection manager is permitted to hold more than one request at a time, then the reception of a lower-than-expected 'ack' value from the connection manager (or the unexpected abscence of an 'ack' attribute) can give the client an early warning that a network failure might have occurred (e.g., if the client believes the connection manager should have received the another request by the time it responded).

9.2 Response Acknowledgements

The client MAY similarly inform the connection manager about the responses it has received by setting the 'ack' attribute of any request to the value of the highest 'rid' of a request for which it has already received a response where it has also received all responses associated with lower 'rid' values. If the client will be including 'ack' attributes on requests during a session then it MUST include an 'ack' attribute (set to '1') in its session creation request, and set the 'ack' attribute of requests throughout the session. Except that, after its session creation request, the client SHOULD NOT include an 'ack' attribute in any request if it has received responses to all its previous requests.

Example 9. Request with response acknowledgement

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 88

<body rid='1249243566'
      sid='SomeSID'
      ack='1249243564'
      xmlns='http://jabber.org/protocol/httpbind'/>

After receiving a request with an 'ack' value less than the 'rid' of the last request that it has already responded to, the connection manager MAY inform the client of the situation by sending its next response immediately instead of waiting until it has stanzas to send to the client (e.g., if some time has passed since it responded). In this case it SHOULD include a 'report' attribute set to one greater than the 'ack' attribute it received from the client, and a 'time' attribute set to the number of milliseconds since it sent the response associated with the 'report' attribute.

Example 10. Response with report

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 64

<body report='1249243565'
      time='852'
      xmlns='http://jabber.org/protocol/httpbind'/>

Upon reception of a response with 'report' and 'time' attributes, if the client has still not received the response associated with the request identifier (RID) specified by the 'report' attribute, then it MAY choose to resend the request associated with the missing response (see Broken Connections).

10. Inactivity

After receiving a response from the connection manager, if none of the client's requests are still being held by the connection manager (and if the session is not a Polling Session), the client SHOULD make a new request as soon as possible. In any case, if no requests are being held, the client MUST make a new request before the maximum inactivity period has expired. The length of this period in seconds is specified by the 'inactivity' attribute in the session creation response.

If the connection manager has responded to all the requests it has received within a session and the time since its last response is longer than the maximum inactivity period, then it SHOULD assume the client has been disconnected and terminate the session without informing the client. If the client subsequently makes another request, then the connection manager SHOULD respond as if the session does not exist.

If the connection manager did not specify a maximum inactivity period in the session creation response, then it SHOULD allow the client to be inactive for as long as it chooses.

If the session is not a polling session then the connection manager SHOULD specify a relatively short inactivity period to ensure disconnections are discovered as early as possible. The RECOMMENDED time would be a little more than the number of seconds for a comfortable network round trip between the connection manager and the client under difficult network conditions (since the client can be expected to make a new request immediately - see above).

If a client encounters an exceptional temporary situation during which it will be unable to send requests to the connection manager for a period of time greater than the maximum inactivity period (e.g., while a runtime environment changes from one web page to another), and if the connection manager included a 'maxpause' attribute in its Session Creation Response, then the client MAY request a temporary increase to the maximum inactivity period by including a 'pause' attribute in a request. Note: If the connection manager did not specify a 'maxpause' attribute at the start of the session then the client MUST NOT send a 'pause' attribute during the session.

Example 11. Requesting a Session Pause

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 98

<body rid='1249243564'
      sid='SomeSID'
      pause='60'
      xmlns='http://jabber.org/protocol/httpbind'/>

Upon reception of a session pause request, if the requested period is not greater than the maximum permitted time, then the connection manager SHOULD respond immediately to all pending requests (including the pause request) and temporarily increase the maximum inactivity period to the requested time. Note: The response to the pause request MUST NOT contain any stanzas.

Note: If the client simply wants the connection manager to return all the requests it is holding then it MAY set the value of the 'pause' attribute to be the value of the 'inactivity' attribute in the connection manager's session creation response. (If the client believes it is in danger of becoming disconnected indefinitely then it MAY even request a temporary reduction of the maximum inactivity period by specifying a 'pause' value less than the 'inactivity' value, thus enabling the connection manager to discover any subsequent disconnection more quickly.)

The connection manager SHOULD set the maximum inactivity period back to normal upon reception of the next request from the client (assuming the connection manager hasn't already terminated the session).

11. Overactivity

The client SHOULD NOT make more simultaneous requests than specified by the 'requests' attribute in the connection manager's Session Creation Response. However the client MAY make one additional request if it is to pause or terminate a session.

If during any period the client sends a sequence of new requests (i.e. requests with incremented rid attributes, not repeat requests) longer than the number specified by the 'requests' attribute, and if the connection manager has not yet responded to any of the requests, and if the last request did not include either a 'pause' attribute or a 'type' attribute set to "terminate", then the connection manager SHOULD consider that the client is making too many simultaneous requests and terminate the HTTP session and return a 'policy-violation' terminal binding error to the client. Note: This behavior applies to equally to normal and polling sessions.

Example 12. Too many simultaneous requests response

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: If the connection manager did not specify a 'requests' attribute in the session creation response, then it MUST allow the client to send as many simultaneous requests as it chooses.

If during any period the client sends a sequence of new requests equal in length to the number specified by the 'requests' attribute, and if the connection manager has not yet responded to any of the requests, and if the last request was empty and did not include either a 'pause' attribute or a 'type' attribute set to "terminate", and if the last two requests arrived within a period shorter than the number of seconds specified by the 'polling' attribute in the session creation response, then the connection manager SHOULD consider that the client is making requests more frequently than it was permitted and terminate the HTTP session and return a 'policy-violation' terminal binding error to the client. Note: the behavior for Polling Sessions is slightly different.

Example 13. Too frequent requests response

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: If the connection manager did not specify a 'polling' attribute in the session creation response, then it MUST allow the client to send requests as frequently as it chooses.

12. Polling Sessions

It may not be possible for a constrained client to either use HTTP Pipelining or open more than one HTTP connection with the connection manager at a time. In this case the client SHOULD inform the connection manager by setting the values of the 'wait' and/or 'hold' attributes in its session creation request to "0", and then "poll" the connection manager at regular intervals throughout the session for stanzas it may have received from the server. Note: Even if the client does not request a polling session then the connection manager MAY require a client to use polling by setting the 'requests' attribute (which specifies the number of simultaneous requests the client may make) of its Session Creation Response to "1", however this is NOT RECOMMENDED.

If a session will use polling the connection manager SHOULD specify a higher than normal value for the 'inactivity' attribute (see Inactivity) in its session creation response. The increase SHOULD be greater than the value it specifies for the 'polling' attribute.

If the client sends two consecutive empty new requests (i.e. requests with incremented rid attributes, not repeat requests) within a period shorter than the number of seconds specified by the 'polling' attribute (the shortest allowable polling interval) in the session creation response, and if the connection manager's response to the first request contained no stanzas, then upon reception of the second request the connection manager SHOULD terminate the HTTP session and return a 'policy-violation' terminal binding error to the client.

Example 14. Too frequent polling response

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: If the connection manager did not specify a 'polling' attribute in the session creation response, then it MUST allow the client to poll as frequently as it chooses.

13. Terminating the HTTP Session

At any time, the client MAY gracefully terminate the session by sending a <body/> element with a 'type' attribute set to "terminate". The termination request MAY include one or more stanzas that the connection manager MUST forward to the server to ensure graceful logoff.

Example 15. Session termination by client

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 153

<body rid='1249243565'
      sid='SomeSID'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'>
  <presence type='unavailable'
            xmlns='jabber:client'/>
</body>

The connection manager SHOULD return to the client an HTTP 200 OK response with an empty <body/> element.

Example 16. Recoverable error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 72

<body type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'/>

Upon receiving the response, the client MUST consider the HTTP session to have been terminated.

14. Request IDs

14.1 Generation

The client MUST generate a large, random, positive integer for the initial 'rid' (see Security Considerations, this also prevents non-compliant proxies from caching Script Syntax responses) and then increment that value by one for each subsequent request. The client MUST take care to choose an initial 'rid' that will never be incremented above 9007199254740991 [20] within the session. In practice, a session would have to be extraordinarily long (or involve the exchange of an extraordinary number of packets) to exceed the defined limit.

14.2 In-Order Message Forwarding

When a client makes simultaneous requests, the connection manager may receive them out of order. The connection manager MUST forward the stanzas to the server and respond to the client requests in the order specified by the 'rid' attributes. The client MUST process responses received from the connection manager in the order the requests were made.

The connection manager SHOULD expect the 'rid' attribute to be within a window of values greater than the 'rid' of the previous request. The size of the window is equal to the maximum number of simultaneous requests allowed by the connection manager. If it receives a request with a 'rid' greater than the values in the window, then the connection manager MUST terminate the session with an error:

Example 17. Unexpected rid error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='item-not-found'
      xmlns='http://jabber.org/protocol/httpbind'/>

14.3 Broken Connections

Unreliable network communications or client constraints can result in broken connections. The connection manager SHOULD remember the 'rid' and the associated HTTP response body of the client's most recent requests which were not session pause requests (see Inactivity) and which did not result in an HTTP or binding error. The number of responses to non-pause requests kept in the buffer SHOULD be either the same as the maximum number of simultaneous requests allowed by the connection manager or, if Acknowledgements are being used, the number of responses that have not yet been acknowledged.

If the network connection is broken or closed before the client receives a response to a request from the connection manager, then the client MAY resend an exact copy of the original request. Whenever the connection manager receives a request with a 'rid' that it has already received, it SHOULD return an HTTP 200 (OK) response that includes the buffered copy of the original XML response to the client (i.e., a <body/> wrapper possessing appropriate attributes and optionally containing one or more XML stanzas or other allowable XML elements). If the original response is not available (e.g., it is no longer in the buffer), then the connection manager MUST return an 'item-not-found' terminal binding error:

Example 18. Response not in buffer error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='item-not-found'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: The error is the same whether the 'rid' is too large or too small. This makes it more difficult for an attacker to discover an acceptable value.

15. Protecting Insecure Sessions

15.1 Applicability

The OPTIONAL key sequencing mechanism described here MAY be used if the client's session with the connection manager is not secure. The session should be considered secure only if all client requests are made via SSL (or TLS) HTTP connections and the connection manager generates an unpredictable session ID. If the session is secure, it is not necessary to use this key sequencing mechanism.

Even if the session is not secure, the unpredictable session and request IDs specified in the preceding sections of this document already provide a level of protection similar to that provided by a connection bound to a single pair of persistent TCP/IP connections, and thus provide sufficient protection against a 'blind' attacker. However, in some circumstances, the key sequencing mechanism defined below helps to protect against a more determined and knowledgeable attacker.

It is important to recognize that the key sequencing mechanism defined below helps to protect only against an attacker who is able to view the contents of all requests or responses in an insecure session but who is not able to alter the contents of those requests (in this case, the mechanism prevents the attacker from interjecting HTTP requests into the session, e.g., termination requests or responses). However, the key sequencing mechanism does not provide any protection when the attacker is able to alter the contents of insecure requests or responses.

15.2 Introduction

The HTTP requests of each session MAY be spread across a series of different socket connections. This would enable an unauthorized user that obtains the session ID and request ID of a session and then use their own socket connection to interject <body/> request elements into the session and receive the corresponding responses.

The key sequencing mechanism below protects against such attacks by enabling a connection manager to detect <body/> request elements interjected by a third party.

15.3 Generating the Key Sequence

Prior to requesting a new session, the client MUST select an unpredictable counter ("n") and an unpredictable value ("seed"). The client then processes the "seed" through a cryptographic hash and converts the resulting 160 bits to a hexadecimal string K(1). It does this "n" times to arrive at the initial key K(n). The hashing algorithm MUST be SHA-1 as defined in RFC 3174 [21].

Example 19. Creating the key sequence

        K(1) = hex(SHA-1(seed))
        K(2) = hex(SHA-1(K(1)))
        ...
        K(n) = hex(SHA-1(K(n-1)))
      

15.4 Use of Keys

The client MUST set the 'newkey' attribute of the first request in the session to the value K(n).

Example 20. Session Request with Initial Key

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104

<body content='text/xml; charset=utf-8'
      hold='1'
      rid='1573741820'
      to='jabber.org'
      wait='60'
      xml:lang='en'
      newkey='ca393b51b682f61f98e7877d61146407f3d0a770'
      xmlns='http://jabber.org/protocol/httpbind'/>

The client MUST set the 'key' attribute of all subsequent requests to the value of the next key in the generated sequence (decrementing from K(n-1) towards K(1) with each request sent).

Example 21. Request with Key

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 88

<body rid='1573741821'
      sid='SomeSID'
      key='bfb06a6f113cd6fd3838ab9d300fdb4fe3da2f7d'
      xmlns='http://jabber.org/protocol/httpbind'/>

The connection manager MAY verify the key by calculating the SHA-1 hash of the key and comparing it to the 'newkey' attribute of the previous request (or the 'key' attribute if the 'newkey' attribute was not set). If the values do not match (or if it receives a request without a 'key' attribute and the 'newkey' or 'key' attribute of the previous request was set), then the connection manager MUST NOT process the element, MUST terminate the session, and MUST return an 'item-not-found' terminal binding error.

Example 22. Invalid Key Sequence Error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='item-not-found'
      xmlns='http://jabber.org/protocol/httpbind'/>

15.5 Switching to Another Key Sequence

A client SHOULD choose a high value for "n" when generating the key sequence. However, if the session lasts long enough that the client arrives at the last key in the sequence K(1) then the client MUST switch to a new key sequence.

The client MUST:

  1. Choose new values for "seed" and "n".
  2. Generate a new key sequence using the algorithm defined above.
  3. Set the 'key' attribute of the request to the next value in the old sequence (i.e. K(1), the last value).
  4. Set the 'newkey' attribute of the request to the value K(n) from the new sequence.

Example 23. New Key Sequence

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188

<body rid='1573741822'
      sid='SomeSID'
      key='6f825e81f4532b2c5fa2d12457d8a1f22e8f838e'
      newkey='113f58a37245ec9637266cf2fb6e48bfeaf7964e'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message to='contact@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
</body>

16. Multiple Streams

16.1 Introduction

The OPTIONAL feature described in this section enables multiple XML streams to be contained within a single HTTP session. This feature is essential in runtime environments that prevent HTTP Pipelining, thereby constraining the number of simultaneous HTTP requests a client may make to each connection manager, since clients running in such environments need multi-stream sessions if they are to connect using more than one account at the same time. This feature also reduces network traffic for any client that needs to establish parallel streams over HTTP.

16.2 Discovery

If a connection manager supports the multi-streams feature, it MUST include a 'stream' attribute in its Session Creation Response. If a client does not receive the 'stream' attribute then it MUST assume that the connection manager does not support the feature. [22]

The 'stream' attribute identifies the first stream to be opened for the session. The value of each 'stream' attribute MUST be an opaque and unpredictable name that is unique within the context of the connection manager application.

Example 24. Session creation response with stream name

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128

<body wait='60'
      inactivity='30'
      polling='5'
      requests='2'
      hold='1'
      accept='deflate,gzip'
      stream='firstStreamName'
      maxpause='120'
      sid='SomeSID'
      charsets='ISO_8859-1 ISO-2022-JP'
      ver='1.6'
      from='jabber.org'
      secure='true'
      xmlns='http://jabber.org/protocol/httpbind'/>

16.3 Adding Streams To A Session

If the connection manager included a 'stream' attribute in its session creation response then the client MAY ask it to open another stream at any time by sending it an empty <body/> element with a 'to' attribute. The request MUST include valid 'sid' and 'rid' [23] attributes, it SHOULD also include an 'xml:lang' attribute. The request MAY include 'route', 'from' and 'secure' attributes (see Session Creation Request), but it SHOULD NOT include 'ver', 'content', 'hold' or 'wait' attributes (since a new session is not being created).

Example 25. Requesting another stream

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104

<body sid='SomeSID'
      rid='1573741820'
      to='jabber.org'
      route='xmpp:jabber.org:9999'
      secure='true'
      xml:lang='en'
      xmlns='http://jabber.org/protocol/httpbind'/>

If the connection manager did not indicate its support for multiple streams at the start of the session then it MUST ignore the extra attributes and treat the request as a normal empty request for stanzas (see Sending and Receiving XML Stanzas). [24] Otherwise it MUST open a new stream with the specified server (see Session Creation Response), generate a new stream name and respond to the client with the name. The response MAY also include 'from' and 'secure' attributes, but it SHOULD NOT include 'sid', 'requests', 'polling', 'hold', 'inactivity', 'maxpause', 'accept', 'charsets', 'ver' or 'wait' attributes.

Example 26. Add stream response

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128

<body stream='secondStreamName'
      from='jabber.org'
      secure='true'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: If the response did not include either 'from' or 'secure' attributes then they MAY be sent in a subsequent response instead (see Session Creation Response). In that case the 'stream' attribute MUST also be specified.

16.4 Transmitting Stanzas

If more than one stream has been opened within a session, then all non-empty <body/> elements sent by the connection manager MUST include a 'stream' attribute that specifies which stream all the stanzas it contains belong to. The client SHOULD include a 'stream' attribute for the same purpose. The client MAY omit the 'stream' attribute if it wants the connection manager to broadcast the stanzas over all open streams. Note: A <body/> element MUST NOT contain different stanzas for different streams.

If a stream name does not correspond to one of the session's open streams, then the receiving connection manager SHOULD return an 'item-not-found' terminal binding error, or the receiving client SHOULD terminate the session. However, if the receiving entity has only just closed the stream (and the sender may not have been aware of that when it sent the stanzas), then it MAY instead simply silently ignore any stanzas the <body/> element contains.

Note: Empty <body/> elements that do not include a 'from' or 'secure' attribute SHOULD NOT include a 'stream' attribute (since nothing is being transmitted for any stream). If such a <body/> element does include a 'stream' attribute then the receiving entity SHOULD ignore the attribute.

Example 27. Client sends stanza with a stream name

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188

<body rid='1249243562'
      sid='SomeSID'
      stream='secondStreamName'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message to='contact@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
</body>

Note: The value of the 'stream' attribute of the response MAY be different to the corresponding request. [25]

Example 28. Connection manager responds with a different stream name

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 185

<body stream='firstStreamName'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message from='contact@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>Hi yourself!</body>
  </message>
</body>

If no stream name is specified by the connection manager then the client MUST assume the stanzas are associated with the first stream (even if the first stream has been closed).

If no stream name is specified by the client then the connection manager MUST broadcast the stanzas over all open streams. [26]

Example 29. Client asks for a stanza to be broadcast

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188

<body rid='1249243562'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'>
  <presence xmlns='jabber:client'>
    <show>away</show>
  </presence>
</body>

16.5 Closing a Stream

If more than one stream is open within a session, the client MAY close one open stream at any time using the procedure described in the section Terminating the HTTP Session above, taking care to specify the stream name with a 'stream' attribute. If the client closes the last stream the connection manager MUST terminate the session. If the client does not specify a stream name then the connection manager MUST close all open streams (sending any stanzas the terminate request contains to all streams), and terminate the session.

Example 30. Client closes one stream

POST /webclient HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 153

<body rid='1249243564'
      sid='SomeSID'
      stream='secondStreamName'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'>
  <presence type='unavailable'
            xmlns='jabber:client'/>
</body>

16.6 Error Conditions

If more than one stream is open within a session, the connection manager MAY include a 'stream' attribute in a fatal binding error (see Terminal Binding Conditions). If a 'stream' attribute is specified then the stream MUST be closed by both entities but the session SHOULD NOT be terminated.

Example 31. Fatal stream error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='remote-connection-failed'
      stream='secondStreamName'
      xmlns='http://jabber.org/protocol/httpbind'/>

Note: If the connection manager does not include a 'stream' attribute in a fatal binding error then all the session's open streams MUST be closed by both entities and the session MUST be terminated.

17. Error and Status Codes

There are four types of error and status reporting in HTTP responses:

Table 1: Error Condition Types

Condition TypeDescription
HTTP Conditions (Deprecated)The connection manager responds to an invalid request from a legacy client with a standard HTTP error. These are used for binding syntax errors, possible attacks, etc. Note that constrained clients are unable to differentiate between HTTP errors.
Terminal Binding ConditionsThese error conditions may be read by constrained clients. They are used for connection manager problems, abstracting stream errors, communication problems between the connection manager and the server, and invalid client requests (binding syntax errors, possible attacks, etc.)
Recoverable Binding ConditionsThese report communication problems between the connection manager and the client. They do not terminate the session. Clients recover from these errors by resending all the preceding <body/> wrappers that have not received responses.
Transported Protocol ConditionsErrors relating to the XML stanzas within <body/> wrappers are, in general, defined in the documentation of the protocol being transported. They do not terminate the session.

Full descriptions are provided below.

17.1 HTTP Conditions

Note: All HTTP codes except 200 have been superseded by Terminal Binding Conditions to allow clients to determine whether the source of errors is the connection manager application or an HTTP intermediary.

A legacy client (or connection manager) is a client (or connection manager) that did not include a 'ver' attribute in its session creation request (or response). A legacy client (or connection manager) will interpret (or respond with) HTTP error codes according to the table below. Non-legacy connection managers SHOULD NOT send HTTP error codes unless they are communicating with a legacy client. Upon receiving an HTTP error (400, 403, 404), a legacy client or any client that is communicating with a legacy connection manager MUST consider the HTTP session to be null and void. A non-legacy client that is communicating with a non-legacy connection manager MAY consider that the session is still active.

Table 2: HTTP Error and Status Codes

Code Name Superseded by Purpose
200 OK - Response to valid client request.
400 Bad Request bad-request Inform client that the format of an HTTP header or binding element is unacceptable (e.g., syntax error).
403 Forbidden policy-violation Inform client that it has broken the session rules (polling too frequently, requesting too frequently, too many simultaneous requests).
404 Not Found item-not-found Inform client that (1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit of the expected window, (4) connection manager is unable to resend response, (5) 'key' sequence is invalid.

No other HTTP error and status codes were defined.

Note: Any connection manager (not only legacy connection managers) MAY indicate that it does not support Script Syntax by sending an HTTP 404 error code (instead of sending a bad-request error using Scrypt Syntax).

Example 32. Script Syntax not supported error

HTTP/1.1 404 Not Found
Content-Length: 0

17.2 Terminal Binding Conditions

In any response it sends to the client, the connection manager MAY return a fatal error by setting a 'type' attribute of the <body/> element to "terminate". These binding errors imply that the HTTP session is terminated (unless a 'stream' attribute is specified - see Multiple Stream Error Conditions).

Note: Although many of these conditions are similar to the XMPP stream error conditions specified in RFC 3920, they should not be confused with XMPP stream errors. In cases where this protocol is being used to transport XMPP, any fatal XMPP stream error conditions experienced between the connection manager and the XMPP server SHOULD only be reported using the "remote-stream-error" condition as described below.

Example 33. Remote connection failed error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='terminate'
      condition='remote-connection-failed'
      xmlns='http://jabber.org/protocol/httpbind'/>

The following values of the 'condition' attribute are defined:

Table 3: Terminal Binding Error Conditions

Condition Purpose
bad-request* The format of an HTTP header or binding element received from the client is unacceptable (e.g., syntax error), or Script Syntax is not supported.
host-gone The target domain specified in the 'to' attribute or the target host or port specified in the 'route' attribute is no longer serviced by the connection manager.
host-unknown The target domain specified in the 'to' attribute or the target host or port specified in the 'route' attribute is unknown to the connection manager.
improper-addressing The initialization element lacks a 'to' or 'route' attribute (or the attribute has no value) but the connection manager requires one.
internal-server-error The connection manager has experienced an internal error that prevents it from servicing the request.
item-not-found* (1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit of the expected window, (4) connection manager is unable to resend response, (5) 'key' sequence is invalid
other-request Another request being processed at the same time as this request caused the session to terminate.
policy-violation* The client has broken the session rules (polling too frequently, requesting too frequently, too many simultaneous requests).
remote-connection-failed The connection manager was unable to connect to, or unable to connect securely to, or has lost its connection to, the server.
remote-stream-error Encapsulates an error in the protocol being transported.
see-other-uri The connection manager does not operate at this URI (e.g., the connection manager accepts only SSL or TLS connections at some https: URI rather than the http: URI requested by the client). The client may try POSTing to the URI in the content of the <uri/> child element.
system-shutdown The connection manager is being shut down. All active HTTP sessions are being terminated. No new sessions can be created.
undefined-condition The error is not one of those defined herein; the connection manager SHOULD include application-specific information in the content of the <body/> wrapper.

* If the client did not include a 'ver' attribute in its session creation request then the connection manager SHOULD send a deprecated HTTP Error Condition instead of this terminal binding condition. If the connection manager did not include a 'ver' attribute in its session creation response then the client SHOULD expect it to send a deprecated HTTP Error Condition instead of this terminal binding condition.

The following is an example of a "see-other-uri" condition:

Example 34. See other URI error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body condition='see-other-uri'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'>
  <uri>https://secure.jabber.org/xmppcm</uri>
</body>

The following is an example including a "remote-stream-error" condition:

Example 35. Remote error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body condition='remote-stream-error'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'
      xmlns:stream='http://etherx.jabber.org/streams'>
  <message from='contact@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>Hi yourself!</body>
  </message>
  <stream:error>
    <xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
    <text xmlns='urn:ietf:params:xml:ns:xmpp-streams'
          xml:lang='en'>
      Some special application diagnostic information!
    </text>
    <escape-your-data xmlns='application-ns'/>
  </stream:error>
</body>

Naturally, the client MAY report binding errors to the connection manager as well, although this is unlikely.

17.3 Recoverable Binding Conditions

In any response it sends to the client, the connection manager MAY return a recoverable error by setting a 'type' attribute of the <body/> element to "error". These errors do not imply that the HTTP session is terminated.

If it decides to recover from the error, then the client MUST repeat the HTTP request and all the preceding HTTP requests that have not received responses. The content of these requests MUST be identical to the <body/> elements of the original requests. This allows the connection manager to recover a session after the previous request was lost due to a communication failure.

Example 36. Recoverable error

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68

<body type='error'
      xmlns='http://jabber.org/protocol/httpbind'/>

17.4 XML Stanza Conditions

Application-level error conditions described in the documentation of the protocol being transported are routed to the client through the connection manager. They are transparent to the connection manager, and therefore out of scope for the transport binding defined herein.

18. Alternative Script Syntax

18.1 Introduction

The cross domain security restrictions of some runtime environments permit clients to access pure XML text only if it was received from a specific server (e.g., the hostname a Web client was downloaded from). Astonishingly the same environments typically permit clients to receive and execute scripts from any server! [27] The Security Considerations section below describes the significant risks of deploying Script Syntax.

To enable domain-restricted clients to use BOSH with any connection manager, this section proposes an optional alternative to the standard "BOSH Pure Syntax" seen in the other sections of this document. The "BOSH Script Syntax" defined here essentially inserts each <body/> element sent by the client into an HTTP GET header instead of into the body of a POST request. Each <body/> element sent by the connection manager is wrapped inside an ECMAScript (JavaScript) [28] string and function call. No changes to the <body/> element or to any other aspects of the protocol are required.

If, and only if, a client is unable to use the Pure Syntax, then it MAY send a session request to a BOSH connection manager using Script Syntax instead. If the connection manager supports Script Syntax then it MUST send its Session Creation Response using Script Syntax, and all subsequent client requests and connection manager responses within the session MUST be sent using Script Syntax. If the connection manager does not support the "BOSH Script" syntax then it SHOULD return either an 'item-not-found' terminal binding error (in Script Syntax) or an HTTP 404 (Not Found) error in response to the client's session request:

Note: The line break in the body of the HTTP response in the following example is included only to improve readability. In practice there MUST be no line breaks.

Example 37. Script Syntax not supported binding error

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=utf-8
Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 212

_BOSH_("<body type='terminate' condition='item-not-found'
        xmlns='http://jabber.org/protocol/httpbind'/>")

Example 38. Script Syntax not supported HTTP error

HTTP/1.1 404 Not Found
Content-Length: 0

18.2 Changes to the Request Syntax

Clients MUST make the following changes to convert their requests to Script Syntax:

  1. Certain octets within the UTF-8 encoded <body/> element SHOULD be replaced according to the rules for escaping octets within URIs defined by RFC 3986 [29]. Therefore all octets except those representing 7-bit alphanumeric characters or the characters -._~!$&'()*+,;=:@/? should be substituted with a character triplet, consisting of the percent character "%" followed by the two hexadecimal digits that represent the value of the octet.

  2. A '?' character and the URI-encoded <body/> element MUST be appended to the URI at which the connection manager is operating within its server.

  3. The resulting URI MUST be sent to the connection manager within an HTTP GET request.

  4. Include extra HTTP headers to prevent request/response caching or storage by any intermediary.

Note: All whitespace between "GET " and " HTTP/1.1" in the HTTP GET header lines in the following two examples is included only to improve readability. In practice there MUST be no whitespace.

Example 39. Requesting a BOSH session in Script Syntax

GET /webclient?%3Cbody%20content='text/xml;%20charset=utf-8'%20
    hold='1'%20rid='1573741820'%20to='jabber.org'%20
    route='xmpp:jabber.org:9999'%20secure='true'%20ver='1.6'%20
    wait='60'%20xml:lang='en'%20
    xmlns='http://jabber.org/protocol/httpbind'/%3E
    HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0

Example 40. Transmitting stanzas in Script Syntax

GET /webclient?%3Cbody%20rid='1249243562'%20sid='SomeSID'%20
    xmlns='http://jabber.org/protocol/httpbind'%3E%3C
    message%20to='friend@example.com'%20xmlns='jabber:client'%3E%3C
    body%3EI%20said%20%22Hi!%22%3C/body%3E%3C/message%3E%3C/body%3E
    HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0

Although RFC 2616 does not limit the length of HTTP URIs, the runtime environment of the client might restrict the length of the URI that it can include in each GET request. [30] In these cases the client MUST reduce the content of the <body/> element accordingly and send the remaining content in subsequent HTTP GET requests wrapped in new <body/> elements (with incremented 'rid' attributes). This is possible since, unlike Pure Syntax, with Script Syntax the connection manager MUST treat the string of characters between the opening and closing <body> tags of each request as part of an octet stream instead of as a set of complete XML stanzas. The content of any one <body/> element MUST NOT be parsed in isolation from the rest of the stream.

18.3 Changes to the Response Syntax

Connection managers MUST make the following changes to convert their responses to Script Syntax:

  1. Certain characters within the <body/> element MUST be replaced according to the rules for escaping characters within strings defined by ECMAScript. The necessary substitutions are summarised in the table below.

    Table 4: Character Substitutions

    CharacterUnicode Code Point ValueEscape sequence
    "U+0022\"
    Line Feed (New Line)U+000A\n
    Carriage ReturnU+000D\r
    Line SeparatorU+2028\u2028
    Paragraph SeparatorU+2029\u2029
    \U+005C\\

    Each Unicode format-control character (i.e., the characters in category "Cf" in the Unicode Character Database, e.g., LEFT-TO-RIGHT MARK or RIGHT-TO-LEFT MARK) MUST also be substituted by its Unicode escape sequence (e.g. \u200e or \u200f).

  2. The following eight characters MUST be prepended to the <body/> element:

    _BOSH_("

  3. The following two characters MUST be appended to the <body/> element:

    ")

  4. If the client request does not possess a 'content' attribute, then the HTTP Content-Type header of responses MUST be either "text/javascript; charset=utf-8" or "application/x-javascript; charset=utf-8".

  5. Include extra HTTP headers to prevent caching or storage by any intermediary.

Note: All line breaks in the bodies of the HTTP responses in the following two examples are included only to improve readability. In practice there MUST be no line breaks.

Example 41. Session creation response in Script Syntax

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=utf-8
Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 233

_BOSH_("<body wait='60' inactivity='30' polling='5' requests='2' hold='1'
        ack='1573741820' accept='deflate,gzip' maxpause='120' sid='SomeSID'
        charsets='ISO_8859-1 ISO-2022-JP' ver='1.6' from='jabber.org'
        secure='true' xmlns='http://jabber.org/protocol/httpbind'/>")
    

Example 42. Receiving stanzas in Script Syntax

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=utf-8
Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 212

_BOSH_("<body rid='1249243562' sid='SomeSID'
        xmlns='http://jabber.org/protocol/httpbind'>\n
        <message to='contact@example.com' xmlns='jabber:client'>\n
        <body>I said \"Hi!\"</body>\n</message>\n</body>")
      

Note: As with Pure Syntax, each <body/> element sent to the client MUST encapsulate zero or more complete XML stanzas.

19. Security Considerations

19.1 Encryption

All communications SHOULD occur over encrypted HTTP connections. Negotiation of encryption between the client and the connection manager SHOULD occur at the transport layer or the HTTP layer, not the application layer; such negotiation SHOULD follow the HTTP/SSL protocol defined in SSL [31], it MAY follow the HTTP/TLS protocol defined in RFC 2818 [32] or the TLS Within HTTP protocol defined in RFC 2817 [33].

If the HTTP connection used to send the initial session request is encrypted, then all the other HTTP connections used within the session MUST also be encrypted. Furthermore, if authentication certificates are exchanged when establishing the encrypted connection that is used to send the initial session request, then the client and/or connection manager SHOULD ensure that the same authentication certificates are employed for all subsequent connections used by the session. Once such a 'secure session' has been established:

In cases where the connection manager acts as a 'translating proxy' independent of the server, it creates another security vulnerability in addition to those on the servers. It is RECOMMENDED that clients ensure the security of stanzas sent through the connection manager (and servers) in both directions by encrypting them end-to-end (e.g., by establishing Encrypted Session Negotiation [34]).

19.2 Unpredictable SID and RID

The session identifier (SID) and initial request identifier (RID) are security-critical and therefore MUST be both unpredictable and nonrepeating (see RFC 1750 [35] for recommendations regarding randomness of SIDs and initial RIDs for security purposes).

19.3 Script Syntax

To avoid the storage of private communications by third parties, when using the alternative Script Syntax connection managers MUST (and clients SHOULD) include all the appropriate HTTP/1.0 and/or HTTP/1.1 headers necessary to ensure as far as possible that no request or response will ever be cached or stored by any intermediary.

The alternative Script Syntax returns code for the client to execute. This code is typically executed immediately without any validation and with the same rights as the code of the client itself. This vulnerability could be exploited to steal passwords and private keys, or to fabricate messages sent from and received by the client, or to forward or modify priviledged information on the servers to which the client has access, or to interfere with any aspect of the client's functionality - limited only by the extent of the runtime environment ("sandbox"), by the extent that naive users may be tricked into doing things outside that environment, and by the attacker's fertile imagination. Therefore, although the client could use Script Syntax with any connection manager on the network, in practice it MUST take care to employ it only with connection managers that the client's user trusts (as much as the server from which the client was downloaded). To prevent a-man-in-the-middle from manipulating the code clients SHOULD only use Script Syntax over encrypted connections (see above). If the client was downloaded over an encrypted connection then it MUST NOT use Script Syntax over connections that are not encrypted.

20. IANA Considerations

This document requires no interaction with the Internet Assigned Numbers Authority (IANA) [36].

21. XMPP Registrar Considerations

21.1 Protocol Namespaces

The XMPP Registrar [37] includes 'http://jabber.org/protocol/httpbind' in its registry of protocol namespaces.

22. XML Schema

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    xmlns:stream='http://etherx.jabber.org/streams'
    targetNamespace='http://jabber.org/protocol/httpbind'
    xmlns='http://jabber.org/protocol/httpbind'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0124: http://www.xmpp.org/extensions/xep-0124.html
    </xs:documentation>
  </xs:annotation>

  <xs:element name='body'>
    <xs:complexType>
      <xs:choice>
        <xs:any namespace='##any'
                minOccurs='0'
                maxOccurs='unbounded'
                processContents='lax'/>
      </xs:choice>
      <xs:attribute name='accept' type='xs:string' use='optional'/>
      <xs:attribute name='ack' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='authid' type='xs:string' use='optional'/>
      <xs:attribute name='charsets' type='xs:NMTOKENS' use='optional'/>
      <xs:attribute name='condition' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='host-gone'/>
            <xs:enumeration value='host-unknown'/>
            <xs:enumeration value='improper-addressing'/>
            <xs:enumeration value='internal-server-error'/>
            <xs:enumeration value='remote-connection-failed'/>
            <xs:enumeration value='remote-stream-error'/>
            <xs:enumeration value='see-other-uri'/>
            <xs:enumeration value='system-shutdown'/>
            <xs:enumeration value='undefined-condition'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='content' type='xs:string' use='optional'/>
      <xs:attribute name='from' type='xs:string' use='optional'/>
      <xs:attribute name='hold' type='xs:byte' use='optional'/>
      <xs:attribute name='inactivity' type='xs:short' use='optional'/>
      <xs:attribute name='key' type='xs:string' use='optional'/>
      <xs:attribute name='maxpause' type='xs:short' use='optional'/>
      <xs:attribute name='newkey' type='xs:string' use='optional'/>
      <xs:attribute name='pause' type='xs:short' use='optional'/>
      <xs:attribute name='polling' type='xs:short' use='optional'/>
      <xs:attribute name='report' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='requests' type='xs:byte' use='optional'/>
      <xs:attribute name='rid' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='route' type='xs:string' use='optional'/>
      <xs:attribute name='secure' type='xs:boolean' use='optional' default='false'/>
      <xs:attribute name='sid' type='xs:string' use='optional'/>
      <xs:attribute name='stream' type='xs:string' use='optional'/>
      <xs:attribute name='time' type='xs:short' use='optional'/>
      <xs:attribute name='to' type='xs:string' use='optional'/>
      <xs:attribute name='type' type='xs:string' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='error'/>
            <xs:enumeration value='terminate'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='ver' type='xs:string' use='optional'/>
      <xs:attribute name='wait' type='xs:short' use='optional'/>
      <xs:attribute name='xml:lang' type='xs:string' use='optional'/>
      <xs:anyAttribute namespace='##any' processContents='lax'/>
    </xs:complexType>
  </xs:element>

</xs:schema>
    

Notes

1. RFC 793: Transmission Control Protocol <http://tools.ietf.org/html/rfc0793>.

2. Enabling communications via RFC 2965 [3] is sub-optimal since several significant computing platforms provide only limited access to underlying HTTP requests/responses; worse, some platforms hide or remove cookie-related headers.

3. RFC 2965: HTTP State Management Mechanism <http://tools.ietf.org/html/rfc2965>.

4. RFC 1945: Hypertext Transfer Protocol -- HTTP/1.0 <http://tools.ietf.org/html/rfc1945>.

5. RFC 2616: Hypertext Transport Protocol -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.

6. XEP-0025: Jabber HTTP Polling <http://www.xmpp.org/extensions/xep-0025.html>.

7. RFC 3920: Extensible Messaging and Presence Protocol (XMPP): Core <http://tools.ietf.org/html/rfc3920>.

8. XEP-0206: XMPP Over BOSH <http://www.xmpp.org/extensions/xep-0206.html>.

9. In order to reduce network congestion, RFC 2616 recommends that clients SHOULD NOT keep more than two HTTP connections to the same HTTP server open at the same time. Clients running in constrained enviroments typically have no choice but to abide by that recommendation.

10. If there is no traffic other than the "pings" then bandwidth consumption will be double that of a TCP connection (although double nothing is still nothing). If data is sent in large packets then bandwidth consumption will be almost identical.

11. Extensible Markup Language (XML) 1.0 (Fourth Edition) <http://www.w3.org/TR/REC-xml/>.

12. Namespaces in XML <http://www.w3.org/TR/REC-xml-names/>.

13. RFC 4627: The application/json Media Type for JavaScript Object Notation (JSON) <http://tools.ietf.org/html/rfc4627>.

14. Extensible Markup Language (XML) 1.0 (Fourth Edition) <http://www.w3.org/TR/REC-xml/>.

15. Although the syntax of the 'route' attribute bears a superficial resemblance to a URI or IRI, it is not a URI/IRI and MUST NOT be processed in accordance with the rules specified in RFC 3986, RFC 3987, or draft-saintandre-xmpp-iri.

16. XML Schema Part 2: Datatypes <http://www.w3.org/TR/xmlschema-2/>.

17. In accordance with Section 3.2.2.1 of XML Schema Part 2: Datatypes, the allowable lexical representations for the xs:boolean datatype are the strings "0" and "false" for the concept 'false' and the strings "1" and "true" for the concept 'true'; implementations MUST support both styles of lexical representation.

18. Each character set name (or character encoding name -- we use the terms interchangeably) SHOULD be of type NMTOKEN, where the names are separated by the white space character #x20, resulting in a tokenized attribute type of NMTOKENS (see Section 3.3.1 of XML 1.0 [19]). Strictly speaking, the Character Sets registry maintained by the Internet Assigned Numbers Authority (see <http://www.iana.org/assignments/character-sets>) allows a character set name to contain any printable US-ASCII character, which might include characters not allowed by the NMTOKEN construction of XML 1.0; however, the only existing character set name which includes such a character is "NF_Z_62-010_(1973)".

19. Extensible Markup Language (XML) 1.0 (Fourth Edition) <http://www.w3.org/TR/REC-xml/>.

20. 9007199254740991 is 253-1. Some weakly typed languages use IEEE Standard 754 Doubles to represent all numbers. These Doubles cannot represent integers above 253 accurately.

21. RFC 3174: US Secure Hash Algorithm 1 (SHA1) <http://tools.ietf.org/html/rfc3174>.

22. Therefore a client and a connection manager will be compatible even if one or the other offers no support for multi-stream sessions.

23. The 'rid' attribute is always incremented normally without reference to any 'stream' attribute.

24. This helps to ensure backwards-compatibility with older implementations.

25. Each HTTP response MUST belong to the same session as the request that triggered it, but not necessarily to the same stream.

26. The broadcast stanzas may be of any type.

27. This security hole is unlikely to be closed by browser vendors since it facilitates online advertising.

28. Standard ECMA-262: ECMAScript Language Specification 3rd edition <http://www.ecma-international.org/publications/standards/Ecma-262.htm>.

29. RFC 3986: Uniform Resource Identifiers (URI): Generic Syntax <http://tools.ietf.org/html/rfc3986>.

30. Internet Explorer versions 4.0 thru 7.0 have a maximum path length of 2048 characters and a maximum URL length of 2083 characters. Other popular browsers appear to have no limit.

31. SSL V3.0 <http://wp.netscape.com/eng/ssl3/draft302.txt>.

32. RFC 2818: HTTP Over TLS <http://tools.ietf.org/html/rfc2818>.

33. RFC 2817: Upgrading to TLS Within HTTP/1.1 <http://tools.ietf.org/html/rfc2817>.

34. XEP-0116: Encrypted Session Negotiation <http://www.xmpp.org/extensions/xep-0116.html>.

35. RFC 1750: Randomness Recommendations for Security <http://tools.ietf.org/html/rfc1750>.

36. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.

37. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <http://www.xmpp.org/registrar/>.


Revision History

Version 1.6 (2007-02-21)

Multiple clarifications and restructuring without changes to protocol itself; changed title to BOSH; added section that fully explores the technique underlying the protocol; separated XMPP-specific features into new XEP-0206; added optional new Script Syntax and session pauses; added Acknowledgements section; added from and ver attributes; added hold attribute to session creation response; clarified polling too-frequently error; recommended clients use HTTP Pipelining.

(ip)

Version 1.5 (2006-04-28)

Added optional Multiple Streams section; added security considerations about encrypted HTTP connections; recommended use of SSL rather than HTTP over TLS; specified that request ID values must not exceed 9007199254740991; corrected datatypes of inactivity, polling, rid, and wait attributes in the schema; added <any/> and <anyAttribute/> elements to schema to optionally support non-XMPP XML elements and attributes; deprecated HTTP error codes in favor of new terminal binding conditions.

(ip/psa)

Version 1.4 (2005-12-14)

Modified syntax of route attribute to be proto:host:port rather than XMPP URI/IRI.

(psa)

Version 1.3 (2005-11-02)

Corrected stream:features namespace and the Recoverable Binding Conditions section; recommended that connection manager shall return secure attribute to client; recommended end-to-end encryption through proxy connection managers.

(ip)

Version 1.2 (2005-06-16)

Specified optional use of route and secure attributes in session request. Minor correction: the stream features element should be included in the response that contains the authid attribute (this is not necessarily the session creation response).

(ip)

Version 1.1 (2005-06-02)

Specified optional use of HTTP Accept-Encoding and Content-Encoding headers for compression at HTTP binding level.

(ip)

Version 1.0 (2005-03-03)

Per a vote of the Jabber Council, advanced status to Draft.

(psa)

Version 0.10 (2004-11-08)

Changed HTTP 401 errors to HTTP 404.

(ip)

Version 0.9 (2004-10-26)

Added charset attribute.

(ip/psa)

Version 0.8 (2004-10-26)

Specified that wait attribute must be included in the session creation response.

(ip)

Version 0.7 (2004-08-12)

Defined appropriate XMPP stanza error conditions.

(psa/ip)

Version 0.6 (2004-07-19)

Added xml:lang attribute to the session request; added recoverable binding error conditions.

(ip)

Version 0.5 (2004-05-07)

Protocol refactored to enable simultaneous requests (request identifier attribute, wait attribute, hold attribute, requests attribute) and recovery of broken connections; added content attribute; removed all wrapper types except 'terminate'; updated error handling; made key mechanism optional (should use SSL/TLS instead).

(ip/psa)

Version 0.4 (2004-02-23)

Fixed typos; removed "resource-constraint" binding error; added HTTP 403 error to table.

(psa/ip)

Version 0.3 (2004-02-19)

Added 'authid' attribute to enable communication of XMPP stream ID (used in digest authentication); specified that Content-Types other than "text/xml" are allowed to support older HTTP clients; specified business rule for connection manager queueing of client requests; changed <packet/> to <body/> to support older HTTP clients; changed 'to' attribute on initialization element from MAY to SHOULD; recommended inclusion of unavailable presence in termination element sent from client; described architectural assumptions; specified binding-specific error handling.

(psa/ip)

Version 0.2 (2004-01-13)

Added 'to' attribute on the initialization element; specified that 'text/html' is allowable for backwards-compatibility.

(dss/psa/ip)

Version 0.1 (2003-11-06)

Initial version.

(dss/psa)

END