mirror of https://github.com/moparisthebest/xeps
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2012 lines
103 KiB
2012 lines
103 KiB
<?xml version='1.0' encoding='UTF-8'?> |
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [ |
|
<!ENTITY % ents SYSTEM 'xep.ent'> |
|
%ents; |
|
]> |
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?> |
|
<xep> |
|
<header> |
|
<title>HTTP over XMPP transport</title> |
|
<abstract>This specification defines how XMPP can be used to transport HTTP communication over peer-to-peer networks.</abstract> |
|
&LEGALNOTICE; |
|
<number>0332</number> |
|
<status>Deferred</status> |
|
<lastcall>2014-10-21</lastcall> |
|
<type>Standards Track</type> |
|
<sig>Standards</sig> |
|
<approver>Council</approver> |
|
<dependencies> |
|
<spec>XMPP Core</spec> |
|
<spec>XEP-0001</spec> |
|
<spec>XEP-0030</spec> |
|
<spec>XEP-0047</spec> |
|
<spec>XEP-0131</spec> |
|
<spec>XEP-0137</spec> |
|
<spec>XEP-0166</spec> |
|
</dependencies> |
|
<supersedes/> |
|
<supersededby/> |
|
<shortname>NOT_YET_ASSIGNED</shortname> |
|
&peterwaher; |
|
<revision> |
|
<version>0.5.1</version> |
|
<date>2020-03-31</date> |
|
<initials>@sonnyp</initials> |
|
<remark>Fix spelling error</remark> |
|
</revision> |
|
<revision> |
|
<version>0.5</version> |
|
<date>2017-09-11</date> |
|
<initials>XEP Editor (jwi)</initials> |
|
<remark>Defer due to lack of activity.</remark> |
|
</revision> |
|
<revision> |
|
<version>0.4</version> |
|
<date>2015-11-09</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Updated contact information.</p> |
|
<p>Updated example JIDs to example.org</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.3</version> |
|
<date>2014-08-12</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>A sequence number have been added to chunks, to allow chunked service to work over servers that do not maintain message order.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.2</version> |
|
<date>2014-07-07</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Updated invalid links.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.1</version> |
|
<date>2013-07-11</date> |
|
<initials>psa</initials> |
|
<remark><p>Initial published version approved by the XMPP Council.</p></remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.7</version> |
|
<date>2013-07-09</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Added remarks for the xml encoding to clarify the need to avoid creating invalid XMPP.</p> |
|
<p>Clarification added regarding to base64 content size when using schema-aware EXI compression.</p> |
|
<p>The name of the new proposed URI scheme has been changed from xmpp to httpx.</p> |
|
<p>An URI Scheme Registration Template has been added, as per BCP 35.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.6</version> |
|
<date>2013-06-17</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Removed the streamBase64 transfer mechanism and replaced it with In-band bytestreams (IBB).</p> |
|
<p>Created new examples, avoiding re-use of known public examples.</p> |
|
<p>Extended the descriptions of the different transfer mechanisms.</p> |
|
<p>Ability to state capabilities of the client in the request.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.5</version> |
|
<date>2013-05-22</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Changed IQ stanza type from 'get' to 'set' for all HTTP methods.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.4</version> |
|
<date>2013-05-14</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Updated format of encoding table, and made it into a definition list.</p> |
|
<p>Language corrections.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.3</version> |
|
<date>2013-05-10</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Added more information about chunking.</p> |
|
<p>Added implementation notes regarding bandwidth and stanza size limitations in XMPP Servers.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.2</version> |
|
<date>2013-05-08</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>Added support for XEP-0131, Stanza Headers and Internet Metadata.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.1</version> |
|
<date>2013-05-05</date> |
|
<initials>pw</initials> |
|
<remark> |
|
<p>First draft.</p> |
|
</remark> |
|
</revision> |
|
</header> |
|
<section1 topic='Introduction' anchor='intro'> |
|
<p> |
|
Many documents have been written on how to transport XMPP datagrams using HTTP. The motivation behind such solutions has often been to be able to use XMPP in |
|
scripting languages such as JavaScript running in web browsers. |
|
</p> |
|
<p> |
|
But up to this point very little has been written about the reverse: How to transport HTTP methods and HTTP responses over an XMPP-based peer-to-peer network. |
|
Here, the motivation is as follows: There are multitudes of applications and APIs written that are based on HTTP over TCP as the basic communication transport protocol. |
|
As these are moving closer and closer to the users, problems arise when the users want to protect their data and services using firewalls. Even though there are methods |
|
today to open up firewalls manually or automatically permit communication with such devices and applications, you still open up the application for everybody. This |
|
rises the need for more advanced security measures which is sometimes difficult to implement using HTTP. |
|
</p> |
|
<p> |
|
The XMPP protocol however does not have the same problems as HTTP in these regards. It's a peer-to-peer protocol naturally allowing communication with applications |
|
and devices behind firewalls. It also includes advanced user authentication and authorization which makes it easier to make sure unauthorized access to private |
|
content is prevented. |
|
</p> |
|
<p> |
|
Furthermore, with the advent of semantic web technologies and its use in web 3.0 and Internet of Things applications, such applications move even more rapidly into |
|
the private spheres of the users, where security and privacy is of paramount importance, it is necessary to use more secure transport protocols than HTTP over TCP. |
|
</p> |
|
<p> |
|
There are many different types of HTTP-based communication that one would like to be able to transport over XMPP. A non-exhaustive list can include: |
|
</p> |
|
<ul> |
|
<li>Web Content like pages, images, files, etc.</li> |
|
<li>Web Forms.</li> |
|
<li>Web Services (SOAP, REST, etc.)</li> |
|
<li>Semantic Web Resources (RDF, Turtle, etc.)</li> |
|
<li>Federated SPARQL queries (SQL-type query language for the semantic web, or web 3.0)</li> |
|
<li>Streamed multi-media content in UPnP and DLNA networks.</li> |
|
</ul> |
|
<p> |
|
Instead of trying to figure out all possible things transportable over HTTP and make them transportable over XMPP, this document ignores the type of content transported, |
|
and instead focuses on encoding and decoding the original HTTP requests and responses, building an HTTP tunnel over an existing XMPP connection. It would enable |
|
existing applications to work seamlessly over XMPP if browsers and web services supported this extension (like displaying your home control application on your phone |
|
when you are at work), without the need to update the myriad of existing applications. It would also permit federated SPARQL queries in personal networks with the added |
|
benefit of being able to control who can talk to who (or what can talk to what) through established friendship relationships. |
|
</p> |
|
<p> |
|
Previous extensions handling different aspects of XMPP working together with HTTP: |
|
</p> |
|
<ul> |
|
<li> |
|
&xep0070;: This specification handles client authentication of resources, where there are three parties: HTTP Client <-> HTTP Server/XMPP Client <-> XMPP Server. |
|
Here HTTP Client authentication to resources on the HTTP Server is made by a third party, an XMPP Server. |
|
</li> |
|
<li> |
|
&xep0072;: This specification handles execution of SOAP-based web services specifically. This specification has some benefits regarding to Web Service calls over XMPP, |
|
but is only one example of all types of HTTP-based communication one would desire to transport over XMPP. |
|
</li> |
|
<li> |
|
&xep0124;: This specification handles XMPP-based communication over HTTP sessions (BOSH), allowing for instance, XMPP communication in JavaScript using the |
|
XML HTTP Request object. This is in some way the reverse of what this document proposes to do. |
|
</li> |
|
<li> |
|
&xep0131;: While not directly related to HTTP, it is used to transport headers in the form of collections of key-value pairs, exactly as is done in HTTP. The format |
|
for encoding headers into XMP defined by this XEP will be re-used in this XEP. |
|
</li> |
|
<li> |
|
&xep0147;: This informational specification proposes ways to define XMPP-actions using URL's. The xmpp URI scheme is formally defined in &rfc5122;. |
|
This document will propose a different URI scheme for HTTP-based resources over an XMPP transport: httpx. |
|
</li> |
|
</ul> |
|
</section1> |
|
<section1 topic='Requirements' anchor='reqs'> |
|
<p> |
|
This document presupposes the server already has a web server (HTTP Server) implementation, and that it hosts content through it, content which can be both |
|
dynamic (i.e. generated) or static (e.g. files) in nature. Content, which it wants to |
|
publish to XMPP clients as well as HTTP clients. It also presupposes that the client is aware of HTTP semantics and MIME encoding. |
|
</p> |
|
</section1> |
|
<section1 topic='Glossary' anchor='glossary'> |
|
<p>The following table lists common terms and corresponding descriptions.</p> |
|
<dl> |
|
<di> |
|
<dt>HTTP</dt> |
|
<dd> |
|
Hyper Text Transfer Protocol. Version 1.1 of HTTP is described in RFC 2616 <note> |
|
RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 <<link url='http://tools.ietf.org/html/rfc2616'>http://tools.ietf.org/html/rfc2616</link>> |
|
</note>. The PATCH method is described in RFC 5789 <note> |
|
RFC 5789: PATCH Method for HTTP <<link url='http://tools.ietf.org/html/rfc5789'>http://tools.ietf.org/html/rfc5789</link>> |
|
</note> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>HTTP Client</dt> |
|
<dd>An HTTP Client is the initiator of an HTTP Request.</dd> |
|
</di> |
|
<di> |
|
<dt>HTTP Method</dt> |
|
<dd> |
|
HTTP Methods are: <strong>OPTIONS</strong>, <strong>GET</strong>, <strong>HEAD</strong>, <strong>POST</strong>, |
|
<strong>PUT</strong>, <strong>DELETE</strong>, <strong>TRACE</strong> and <strong>PATCH</strong>. The HTTP |
|
Method CONNECT is not supported by this specification. |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>HTTP Request</dt> |
|
<dd>An HTTP Request consists of a HTTP Method, version information, headers and optional body.</dd> |
|
</di> |
|
<di> |
|
<dt>HTTP Resource</dt> |
|
<dd>A resource on an HTTP Server identified by a path. Each path begins with a separator character (/).</dd> |
|
</di> |
|
<di> |
|
<dt>HTTP Response</dt> |
|
<dd>An HTTP Response consists of a status code, optional status message, headers and optional body.</dd> |
|
</di> |
|
<di> |
|
<dt>HTTP Server</dt> |
|
<dd>An HTTP Server responds to HTTP Client requests.</dd> |
|
</di> |
|
<di> |
|
<dt>Web Server</dt> |
|
<dd>Used synonymously with HTTP Server.</dd> |
|
</di> |
|
</dl> |
|
</section1> |
|
<section1 topic='Use Cases' anchor='usecases'> |
|
<p> |
|
All HTTP communication is done using the <strong>Request</strong>/<strong>Response</strong> paradigm. Each HTTP Request is made sending an <strong>iq</strong>-stanza |
|
containing a <strong>req</strong> element to the server. Each <strong>iq</strong>-stanza sent is of type <strong>set</strong>. |
|
</p> |
|
<p> |
|
When the server responds, it does so by sending an <strong>iq</strong>-stanza response (type <strong>result</strong>) back to the client containing a <strong>resp</strong> |
|
element. Since responses are asynchronous, and since multiple requests may be active at the same time, responses may be returned in a different order than the in which the |
|
original requests were made. |
|
</p> |
|
<p> |
|
Requests or responses containing data must also consider how this data should be encoded within the XML telegram. Normally in HTTP, content and headers are separated |
|
by a blank line, and the transfer of the content is made in the same stream. Specific HTTP headers are used to define how the content is transferred and encoded within |
|
the stream (Content-Type, Content-Length, Content-Encoding, Content-Transfer-Encoding). This approach is not possible if the response is to be embedded in an XML telegram, |
|
since it can interfere with the encoding of the encompassing XML. |
|
</p> |
|
<p> |
|
To solve this, this document specifies additional data transfer mechanisms that are compatible with the XMPP protocol. The normal HTTP-based content transfer headers will |
|
still be transported, but do not affect the content encoding used in the XMPP transport. The following content encoding methods are available: |
|
</p> |
|
<dl> |
|
<di> |
|
<dt>text</dt> |
|
<dd> |
|
<p> |
|
Normal text content. The text is encoded as text within XML, using the same encoding used by the XML stream. XML escape characters (<, > and &) |
|
are escaped using the normal &lt;, &gt; and &amp; character escape sequences. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>xml</dt> |
|
<dd> |
|
<p> |
|
Xml content embedded in the XML telegram. Note however, that any processing instructions or XML version statements must be avoided, since it may cause |
|
the XML stream to become invalid XML. If this is a problem, normal <strong>text</strong> encoding can be used as an alternative. The advantage of <strong>xml</strong> |
|
instead of <strong>text</strong> or <strong>base64</strong> encodings is when used in conjunction with EXI compression &xep0322;. EXI compression has the ability to |
|
compress XML efficiently. Text will not be compressed, unless response exists in internal string tables. Base-64 encoded data will be compressed so that the 33% |
|
size gain induced by the encoding is recaptured. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>base64</dt> |
|
<dd> |
|
<p> |
|
Base-64 encoded binary content. Can be used to easily embed binary content in the telegram. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>chunkedBase64</dt> |
|
<dd> |
|
<p> |
|
Chunked Base-64 encoded binary content. The content is not embedded in the telegram. Instead it is sent in chunks, using separate |
|
<strong>chunk</strong> messages to the client. Chunked transport can be used by the server when it doesn't know the size of the final result. |
|
Streaming content, i.e. content of infinite length, must use <strong>ibb</strong> or <strong>jingle</strong> transport types to transfer content. |
|
If the content consists of a file, <strong>sipub</strong> should be used. |
|
</p> |
|
<p> |
|
Chunked encoding is perfect for dynamic responses of moderate sizes, for instance for API method responses. The server does not know when the response |
|
is begun to be generated what the final size will be, but it will be most probably "manageable". Using the chunked transfer mechanism enables the |
|
server to start sending the content, minimizing the need for buffers, and at the same time minimizing the number of messages that needs to be sent, |
|
increasing throughput. |
|
</p> |
|
<p> |
|
The client can limit the maximum chunk size to be used by the server, using the <strong>maxChunkSize</strong> attribute in the request. The chunk |
|
size can be set to a value between 256 and 65536. If not provided in the request, the server chooses an appropriate value. Note that chunks can |
|
be sent containing a smaller amount of bytes than the maximum chunk size provided in the request. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>sipub</dt> |
|
<dd> |
|
<p> |
|
The sender might deem the content to be too large for sending embedded in the XMPP telegram. To circumnavigate this, the sender publishes |
|
the content as a file using &xep0137; (Publishing Stream Initiation Requests), instead of embedding the content directly. This might be the case for instance, when |
|
a client requests a video resource, without using a ranged request. |
|
</p> |
|
<p> |
|
This transfer mechanism is of course the logical choice, if the content is already stored in a file on the server, and the size of the file |
|
is sufficiently large to merit the overhead of sipub. Smaller files can simply be returned using the <strong>text</strong>, <strong>xml</strong> |
|
or <strong>base64</strong> mechanisms. |
|
</p> |
|
<p> |
|
The client can disable the use of <strong>sipub</strong> by the server, by including a <strong>sipub='false'</strong> attribute in the request. |
|
<strong>sipub</strong> is enabled by default. On constrained devices with limited support for different XEP's, this can be a way to avoid the |
|
use of technologies not supported by the client. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>ibb</dt> |
|
<dd> |
|
<p> |
|
This option may be used to encode indefinite streams, like live audio or video streams (HLS, SHOUTcast, Motion JPeg web cams, etc). |
|
It uses &xep0047; to send the content over an in-band bytestream to the client. This option is not available in requests, only in responses. |
|
</p> |
|
<p> |
|
Streams must not use any of the above mechanisms. Only <strong>ibb</strong> and <strong>jingle</strong> mechanisms can be used. If the content |
|
represents multimedia <strong>jingle</strong> is preferrable, especially if different encodings are available. |
|
</p> |
|
<p> |
|
The client can disable the use of <strong>ibb</strong> by the server, by including a <strong>ibb='false'</strong> attribute in the request. |
|
<strong>ibb</strong> is enabled by default. On constrained devices with limited support for different XEP's, this can be a way to avoid the |
|
use of technologies not supported by the client. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>jingle</dt> |
|
<dd> |
|
<p> |
|
For demanding multi-media streams alternative methods to transport streaming rather than embedded into the XMPP stream may be |
|
required. Even though the <strong>ibb</strong> method may be sufficient to stream a low-resolution web cam in the home, or listen to a microphone |
|
or a radio station, it is probably badly suited for high-resolution video streams with multiple video angles and audio channels. If such content is accessed |
|
and streamed, the server can negotiate a different way to stream the content using &xep0166;. |
|
</p> |
|
<p> |
|
The client can disable the use of <strong>ingle</strong> by the server, by including a <strong>jingle='false'</strong> attribute in the request. |
|
<strong>jingle</strong> is enabled by default. On constrained devices with limited support for different XEP's, this can be a way to avoid the |
|
use of technologies not supported by the client. |
|
</p> |
|
</dd> |
|
</di> |
|
</dl> |
|
<p> |
|
<strong>Note:</strong> Content encoded using <strong>chunkedBase64</strong> encoding method can be terminated, either by the receptor going off-line, or by |
|
sending a <strong>close</strong> command to the sender. The transfer methods <strong>sipub</strong>, <strong>ibb</strong> and <strong>jingle</strong> have |
|
their own mechanisms for aborting content transfer. |
|
</p> |
|
<section2 topic='HTTP Methods'> |
|
<p> |
|
The following use cases show how different HTTP methods may work when transported over XMPP. To facilitate the readability in these examples, |
|
simple text or xml results are shown. |
|
</p> |
|
<section3 topic='OPTIONS' anchor='OPTIONS'> |
|
<p> |
|
This section shows an example of an OPTIONS method call. OPTIONS is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.2'>§9.2 in RFC 2616</link>. |
|
</p> |
|
<example caption='OPTIONS'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='1'> |
|
<req xmlns='urn:xmpp:http' method='OPTIONS' resource='*' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='1'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 13:52:10 GMT-4</header> |
|
<header name='Allow'>OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE</header> |
|
<header name='Content-Length'>0</header> |
|
</headers> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='GET' anchor='GET'> |
|
<p> |
|
This section shows an example of a GET method call. GET is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.3'>§9.3 in RFC 2616</link>. |
|
</p> |
|
<example caption='GET'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='2'> |
|
<req xmlns='urn:xmpp:http' method='GET' resource='/rdf/xep' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='2'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:39:54GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>text/turtle</header> |
|
<header name='Content-Length'>...</header> |
|
<header name='Connection'>Close</header> |
|
</headers> |
|
<data> |
|
<text>@prefix dc: <http://purl.org/dc/elements/1.1/>. |
|
@base <http://example.org/>. |
|
|
|
<xep> dc:title "HTTP over XMPP"; |
|
dc:creator <PeterWaher>; |
|
dc:publisher <XSF>.</text> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
<p> |
|
<strong>Note:</strong> The XMPP/HTTP bridge at the server only transmits headers literally as they are reported, as if it was normal HTTP over TCP |
|
that was used. In the HTTP over XMPP case, connections are not handled in the same way, and so the "Connection: Close" header has no meaning in this |
|
case. For more information about connection handling in the HTTP over XMPP case, see the section on <link url='#httpconnections'>Connection Handling</link>. |
|
</p> |
|
</section3> |
|
<section3 topic='HEAD' anchor='HEAD'> |
|
<p> |
|
This section shows an example of a HEAD method call. HEAD is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.4'>§9.4 in RFC 2616</link>. |
|
</p> |
|
<example caption='HEAD'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='3'> |
|
<req xmlns='urn:xmpp:http' method='HEAD' resource='/video/video1.m4' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='3'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:57:12GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>video/mp4</header> |
|
<header name='Content-Length'>12345678</header> |
|
</headers> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='POST' anchor='POST'> |
|
<p> |
|
This section shows an example of a POST method call. POST is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.5'>§9.5 in RFC 2616</link>. |
|
</p> |
|
<example caption='POST'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='4'> |
|
<req xmlns='urn:xmpp:http' method='POST' resource='/sparql/?default-graph-uri=http%3A%2F%2Fexample.org%2Frdf/xep' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
<header name='User-agent'>Clayster HTTP/XMPP Client</header> |
|
<header name='Content-Type'>application/sparql-query</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<text>PREFIX dc: <http://purl.org/dc/elements/1.1/> |
|
BASE <http://example.org/> |
|
|
|
SELECT ?title ?creator ?publisher |
|
WHERE { ?x dc:title ?title . |
|
OPTIONAL { ?x dc:creator ?creator } . |
|
}</text> |
|
</data> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='4'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 17:09:34-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>application/sparql-results+xml</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<sparql xmlns="http://www.w3.org/2005/sparql-results#"> |
|
<head> |
|
<variable name="title"/> |
|
<variable name="creator"/> |
|
</head> |
|
<results> |
|
<result> |
|
<binding name="title"> |
|
<literal>HTTP over XMPP</literal> |
|
</binding> |
|
<binding name="creator"> |
|
<uri>http://example.org/PeterWaher</uri> |
|
</binding> |
|
</result> |
|
</results> |
|
</sparql> |
|
</xml> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
<p> |
|
<strong>Note:</strong> If using <strong>xml</strong> encoding of data, care has to be taken to avoid including the version and encoding information |
|
(<?xml version="1.0"?>) at the top of the document, otherwise the resulting XML will be invalid. Care has also to be taken to make sure that the |
|
generated XML is not invalid XMPP, even though it might be valid XML. This could happen for instance, if the XML contains illegal elements from the |
|
jabber:client namespace. If in doubt, use another encoding mechanism. |
|
</p> |
|
</section3> |
|
<section3 topic='PUT' anchor='PUT'> |
|
<p> |
|
This section shows an example of a PUT method call. PUT is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.6'>§9.6 in RFC 2616</link>. |
|
</p> |
|
<example caption='PUT'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='5'> |
|
<req xmlns='urn:xmpp:http' method='PUT' resource='/index.html' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
<header name='Content-Type'>text/html</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<text><html><header/><body><p>Beautiful home page.</p></body></html></text> |
|
</data> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='5'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='204' statusMessage='No Content'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 17:40:41GMT-4</header> |
|
<header name='Content-Length'>0</header> |
|
</headers> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='DELETE' anchor='DELETE'> |
|
<p> |
|
This section shows an example of a DELETE method call. DELETE is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.7'>§9.7 in RFC 2616</link>. |
|
</p> |
|
<example caption='DELETE'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='6'> |
|
<req xmlns='urn:xmpp:http' method='DELETE' resource='/index.html' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='6'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='403' statusMessage='Forbidden'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 17:46:07GMT-4</header> |
|
<header name='Content-Type'>text/plain</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<text>You're not allowed to change the home page!</text> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='TRACE' anchor='TRACE'> |
|
<p> |
|
This section shows an example of a TRACE method call. TRACE is described in <link url='http://tools.ietf.org/html/rfc2616#section-9.8'>§9.8 in RFC 2616</link>. |
|
</p> |
|
<example caption='TRACE'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='7'> |
|
<req xmlns='urn:xmpp:http' method='TRACE' resource='/rdf/ex1.turtle' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='7'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 17:55:10GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>message/http</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<text>GET /rdf/ex1.turtle HTTP/1.1 |
|
Host: example.org</text> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
<p> |
|
<strong>Note:</strong> The Trace command returns the request it received from the client by the server. Here, however, it is assumed that the request |
|
is made over HTTP/TCP, not HTTP/XMPP. Therefore, in this example, the XMPP layer has transformed the HTTP/XMPP request into an HTTP/TCP-looking |
|
request, which is returned as the response to the TRACE Method call. RFC 2616 is silent to the actual format of the TRACE response |
|
(MIME TYPE message/http), and TRACE is only used (if not disabled for security reasons) for debugging connections and routing via proxies. |
|
Therefore, a response returning the original XMPP request should also be accepted by the caller. |
|
</p> |
|
</section3> |
|
<section3 topic='PATCH' anchor='PATCH'> |
|
<p> |
|
This section shows an example of a PATCH method call. PATCH is described in <link url='http://tools.ietf.org/html/rfc5789'>RFC 5789</link>. |
|
</p> |
|
<example caption='PATCH'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='8'> |
|
<req xmlns='urn:xmpp:http' method='PATCH' resource='/file.txt' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>www.example.com</header> |
|
<header name='Content-Type'>application/example</header> |
|
<header name='If-Match'>e0023aa4e</header> |
|
<header name='Content-Length'>100</header> |
|
</headers> |
|
<data> |
|
[description of changes] |
|
</data> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='8'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='204' statusMessage='No Content'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Content-Location'>/file.txt</header> |
|
<header name='ETag'>e0023aa4e</header> |
|
</headers> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
</section2> |
|
<section2 topic='Encoding formats' anchor='encoding'> |
|
<p> |
|
In the following sub-sections, the different data encoding formats are discussed, each with corresponding examples to illustrate how they work. |
|
The interesting part of these examples is the <strong>data</strong> element and its contents. |
|
</p> |
|
<section3 topic='text'> |
|
<p> |
|
Text responses is a simple way to return text responses (i.e. any MIME Type starting with text/). Since the text is embedded into XML, the |
|
characters <, > and & need to be escaped to &lt;, &gt; and &amp; respectively. |
|
</p> |
|
<p> |
|
The following example shows how a TURTLE response, which is text-based, is returned using the <strong>text</strong> encoding: |
|
</p> |
|
<example caption='text'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='2'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:39:54GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>text/turtle</header> |
|
<header name='Content-Length'>...</header> |
|
<header name='Connection'>Close</header> |
|
</headers> |
|
<data> |
|
<text>@prefix dc: <http://purl.org/dc/elements/1.1/>. |
|
@base <http://example.org/>. |
|
|
|
<xep> dc:title "HTTP over XMPP"; |
|
dc:creator <PeterWaher>; |
|
dc:publisher <XSF>.</text> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='xml'> |
|
<p> |
|
XML is a convenient way to return XML embedded in the XMPP response. This can be suitable for MIME Types of the form <strong>.*/(.*[+])?xml</strong> |
|
(using regular expression to match them), like text/xml, application/soap+xml or application/sparql-results+xml. Care has to be taken however, since |
|
not all XML constructs can be embedded as content to an XML element without invalidating it, like the xml version and encoding declaration |
|
(<?xml version="1.0"?> as an example). Care has also to be taken to make sure that the generated XML is not invalid XMPP, even though it might |
|
be valid XML. This could happen for instance, if the XML contains illegal elements from the jabber:client namespace. |
|
</p> |
|
<p> |
|
If unsure how to handle XML responses using the <strong>xml</strong> encoding type, you can equally well use the <strong>text</strong> type, but |
|
encode the XML escape characters <, > and &, or use another encoding, like <strong>base64</strong>. |
|
</p> |
|
<p> |
|
The advantage of <strong>xml</strong> instead of <strong>text</strong> or <strong>base64</strong> encodings is when used in conjunction with |
|
<link url='http://xmpp.org/extensions/xep-0322.html'>EXI compression</link>. EXI compression has the ability to compress XML efficiently. |
|
Text will not be compressed, unless response exists in internal string tables. Base-64 encoded data will be compressed so that the 33% size |
|
gain induced by the encoding is recaptured. |
|
</p> |
|
<example caption='xml'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='4'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 17:09:34-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>application/sparql-results+xml</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<sparql xmlns="http://www.w3.org/2005/sparql-results#"> |
|
<head> |
|
<variable name="title"/> |
|
<variable name="creator"/> |
|
</head> |
|
<results> |
|
<result> |
|
<binding name="title"> |
|
<literal>HTTP over XMPP</literal> |
|
</binding> |
|
<binding name="creator"> |
|
<uri>http://example.org/PeterWaher</uri> |
|
</binding> |
|
</result> |
|
</results> |
|
</sparql> |
|
</xml> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='base64'> |
|
<p> |
|
Base-64 encoding is a simple way to encode content that is easily embedded into XML. Apart from the advantage of being easy to encode, |
|
it has the disadvantage to increase the size of the content by 33%, since it requires 4 bytes to encode 3 bytes of data. |
|
Care has to be taken not to send too large items using this encoding. |
|
</p> |
|
<p> |
|
<strong>Note:</strong> The actual size of the content being sent does not necessarily need to increase if this encoding method is used. |
|
If EXI compression is used at the same time, and it uses schema-aware compression, it will actually understand that the character set used |
|
to encode the data only uses 6 bits of information per character, and thus compresses the data back to its original size. |
|
</p> |
|
<p> |
|
The following example shows an image is returned using the <strong>base64</strong> encoding: |
|
</p> |
|
<example caption='base64'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='9'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:39:54GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>image/png</header> |
|
<header name='Content-Length'>221203</header> |
|
</headers> |
|
<data> |
|
<base64>iVBORw0KGgoAAAANSUhEUgAAASwAAAGQCAYAAAAUdV17AAAAAXNSR0 ... tVWJd+e+y1AAAAABJRU5ErkJggg==</base64> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='chunkedBase64'> |
|
<p> |
|
In HTTP, Chunked Transfer Encoding is used when the sender does not know the size of the content being sent, and to avoid having its buffers |
|
overflow, sends the content in chunks with a definite size. |
|
</p> |
|
<p> |
|
A similar method exists in the HTTP over XMPP transport: The <strong>chunkedBase64</strong> allows the sender to transmit the content in chunks. |
|
Every chunk is base-64 encoded. The stream of chunks are identified by a <strong>streamId</strong> parameter, since chunks from different responses |
|
may be transmitted at the same time. |
|
</p> |
|
<p> |
|
Another difference between normal chunked transport, and the <strong>chunkedBase64</strong> encoding, is that the size of chunks does not have to be |
|
predetermined. Chunks are naturally delimited and embedded in the XML stanza. The last chunk in a response must have the <strong>last</strong> |
|
attribute set to true. |
|
</p> |
|
<example caption='chunkedBase64'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='10'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 04 May 2013 13:43:12GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>image/png</header> |
|
<header name='Content-Length'>221203</header> |
|
</headers> |
|
<data> |
|
<chunkedBase64 streamId='Stream0001'/> |
|
</data> |
|
</resp> |
|
</iq> |
|
|
|
<message from='httpserver@example.org' |
|
to='httpclient@example.org/browser'> |
|
<chunk xmlns='urn:xmpp:http' streamId='Stream0001' nr='0'>iVBORw0KGgoAAAANSUhEUgAAASwAAAGQCAYAA ...</chunk> |
|
</message> |
|
|
|
... |
|
|
|
<message from='httpserver@example.org' |
|
to='httpclient@example.org/browser'> |
|
<chunk xmlns='urn:xmpp:http' streamId='Stream0001' nr='5' last='true'>... 2uPzi9u+tVWJd+e+y1AAAAABJRU5ErkJggg==</chunk> |
|
</message>]]> |
|
</example> |
|
<p> |
|
<strong>Note:</strong> Chunked encoding assumes the content to be finite. If content is infinite (i.e. for instance live streaming), |
|
the <strong>ibb</strong> or <strong>jingle</strong> transfer encodings must be used instead. If the sender is unsure if the content is |
|
finite or infinite, <strong>ibb</strong> or <strong>jingle</strong> must be used. |
|
</p> |
|
<p> |
|
<strong>Note 2:</strong> If the web server sends chunked data to the client it uses the HTTP header <strong>Transfer-Encoding: chunked</strong>, |
|
and then sends the data in chunks but with chunk sizes inserted so the receiving end can decode the incoming data. Note that this data will |
|
be included in the data sent in the XMPP chunks defined by this document. In this case, data will be chunked twice: First by the web server, |
|
and then by the HTTP over XMPP transport layer. When received by the client, it is first reassembled by the HTTP over XMPP layer on the client, |
|
and then by the HTTP client who will read the original chunk size elements inserted into the content. More information about HTTP chunking, |
|
can be found in <link url='http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1'>RDF2616 §3.6.1</link>. |
|
</p> |
|
<p> |
|
<strong>Note 3:</strong> In order to work over XMPP servers that do not maintain message order, a <strong>nr</strong> attribute is available on the |
|
<strong>chunk</strong> element. The first chunk reports a <strong>nr</strong> of zero. Each succcessive chunk reports a <strong>nr</strong> that is |
|
incremented by one. In this way, the receiver can make sure to order incoming chunks in the correct order. |
|
</p> |
|
</section3> |
|
<section3 topic='sipub'> |
|
<p> |
|
Often content being sent can be represented by a file, virtual or real, especially if the content actually represents a file and is not |
|
dynamically generated. In these instances, instead of embedding the contents in the response, |
|
since content can be potentially huge, a File Stream Initiation is returned instead, as defined in |
|
<link url='http://xmpp.org/extensions/xep-0137.html'>XEP 0137: Publishing Stream Initiation Requests</link>. This is done using the |
|
<strong>sipub</strong> element. |
|
</p> |
|
<example caption='sipub'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='11'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:39:54GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>image/png</header> |
|
<header name='Content-Length'>221203</header> |
|
</headers> |
|
<data> |
|
<sipub xmlns='http://jabber.org/protocol/sipub' |
|
from='httpserver@example.org' |
|
id='file-0001' |
|
mime-type='image/png' |
|
profile='http://jabber.org/protocol/si/profile/file-transfer'> |
|
<file xmlns='http://jabber.org/protocol/si/profile/file-transfer' |
|
name='Kermit.png' |
|
size='221203' |
|
date='2013-03-06T16:47Z'/> |
|
</sipub> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='ibb' anchor='#streams'> |
|
<p> |
|
Some web servers provide streaming content, i.e. content where packets are sent according to a timely fashion. Examples are video |
|
and audio streams like HLS (HTTP Live Streams), SHOUTcast, ICEcast, Motion JPeg, etc. In all these examples, content is infinite, |
|
and cannot be sent "all as quickly as possible". Instead, content is sent according to some kind of bitrate or frame rate for |
|
example. |
|
</p> |
|
<p> |
|
Such content must use the <strong>ibb</strong> transfer mechanism, if used (or the <strong>jingle</strong> transfer machanism). |
|
The <strong>ibb</strong> transfer mechanism uses <link url='http://xmpp.org/extensions/xep-0047.html'>In-Band Bytestreams</link> |
|
to transfer data from the server to the client. It starts by sending an a <strong>ibb</strong> element containing a <strong>sid</strong> |
|
attribute identifying the stream. Then the server sends an <strong>ibb:open</strong> IQ-stanza to the client according to |
|
<link url='http://xmpp.org/extensions/xep-0047.html'>XEP-0047</link>. The client can choose to reject, negotiate or acceopt the request |
|
whereby the transfer is begun. When the client is satisified and wants to close the stream, it does so, also according to |
|
<link url='http://xmpp.org/extensions/xep-0047.html'>XEP-0047</link>. The <strong>sid</strong> value returned in the HTTP response |
|
is the same <strong>sid</strong> value that is later used by the IBB messages that follow. In this way, the client can relate |
|
the HTTP request and response, with the corresponding data transferred separately. |
|
</p> |
|
<example caption='ibb'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='12'> |
|
<req xmlns='urn:xmpp:http' method='GET' resource='/webcam1.jpg' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='12'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 04 May 2013 15:05:32GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>multipart/x-mixed-replace;boundary=__2347927492837489237492837</header> |
|
</headers> |
|
<data> |
|
<ibb sid='Stream0002'/> |
|
</data> |
|
</resp> |
|
</iq> |
|
|
|
<iq type='set' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='13'> |
|
<open xmlns='http://jabber.org/protocol/ibb' |
|
block-size='32768' |
|
sid='Stream0002' |
|
stanza='message'/> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='13'/> |
|
|
|
<message from='httpserver@example.org' |
|
to='httpclient@example.org/browser'> |
|
<data xmlns='http://jabber.org/protocol/ibb' sid='Stream0002' seq='0'>...</chunk> |
|
</message> |
|
|
|
... |
|
|
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='14'> |
|
<close xmlns='http://jabber.org/protocol/ibb' sid='Stream0002'/> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='14'/>]]> |
|
</example> |
|
</section3> |
|
<section3 topic='jingle' anchor='jingle'> |
|
<p> |
|
For demanding multi-media streams alternative methods to transport streaming rather than embedded into the XMPP stream may be |
|
required. Even though the <strong>ibb</strong> method may be sufficient to stream a low-resolution web cam in the home, or listen to a microphone |
|
or a radio station, it is probably badly suited for high-resolution video streams with multiple video angles and audio channels. If such content is accessed |
|
and streamed, the server can negotiate a different way to stream the content using <link url='http://xmpp.org/extensions/xep-0166.html'>XEP 0166: Jingle</link>. |
|
</p> |
|
<example caption='jingle'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='14'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:39:54GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>video/mp4</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<jingle xmlns='urn:xmpp:jingle:1' |
|
action='session-initiate' |
|
initiator='romeo@montague.lit/orchard' |
|
sid='a73sjjvkla37jfea'> |
|
<content creator='initiator' name='voice'> |
|
<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> |
|
<payload-type id='96' name='speex' clockrate='16000'/> |
|
<payload-type id='97' name='speex' clockrate='8000'/> |
|
<payload-type id='18' name='G729'/> |
|
<payload-type id='0' name='PCMU' /> |
|
<payload-type id='103' name='L16' clockrate='16000' channels='2'/> |
|
<payload-type id='98' name='x-ISAC' clockrate='8000'/> |
|
</description> |
|
<transport xmlns='urn:xmpp:jingle:transports:ice-udp:1' |
|
pwd='asd88fgpdd777uzjYhagZg' |
|
ufrag='8hhy'> |
|
<candidate component='1' |
|
foundation='1' |
|
generation='0' |
|
id='el0747fg11' |
|
ip='10.0.1.1' |
|
network='1' |
|
port='8998' |
|
priority='2130706431' |
|
protocol='udp' |
|
type='host'/> |
|
<candidate component='1' |
|
foundation='2' |
|
generation='0' |
|
id='y3s2b30v3r' |
|
ip='192.0.2.3' |
|
network='1' |
|
port='45664' |
|
priority='1694498815' |
|
protocol='udp' |
|
rel-addr='10.0.1.1' |
|
rel-port='8998' |
|
type='srflx'/> |
|
</transport> |
|
</content> |
|
</jingle> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
<p> |
|
<strong>Note:</strong> Example taken from <link url='http://xmpp.org/extensions/xep-0166.html#howitworks'>XEP 166: Jingle</link>. |
|
</p> |
|
<p> |
|
<strong>Note2:</strong> Using Jingle in this way makes it possible for an intelligent server to return multiple streams the client |
|
can choose from, something that is not done in normal HTTP over TCP. The first candidate should however correspond to the same stream |
|
that would have been returned if the request had been made using normal HTTP over TCP. |
|
</p> |
|
</section3> |
|
</section2> |
|
<section2 topic='Applications'> |
|
<p> |
|
The following section lists use cases based on type of application. It is used to illustrate what types of applications would benefit from |
|
implementing this extension. |
|
</p> |
|
<section3 topic='Browsers'> |
|
<p> |
|
HTTP began as a protocol for presenting text in browsers. So, browsers is a natural place to start to list use cases for this extensions. |
|
In general, content is identified using URL's, and in the browser a user enters the URL into Address Field of the browser, and the corresponding |
|
content is displayed in the display area. The content itself will probably contain links to other content, each such item identified |
|
by an absolute or relative URL. |
|
</p> |
|
<section4 topic='httpx scheme' anchor='httpxscheme'> |
|
<p> |
|
The syntax and format of Uniform Resource Locators (URLs) or Uniform Resource Identifiers (URIs) is defined in &rfc3986;. The basic format is |
|
defined as follows: |
|
</p> |
|
<example caption='URL syntax'> |
|
<![CDATA[ |
|
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] |
|
|
|
hier-part = "//" authority path-abempty |
|
/ path-absolute |
|
/ path-rootless |
|
/ path-empty]]> |
|
</example> |
|
<p> |
|
&rfc2616; furthermore defines the format of URLs using the http URI scheme, as follows: |
|
</p> |
|
<example caption='HTTP (over TCP) URL syntax'> |
|
<![CDATA[ |
|
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]]]> |
|
</example> |
|
<p> |
|
&rfc2818; continues to define the https scheme for HTTP transport over SSL/TLS over TCP using the same format as for HTTP URLs, except the |
|
https scheme is used to inform the client that HTTP over SSL/TLS is to be used. |
|
</p> |
|
<p> |
|
In a similar way, this document proposes a new URI scheme: <strong>httpx</strong>, based on the HTTP URL scheme, except |
|
<strong>httpx</strong> URLs imply the use of HTTP over XMPP instead of HTTP over TCP. URLs using the <strong>httpx</strong> |
|
URL scheme has the following format: |
|
</p> |
|
<example caption='HTTP over XMPP URL syntax'> |
|
<![CDATA[ |
|
httpx_URL = "httpx:" "//" resourceless_jid [ abs_path [ "?" query ]]]]> |
|
</example> |
|
<p> |
|
Here, the host and port parts of normal HTTP URLs have been replaced by the resource-less JID of the HTTP Server, i.e. only the user name, |
|
the @ character and the domain. The / separator between the resource-less JID and the following abs_path, is part of abs_path. |
|
</p> |
|
<example caption='Examples of URLs with the httpx scheme'> |
|
<![CDATA[ |
|
httpx://httpServer@example.org/index.html |
|
httpx://httpServer@example.org/images/image1.png |
|
httpx://httpServer@example.org/api?p1=a&p2=b]]> |
|
</example> |
|
<p> |
|
By creating a new scheme for HTTP over XMPP transport, and implementing support for it in web browsers, XML HTTP request objects and web servers, |
|
Web Applications previously requiring web hosting on the Internet will be able to be seamlessly hosted privately and securely behind firewalls instead, |
|
by simply switching from the http URL scheme to the httpx URL scheme in the calling application. All relative URL's within the application, including |
|
URL's sent to the XHR object (Ajax) will automatically be directed to use the HTTP over XMPP transport instead. |
|
</p> |
|
</section4> |
|
<section4 topic='Friendship requests'> |
|
<p> |
|
It's beyond the scope of this specification to define how browsers handles its own XMPP account(s) and roster. This section only |
|
makes a suggestion to show how this can be handled. It is assumed in this discussion that the browser has a working XMPP |
|
connection with a server, and has its own JID. For simplicity, we will assume the browser has only one connection. Extension to |
|
multiple connection is canonical. |
|
</p> |
|
<p> |
|
When resolving an URL using the httpx scheme, the browser needs to extract the JID of the server hosting the resource. If that JID |
|
is already in the roster, the request can proceed as usual. |
|
</p> |
|
<p> |
|
If not in the roster, the browser needs to send a friendship request. A non-exhaustive list of states could be made: |
|
</p> |
|
<ul> |
|
<li>No response: This could be presented as a connection to the content server being made.</li> |
|
<li>Request rejected: This could be handled in the same way as HTTP Error Forbidden.</li> |
|
<li>Request accepted: Connection made, proceed with fetching content.</li> |
|
<li>Timeout: If no friendship request response have been returned, the browser can choose to time out.</li> |
|
</ul> |
|
<p> |
|
Since XMPP works both ways, the browser can receive friendship requests from the outside world. Any such requests should be displayed to the |
|
end user, if any, or rejected. |
|
</p> |
|
<p> |
|
For more information, see <link url='#rosterclient'>Roster Handling in web clients</link> and |
|
<link url='#rosterserver'>Roster Handling in web servers</link>. |
|
</p> |
|
</section4> |
|
<section4 topic='Seamless use of web applications hosted at home'> |
|
<p> |
|
Today, most people who want to host their own web applications (HTML/HTTP based applications) need to host them on a server publicly |
|
available on the Internet. However, many applications of a private nature like a family blog, home automation system, etc., is not |
|
suited for public hosting, since it puts all private data at risk of being compromised, or access to home security functions (like |
|
home web cams) to get in the hands of people you don't want to have access to them. |
|
</p> |
|
<p> |
|
To solve this, one can host the application on a server at home, perhaps a small cheap plug computer consuming as little as 1 or 2 Watts |
|
of electricity, using a web server supporting this extension. If the following design rules are followed, the application should be visible |
|
in any browser also supporting this extensions, as long as friendship exists between the browser and the web server: |
|
</p> |
|
<ul> |
|
<li> |
|
<p> |
|
Only relative URL's are used within references (images, audio, video, links, objects, etc.). If absolute URL's are used (including scheme), |
|
the browser might get the first page correctly, but will be unable to get the content with the absolute URL, unless the URL has the same scheme |
|
as the principal page. |
|
</p> |
|
</li> |
|
<li> |
|
<p> |
|
URL's to web forms must also be relative, for the same reason. |
|
</p> |
|
</li> |
|
<li> |
|
<p> |
|
Any URL's sent to the XML HTTP Request (XHR) Object directed to API's or resources hosted by the same application must also be relative, |
|
for the same reasons as above. The XHR Object supports relative URL's. |
|
</p> |
|
</li> |
|
</ul> |
|
<p> |
|
If the above rules are met, which they should under normal conditions, typing in the httpx URL in the browser (for instance when |
|
you're at the office) should display the application (hosted for example at home behind a firewall) in the same way as when you use http |
|
(or https) when you have access to the server (for instance when you're home), as long as friendship exists between the browser JID and |
|
the server JID. |
|
</p> |
|
</section4> |
|
</section3> |
|
<section3 topic='Web Services'> |
|
<p> |
|
Many applications use a Service Oriented Architecture (SOA) and use web services to communicate between clients and servers. These web services |
|
are mostly HTTP over TCP based, even though there are bindings which are not based on this. The most common APIs today (REST) are however all |
|
based on HTTP over TCP. Being HTTP over TCP requires the web server hosting the web services either to be public or directly accessible by the |
|
client. But as the services move closer to end users (for instance a Thermostat publishing a REST API for control in your home), problems arise |
|
when you try to access the web service outside of private network in which the API is available. As explained previously, the use of HTTP over XMPP |
|
solves this. |
|
</p> |
|
<section4 topic='SOAP'> |
|
<p> |
|
The following example shows a simple SOAP method call: |
|
</p> |
|
<example caption='SOAP method call'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.com' |
|
id='15'> |
|
<req xmlns='urn:xmpp:http' method='POST' resource='/Math' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>www.example.com</header> |
|
<header name='Content-Type'>application/soap+xml; charset=utf-8</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" |
|
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
<soap:Body xmlns:m="http://www.example.org/math"> |
|
<m:AddNumbers> |
|
<m:N1>10</m:N1> |
|
<m:N2>20</m:N2> |
|
</m:GetStockPrice> |
|
</soap:Body> |
|
</soap:Envelope> |
|
</xml> |
|
</data> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.com' |
|
to='httpclient@example.org/browser' |
|
id='15'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Content-Type'>application/soap+xml; charset=utf-8</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" |
|
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
<soap:Body xmlns:m="http://www.example.org/math"> |
|
<m:AddNumbersResponse> |
|
<m:Sum>30</m:Sum> |
|
</m:AddNumbersResponse> |
|
</soap:Body> |
|
</soap:Envelope> |
|
</xml> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
<p> |
|
<strong>Note:</strong> Other components of SOAP, such as WSDL and disco-documents are just examples of content |
|
handled by simple <link url='#GET'>GET</link> requests. |
|
</p> |
|
</section4> |
|
<section4 topic='REST'> |
|
<p> |
|
This section shows an example of a REST method call. REST method calls are just simple <link url='#GET'>GET</link>, |
|
<link url='#POST'>POST</link>, <link url='#PUT'>PUT</link> or <link url='#DELETE'>DELETE</link> HTTP calls with |
|
dynamically generated content. |
|
</p> |
|
<example caption='REST'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='16'> |
|
<req xmlns='urn:xmpp:http' method='GET' resource='/api/multiplicationtable?m=5' version='1.1'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
</headers> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='16'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 05 May 2013 15:01:53GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>text/xml</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<table> |
|
<value n='1' nTimesM='5'/> |
|
<value n='2' nTimesM='10'/> |
|
<value n='3' nTimesM='15'/> |
|
<value n='4' nTimesM='20'/> |
|
<value n='5' nTimesM='25'/> |
|
<value n='6' nTimesM='30'/> |
|
<value n='7' nTimesM='35'/> |
|
<value n='8' nTimesM='40'/> |
|
<value n='9' nTimesM='45'/> |
|
<value n='10' nTimesM='50'/> |
|
</table> |
|
</xml> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section4> |
|
</section3> |
|
<section3 topic='Semantic Web & IoT'> |
|
<p> |
|
The Semantic Web was originally developed as a way to link data between servers on the Web, and understand it. However, with the advents |
|
of technologies such as <link url='http://www.w3.org/TR/sparql11-query/'>SPARQL</link>, the Semantic Web has become a way to |
|
unify API's into a universal form of distributed API to all types of data possible. It also allows for a standardized way to perform |
|
grid computing, in the sense that queries can be federated and executed in a distributed fashion ("in the grid"). |
|
</p> |
|
<p> |
|
For these reasons, and others, semantic web technologies have been moving closer to Internet of Things, and also into the private spheres |
|
of its end users. Since the semantic web technologies are based on HTTP, they also suffer from the shortcomings of HTTP over TCP, when it |
|
comes to firewalls and user authentication and authorization. Allowing HTTP transport over XMPP greatly improves the reach of semantic |
|
technologies beyond "The Internet" while at the same time improving security and controllability of the information. |
|
</p> |
|
<p> |
|
As the semantic web moves closer to Internet of Things and the world of XMPP, it can benefit from work done with relation to the Internet of |
|
Things, such as &xep0324;, which would give automatic control of who (or what) can communicate with whom (or what). |
|
</p> |
|
<section4 topic='Turtle'> |
|
<p> |
|
Turtle <note> |
|
Turtle: Terse RDF Triple Language <<link url='http://www.w3.org/TR/turtle/'>http://www.w3.org/TR/turtle/</link>> |
|
</note>, is a simple way to represent semantic data. The following example shows Turtle-encoded semantic data being returned |
|
to the client as a response to a request. |
|
</p> |
|
<example caption='Turtle'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='2'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 16:39:54GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>text/turtle</header> |
|
<header name='Content-Length'>...</header> |
|
<header name='Connection'>Close</header> |
|
</headers> |
|
<data> |
|
<text>@prefix dc: <http://purl.org/dc/elements/1.1/>. |
|
@base <http://example.org/>. |
|
|
|
<xep> dc:title "HTTP over XMPP"; |
|
dc:creator <PeterWaher>; |
|
dc:publisher <XSF>.</text> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section4> |
|
<section4 topic='RDF'> |
|
<p> |
|
RDF <note> |
|
RDF: Resource Description Framework <<link url='http://www.w3.org/RDF/'>http://www.w3.org/RDF/</link>> |
|
</note>, is a another way to represent semantic data, better suited than Turtle for M2M communication. Related technologies, |
|
such as the micro format RDFa <note> |
|
RDFa: RDF through attributes <<link url='http://www.w3.org/TR/rdfa-syntax/'>http://www.w3.org/TR/rdfa-syntax/</link>> |
|
</note> allows for embedding RDF into HTML pages or XML documents. The following example shows RDF-encoded semantic data being returned |
|
to the client as a response to a request. |
|
</p> |
|
<example caption='RDF'> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='17'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 05 May 2013 16:02:23GMT-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>application/rdf+xml</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" |
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> |
|
<rdf:Description rdf:about="http://example.org/xep"> |
|
<dc:title>HTTP over XMPP</dc:title> |
|
<dc:creator rdf:resource="http://example.org/PeterWaher" /> |
|
<dc:publisher rdf:resource="http://example.org/XSF" /> |
|
</rdf:Description> |
|
</rdf:RDF> |
|
</xml> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section4> |
|
<section4 topic='SPARQL'> |
|
<p> |
|
This section shows an example of a SPARQL query executed as a POST call. |
|
</p> |
|
<example caption='SPARQL'> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='4'> |
|
<req xmlns='urn:xmpp:http' method='POST' version='1.1' |
|
resource='/sparql/?default-graph-uri=http%3A%2F%2Fanother.example%2Fcalendar.rdf'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Host'>example.org</header> |
|
<header name='User-agent'>Clayster HTTP/XMPP Client</header> |
|
<header name='Content-Type'>application/sparql-query</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<text>@prefix dc: <http://purl.org/dc/elements/1.1/>. |
|
@base <http://example.org/>. |
|
|
|
<xep> dc:title "HTTP over XMPP"; |
|
dc:creator <PeterWaher>; |
|
dc:publisher <XSF>.</text> |
|
</data> |
|
</req> |
|
</iq> |
|
|
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='4'> |
|
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'> |
|
<headers xmlns='http://jabber.org/protocol/shim'> |
|
<header name='Date'>Fri, 03 May 2013 17:09:34-4</header> |
|
<header name='Server'>Clayster</header> |
|
<header name='Content-Type'>application/sparql-results+xml</header> |
|
<header name='Content-Length'>...</header> |
|
</headers> |
|
<data> |
|
<xml> |
|
<sparql xmlns="http://www.w3.org/2005/sparql-results#"> |
|
<head> |
|
<variable name="title"/> |
|
<variable name="creator"/> |
|
</head> |
|
<results> |
|
<result> |
|
<binding name="title"> |
|
<literal>HTTP over XMPP</literal> |
|
</binding> |
|
<binding name="creator"> |
|
<uri>http://example.org/PeterWaher</uri> |
|
</binding> |
|
</result> |
|
</results> |
|
</sparql> |
|
</xml> |
|
</data> |
|
</resp> |
|
</iq>]]> |
|
</example> |
|
</section4> |
|
</section3> |
|
<section3 topic='Streaming'> |
|
<p> |
|
There are many types of streams and streaming protocols. Several of these are based on HTTP or variants simulating HTTP. Examples of such HTTP-based or |
|
pseudo-HTTP based streaming protocols can include HLS <note> |
|
HLS: HTTP Live Streaming <<link url='http://en.wikipedia.org/wiki/HTTP_Live_Streaming'>http://en.wikipedia.org/wiki/HTTP_Live_Streaming</link>> |
|
</note> used for multi-media streaming, |
|
SHOUTcast <note> |
|
SHOUTcast <<link url='http://en.wikipedia.org/wiki/SHOUTcast'>http://en.wikipedia.org/wiki/SHOUTcast</link>> |
|
</note> used for internet radio and |
|
Motion JPeg <note> |
|
Motion JPeg <<link url='http://en.wikipedia.org/wiki/Motion_JPEG'>http://en.wikipedia.org/wiki/Motion_JPEG</link>> |
|
</note> common format for web cameras. |
|
</p> |
|
<p> |
|
Common for all streaming data, is that they are indefinite, but at the same time rate-limited depending on quality, etc. Because of this, the |
|
web server is required to use the <link url='#streams'>ibb</link> encoding or the <link url='#jingle'>jingle</link> encoding to |
|
transport the content to the client. |
|
</p> |
|
</section3> |
|
</section2> |
|
</section1> |
|
<section1 topic='Determining Support' anchor='support'> |
|
<p>If an entity supports the protocol specified herein, it MUST advertise that fact by returning a feature of "urn:xmpp:http" in response to &xep0030; information requests.</p> |
|
<example caption="Service discovery information request"> |
|
<![CDATA[ |
|
<iq type='set' |
|
from='httpclient@example.org/browser' |
|
to='httpserver@example.org' |
|
id='disco1'> |
|
<query xmlns='http://jabber.org/protocol/disco#info'/> |
|
</iq>]]> |
|
</example> |
|
<example caption="Service discovery information response"> |
|
<![CDATA[ |
|
<iq type='result' |
|
from='httpserver@example.org' |
|
to='httpclient@example.org/browser' |
|
id='disco1'> |
|
<query xmlns='http://jabber.org/protocol/disco#info'> |
|
... |
|
<feature var='urn:xmpp:http'/> |
|
... |
|
</query> |
|
</iq>]]> |
|
</example> |
|
<p> |
|
In order for an application to determine whether an entity supports this protocol, where possible it SHOULD use the dynamic, presence-based profile of service discovery defined |
|
in &xep0115;. However, if an application has not received entity capabilities information from an entity, it SHOULD use explicit service discovery instead. |
|
</p> |
|
</section1> |
|
<section1 topic='Implementation Notes' anchor='impl'> |
|
<section2 topic='Connection handling' anchor='httpconnections'> |
|
<p> |
|
HTTP over TCP includes headers for connection handling. The basic sequence for an HTTP request might be: |
|
</p> |
|
<ul> |
|
<li>Client connects to server</li> |
|
<li>Clients sends request</li> |
|
<li>Client received response</li> |
|
<li>Client closes connection</li> |
|
</ul> |
|
<p> |
|
However, in the HTTP over XMPP case, there are no connections between the client and the server. Both clients and servers |
|
have active connections to the XMPP Server, but these remain unchanged during the sequence of requests. Therefore, both |
|
clients and servers should ignore any HTTP over TCP connection settings, since they have no meaning in the HTTP over XMPP |
|
case. However, the corresponding headers should always be transported as is, to maintain the information. |
|
</p> |
|
</section2> |
|
<section2 topic='HTTP Headers' anchor='headers'> |
|
<p> |
|
HTTP Headers are serialized to and from XML using the XEP-0131 <link url='http://xmpp.org/extensions/xep-0131.html'>Stanza Headers and Internet Metadata</link>. |
|
However, this does not mean that the SHIM feature needs to be published by the client, as defined in §3 in |
|
<link url='http://xmpp.org/extensions/xep-0131.html#disco'>XEP-0131</link>, since the headers will be embedded into the HTTP elements. |
|
Also, if there is any conflicts in how to store header values, when it comes to data types, etc., the original format as used by the original |
|
HTTP request must be used, and not the format defined in <link url='http://xmpp.org/extensions/xep-0131.html#headers'>Header Definitions</link> or |
|
<link url='http://xmpp.org/extensions/xep-0131.html#dates'>A Note About date-Related Headers</link> in XEP-0131. |
|
</p> |
|
<p> |
|
The HTTP over XMPP tunnel is just a tunnel of HTTP over XMPP, it does not know the semantic meaning of headers used in the transport. It does not know |
|
if additional headers added by the myriad of custom applications using HTTP are actually HTTP-compliant. It just acts as a transport, returning the |
|
sime kind of response (being deterministric) as if the original request was made through other means, for example over TCP. It does not add, remove or |
|
change semantic meaning of keys and values, nor change the format of the corresponding values. Such changes will create uncountable problems very difficult |
|
to detect and solve in a general case. |
|
</p> |
|
<p> |
|
This specification differs from XEP-0131 in that this specification the headers are consumed by web servers and web clients (The XMPP client here only |
|
being a "dumb" gateway), while in XEP-0131 the headers are consumed by the XMPP clients themselves, knowing XML and XML formats. |
|
</p> |
|
</section2> |
|
<section2 topic='Stanza Sizes'> |
|
<p> |
|
Some XMPP Servers may limit stanza sizes for various reasons. While this may work well for certain applications, like |
|
Instant Messaging and Chat, implementors of HTTP over XMPP need to know that some server have such stanza size |
|
restrictions. Therefore, an implementation should include configurable size limits, so chunking can be used instead |
|
of sending large stanzas. Another limit could be when streaming should be used instead of chunking. This later limit |
|
should be applied in particular on audio and video content. |
|
</p> |
|
<p> |
|
The implementor should also consider to send large content in the form of files using file transfer, and large multi-media |
|
content using Jingle. |
|
</p> |
|
<p> |
|
<strong>Note:</strong> According to &rfc6120; there is a smallest allowed maximum stanza size that all XMPP servers must support. |
|
According to §13.12.4 of that document, this limit is set to 10000 bytes including all characters from the opening < character |
|
to the closing > character. |
|
</p> |
|
</section2> |
|
<section2 topic='Bandwidth Limitations'> |
|
<p> |
|
Some XMPP Servers may also have bandwidth resitrctions enforced. This to limit the possibility of Denial of Service attacks |
|
or similar flooding of messages. Implementors of the HTTP over XMPP extensions must know however, that the bandwidth |
|
limitations for instant messaging and chat may be completely different from that of normal web applications. In chatting, |
|
a 1000 bytes/s limit is in most cases sufficient, while the same limit for even a modest web applications will make the |
|
application completely impossible to use. |
|
</p> |
|
</section2> |
|
</section1> |
|
<section1 topic='Security Considerations' anchor='security'> |
|
<p> |
|
It's beyond the scope of this document to define how HTTP clients or HTTP servers handle rosters internally. The following |
|
sections list suggestions on how these can be handled by different parties. |
|
</p> |
|
<section2 topic='Roster handling in browsers' anchor='rosterclient'> |
|
<p> |
|
Since browsers are operated by end users, any friendship request received from the outside should be either shown to the user |
|
(if the browser also maintains an IM client), or automatically rejected. |
|
</p> |
|
<p> |
|
On the other hand, when the browser wants to access an URL using the httpx scheme, an automatic friendship request to the |
|
corresponding JID should be done, if not already in the roster. It is assumed that by entering the URL, or using the URL |
|
of an application already displayed, this implies giving permission to add that JID as a friend to the roster of the |
|
browser. |
|
</p> |
|
</section2> |
|
<section2 topic='Roster handling in web servers' anchor='rosterserver'> |
|
<p> |
|
A web server should have different security settings available. The following subsections list possible settings for different |
|
scenarios. Note that these settings only reflect roster handling and cannot be set per resource. However, the server can |
|
maintain a set of JIDs with different settings and restrict access to parts of the content hosted by the server per JID. |
|
</p> |
|
<section3 topic='Public Server'> |
|
<p> |
|
A public server should accept requests from anybody (reachable from the current JID). All friendship requests should be |
|
automatically accepted. |
|
</p> |
|
<p> |
|
To avoid bloating the roster, friendship requests could be automatically unsubscribed once the HTTP session has ended. |
|
</p> |
|
</section3> |
|
<section3 topic='Manual Server'> |
|
<p> |
|
All new friendship are shown (or queued) to an administrator for manual acceptance or rejection. Once accepted, the client |
|
can access the corresponding content. During the wait (which can be substantial), the client should display a message |
|
that the friendship request is sent and response is pending. |
|
</p> |
|
<p> |
|
Automatic unsubscription of friendships should only be done on a much longer inactivity timeframe than the normal session |
|
timeout interval. |
|
</p> |
|
</section3> |
|
<section3 topic='Private Server'> |
|
<p> |
|
All new friendship requests are automatically rejected. Only already accepted friendships are allowed to make HTTP requests |
|
to the server. |
|
</p> |
|
</section3> |
|
<section3 topic='Provisioned Server'> |
|
<p> |
|
All new friendship requests are delegated to a trusted third party, according to |
|
<link url='http://xmpp.org/extensions/xep-0324.html'>XEP 0324: Internet of Things - Provisioning</link>. Friendship |
|
acceptance or rejection is then performed according to the response from the provisioning server(s). |
|
</p> |
|
<p> |
|
Automatic friendship unsubscription can be made to avoid bloating the roster. However, the time interval for unsubscribing |
|
inactive users should be longer than the normal session timeout period, to avoid spamming any provisioning servers each |
|
time a client requests friendship. |
|
</p> |
|
</section3> |
|
</section2> |
|
</section1> |
|
<section1 topic='IANA Considerations' anchor='iana'> |
|
<p> |
|
The httpx URL scheme, as described <link url='#httpxscheme'>above</link>, must be registered as a provisional URI scheme according to BCP 35 <note> |
|
BCP 35: New URI Schemes <<link url='http://tools.ietf.org/html/bcp35'>http://tools.ietf.org/html/bcp35</link>> |
|
</note>. The registration procedure is specified in <link url='http://tools.ietf.org/html/bcp35#section-7'>BCP 35, section 7</link>. |
|
</p> |
|
<section2 topic='URI Scheme Registration Template'> |
|
<p> |
|
Following is an URI Scheme Registration Template, as per <link url='http://tools.ietf.org/html/bcp35#section-7.4'>BCP 35, section 7.4</link>. |
|
</p> |
|
<dl> |
|
<di> |
|
<dt>URI scheme name</dt> |
|
<dd> |
|
<p> |
|
httpx |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Status</dt> |
|
<dd> |
|
<p> |
|
provisional |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>URI scheme syntax</dt> |
|
<dd> |
|
<p> |
|
The syntax used for the httpx scheme reuses the URI scheme syntax for the http scheme, as defined in RFC 2616: |
|
</p> |
|
<code> |
|
<![CDATA[ |
|
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]]]> |
|
</code> |
|
<p> |
|
Instead of using host and port to define the where the HTTP server resides, the httpx scheme uses a resource-less |
|
XMPP JID to define where the HTTP server resides, implying the use of HTTP over XMPP as defined in this document |
|
instead of HTTP over TCP: |
|
</p> |
|
<code> |
|
<![CDATA[ |
|
httpx_URL = "httpx:" "//" resourceless_jid [ abs_path [ "?" query ]]]]> |
|
</code> |
|
<p> |
|
Here, the host and port parts of normal HTTP URLs have been replaced by the resource-less JID of the HTTP Server, i.e. only the user name, |
|
the @ character and the domain. The / separator between the resource-less JID and the following abs_path, is part of abs_path. |
|
</p> |
|
<code> |
|
<![CDATA[ |
|
httpx://httpServer@example.org/index.html |
|
httpx://httpServer@example.org/images/image1.png |
|
httpx://httpServer@example.org/api?p1=a&p2=b]]> |
|
</code> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>URI scheme semantics</dt> |
|
<dd> |
|
<p> |
|
By creating a new scheme for HTTP over XMPP transport, and implementing support for it in web browsers, XML HTTP request objects and web servers, |
|
Web Applications previously requiring web hosting on the Internet will be able to be seamlessly hosted privately and securely behind firewalls instead, |
|
by simply switching from the http URL scheme to the httpx URL scheme in the calling application. All relative URL's within the application, including |
|
URL's sent to the XHR object (Ajax) will automatically be directed to use the HTTP over XMPP transport instead. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Encoding considerations</dt> |
|
<dd> |
|
<p> |
|
Encoding is fully described in the |
|
<link url='http://xmpp.org/extensions/xep-0332.html#encoding'>Encoding section of the HTTP over XMPP XEP</link> document. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Applications/protocols that use this URI scheme name</dt> |
|
<dd> |
|
<p> |
|
This URI scheme is to be used in the same environments and by the same types of applications as the http URI scheme. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Interoperability considerations</dt> |
|
<dd> |
|
<p> |
|
Interoperability considerations is described in the |
|
<link url='http://xmpp.org/extensions/xep-0332.html#impl'>Implementation Notes section of the HTTP over XMPP XEP</link> document. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Security considerations</dt> |
|
<dd> |
|
<p> |
|
Security considerations is described in the |
|
<link url='http://xmpp.org/extensions/xep-0332.html#security'>Security considerations section of the HTTP over XMPP XEP</link> document. |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Contact</dt> |
|
<dd> |
|
<p> |
|
For further information, please contact Peter Waher: |
|
</p> |
|
<p> |
|
Email: <link url='mailto:peter.waher@example.org'>peter.waher@example.org</link><br/> |
|
JabberID: <link url='xmpp:peter.waher@jabber.org'>peter.waher@jabber.org</link><br/> |
|
URI: <link url='http://www.linkedin.com/in/peterwaher'>http://www.linkedin.com/in/peterwaher</link> |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>Author/Change controller</dt> |
|
<dd> |
|
<p> |
|
For concerns regarding changes to the provisional registration, please contact Peter Waher: |
|
</p> |
|
<p> |
|
Email: <link url='mailto:peter.waher@example.org'>peter.waher@example.org</link><br/> |
|
JabberID: <link url='xmpp:peter.waher@jabber.org'>peter.waher@jabber.org</link><br/> |
|
URI: <link url='http://www.linkedin.com/in/peterwaher'>http://www.linkedin.com/in/peterwaher</link> |
|
</p> |
|
</dd> |
|
</di> |
|
<di> |
|
<dt>References</dt> |
|
<dd> |
|
<p> |
|
Following is a short list of referenced documents: |
|
</p> |
|
<ol> |
|
<li> |
|
RFC 6120: <link url='http://tools.ietf.org/html/rfc6120'> |
|
Extensible Messaging and Presence Protocol (XMPP): Core |
|
</link> |
|
</li> |
|
<li> |
|
RFC 2616: <link url='http://tools.ietf.org/html/rfc2616'> |
|
Hypertext Transfer Protocol -- HTTP/1.1 |
|
</link> |
|
</li> |
|
<li> |
|
HTTP over XMPP XEP: <link url='http://xmpp.org/extensions/xep-0332.html'> |
|
XMPP Extension Protocol: HTTP over XMPP |
|
</link> |
|
</li> |
|
</ol> |
|
</dd> |
|
</di> |
|
</dl> |
|
</section2> |
|
</section1> |
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'> |
|
<p> |
|
The <link url="#schema">protocol schema</link> needs to be added to the list of <link url="http://xmpp.org/resources/schemas/">XMPP protocol schemas</link>. |
|
</p> |
|
</section1> |
|
<section1 topic='XML Schema' anchor='schema'> |
|
<code> |
|
<![CDATA[ |
|
<?xml version='1.0' encoding='UTF-8'?> |
|
<xs:schema |
|
xmlns:xs='http://www.w3.org/2001/XMLSchema' |
|
targetNamespace='urn:xmpp:http' |
|
xmlns='urn:xmpp:http' |
|
xmlns:shim='http://jabber.org/protocol/shim' |
|
xmlns:sipub='http://jabber.org/protocol/sipub' |
|
xmlns:ibb='http://jabber.org/protocol/ibb' |
|
xmlns:jingle='urn:xmpp:jingle:1' |
|
elementFormDefault='qualified'> |
|
|
|
<xs:import namespace='http://jabber.org/protocol/shim'/> |
|
<xs:import namespace='http://jabber.org/protocol/sipub'/> |
|
<xs:import namespace='http://jabber.org/protocol/ibb'/> |
|
<xs:import namespace='urn:xmpp:jingle:1'/> |
|
|
|
<xs:element name='req'> |
|
<xs:complexType> |
|
<xs:sequence> |
|
<xs:element ref='shim:headers' minOccurs='0' maxOccurs='1'/> |
|
<xs:element name='data' type='Data' minOccurs='0' maxOccurs='1'/> |
|
</xs:sequence> |
|
<xs:attribute name='method' type='Method' use='required'/> |
|
<xs:attribute name='resource' type='xs:string' use='required'/> |
|
<xs:attribute name='version' type='Version' use='required'/> |
|
<xs:attribute name='maxChunkSize' type='MaxChunkSize' use='optional'/> |
|
<xs:attribute name='sipub' type='xs:boolean' use='optional' default='true'/> |
|
<xs:attribute name='ibb' type='xs:boolean' use='optional' default='true'/> |
|
<xs:attribute name='jingle' type='xs:boolean' use='optional' default='true'/> |
|
</xs:complexType> |
|
</xs:element> |
|
|
|
<xs:simpleType name='MaxChunkSize'> |
|
<xs:restriction base='xs:int'> |
|
<xs:minInclusive value='256'/> |
|
<xs:maxInclusive value='65536'/> |
|
</xs:restriction> |
|
</xs:simpleType> |
|
|
|
<xs:element name='resp'> |
|
<xs:complexType> |
|
<xs:sequence> |
|
<xs:element ref='shim:headers' minOccurs='0' maxOccurs='1'/> |
|
<xs:element name='data' type='Data' minOccurs='0' maxOccurs='1'/> |
|
</xs:sequence> |
|
<xs:attribute name='version' type='Version' use='required'/> |
|
<xs:attribute name='statusCode' type='xs:positiveInteger' use='required'/> |
|
<xs:attribute name='statusMessage' type='xs:string' use='optional'/> |
|
</xs:complexType> |
|
</xs:element> |
|
|
|
<xs:complexType name='Data'> |
|
<xs:choice minOccurs='1' maxOccurs='1'> |
|
<xs:element name='text' type='xs:string'> |
|
<xs:annotation> |
|
<xs:documentation>Used for text responses that are not XML.</xs:documentation> |
|
</xs:annotation> |
|
</xs:element> |
|
<xs:element name='xml'> |
|
<xs:annotation> |
|
<xs:documentation>Specifically used for XML-formatted responses.</xs:documentation> |
|
</xs:annotation> |
|
<xs:complexType> |
|
<xs:sequence minOccurs='0' maxOccurs='1'> |
|
<xs:any processContents="lax" namespace="##any"/> |
|
</xs:sequence> |
|
</xs:complexType> |
|
</xs:element> |
|
<xs:element name="base64" type="xs:base64Binary"> |
|
<xs:annotation> |
|
<xs:documentation>Short binary responses, base-64 encoded.</xs:documentation> |
|
</xs:annotation> |
|
</xs:element> |
|
<xs:element name="chunkedBase64"> |
|
<xs:annotation> |
|
<xs:documentation>Content is divided into chunks of binary base-64 encoded data.</xs:documentation> |
|
<xs:documentation>Used if content is generated dynamically and/or content size is not known.</xs:documentation> |
|
<xs:documentation>For streaming data the ibb:open or jingle:jingle transports must be used.</xs:documentation> |
|
<xs:documentation>For static data, such as files, sipub:sipub should be used.</xs:documentation> |
|
</xs:annotation> |
|
<xs:complexType> |
|
<xs:attribute name="streamId" type="xs:string" use="required"/> |
|
</xs:complexType> |
|
</xs:element> |
|
<xs:element ref='sipub:sipub'> |
|
<xs:annotation> |
|
<xs:documentation>Content available through file transfer.</xs:documentation> |
|
</xs:annotation> |
|
</xs:element> |
|
<xs:element name="ibb"> |
|
<xs:annotation> |
|
<xs:documentation>Content returned through an in-band bytestream.</xs:documentation> |
|
</xs:annotation> |
|
<xs:complexType> |
|
<xs:attribute name="sid" type="xs:string" use="required"/> |
|
</xs:complexType> |
|
</xs:element> |
|
<xs:element ref="jingle:jingle"> |
|
<xs:annotation> |
|
<xs:documentation>Multi-media content returned through jingle.</xs:documentation> |
|
</xs:annotation> |
|
</xs:element> |
|
</xs:choice> |
|
</xs:complexType> |
|
|
|
<xs:element name="chunk"> |
|
<xs:complexType> |
|
<xs:simpleContent> |
|
<xs:extension base="xs:base64Binary"> |
|
<xs:attribute name="streamId" type="xs:string" use="required"/> |
|
<xs:attribute name="nr" type="xs:nonNegativeInteger" use="required"/> |
|
<xs:attribute name="last" type="xs:boolean" use="optional" default="false"/> |
|
</xs:extension> |
|
</xs:simpleContent> |
|
</xs:complexType> |
|
</xs:element> |
|
|
|
<xs:element name='close'> |
|
<xs:complexType> |
|
<xs:attribute name='streamId' type='xs:string' use='required'/> |
|
</xs:complexType> |
|
</xs:element> |
|
|
|
<xs:simpleType name='Method'> |
|
<xs:restriction base='xs:string'> |
|
<xs:enumeration value='OPTIONS'/> |
|
<xs:enumeration value='GET'/> |
|
<xs:enumeration value='HEAD'/> |
|
<xs:enumeration value='POST'/> |
|
<xs:enumeration value='PUT'/> |
|
<xs:enumeration value='DELETE'/> |
|
<xs:enumeration value='TRACE'/> |
|
<xs:enumeration value='PATCH'/> |
|
</xs:restriction> |
|
</xs:simpleType> |
|
|
|
<xs:simpleType name='Version'> |
|
<xs:restriction base='xs:string'> |
|
<xs:pattern value='\d[.]\d'/> |
|
</xs:restriction> |
|
</xs:simpleType> |
|
|
|
</xs:schema>]]> |
|
</code> |
|
</section1> |
|
<section1 topic='Acknowledgements' anchor='ack'> |
|
<p>Thanks to Peter Saint-Andre, Karin Forsell, Matthew A. Miller, Kevin Smith and Ralph Meijer for all valuable feedback.</p> |
|
</section1> |
|
</xep>
|
|
|