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.

2007 lines
103 KiB

<?xml version='1.0' encoding='UTF-8'?>
10 years ago
<!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>
10 years ago
&LEGALNOTICE;
<number>0332</number>
<status>Deferred</status>
<lastcall>2014-10-21</lastcall>
10 years ago
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0001</spec>
<spec>XEP-0030</spec>
10 years ago
<spec>XEP-0047</spec>
<spec>XEP-0131</spec>
10 years ago
<spec>XEP-0137</spec>
<spec>XEP-0166</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
&peterwaher;
<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>
10 years ago
<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>
10 years ago
<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>
10 years ago
<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>
10 years ago
<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>
10 years ago
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
10 years ago
scripting languages such as Java Script running in web browsers.
</p>
<p>
10 years ago
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.
10 years ago
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
10 years ago
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.
10 years ago
</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
10 years ago
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 &lt;-&gt; HTTP Server/XMPP Client &lt;-&gt; XMPP Server.
Here HTTP Client authentication to resources on the HTTP Server is made by a third party, an XMPP Server.
</li>
<li>
10 years ago
&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.
10 years ago
</li>
<li>
10 years ago
&xep0124;: This specification handles XMPP-based communication over HTTP sessions (BOSH), allowing for instance, XMPP communication in java script using the
10 years ago
XML HTTP Request object. This is in some way the reverse of what this document proposes to do.
</li>
10 years ago
<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>
10 years ago
<li>
&xep0147;: This informational specification proposes ways to define XMPP-actions using URL's. The xmpp URI scheme is formally defined in &rfc5122;.
10 years ago
This document will propose a different URI scheme for HTTP-based resources over an XMPP transport: httpx.
10 years ago
</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
10 years ago
dynamic (i.e. generated) or static (e.g. files) in nature. Content, which it wants to
10 years ago
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>
10 years ago
Hyper Text Transfer Protocol. Version 1.1 of HTTP is described in RFC 2616 <note>
10 years ago
RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 &lt;<link url='http://tools.ietf.org/html/rfc2616'>http://tools.ietf.org/html/rfc2616</link>&gt;
10 years ago
</note>. The PATCH method is described in RFC 5789 <note>
10 years ago
RFC 5789: PATCH Method for HTTP &lt;<link url='http://tools.ietf.org/html/rfc5789'>http://tools.ietf.org/html/rfc5789</link>&gt;
</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>
10 years ago
<dd>An HTTP Request consists of a HTTP Method, version information, headers and optional body.</dd>
10 years ago
</di>
<di>
<dt>HTTP Resource</dt>
10 years ago
<dd>A resource on an HTTP Server identified by a path. Each path begins with a separator character (/).</dd>
10 years ago
</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>
10 years ago
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>.
10 years ago
</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
10 years ago
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,
10 years ago
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>
10 years ago
<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 (&lt;, &gt; and &amp;)
are escaped using the normal &amp;lt;, &amp;gt; and &amp;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
10 years ago
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,
10 years ago
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
10 years ago
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>
10 years ago
<p>
<strong>Note:</strong> Content encoded using <strong>chunkedBase64</strong> encoding method can be terminated, either by the receptor going off-line, or by
10 years ago
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.
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='1'>
<req xmlns='urn:xmpp:http' method='OPTIONS' resource='*' version='1.1'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Host'>example.org</header>
10 years ago
</headers>
10 years ago
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='1'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='2'>
10 years ago
<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>
10 years ago
</headers>
10 years ago
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='2'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
10 years ago
<text>@prefix dc: &lt;http://purl.org/dc/elements/1.1/&gt;.
@base &lt;http://example.org/&gt;.
10 years ago
10 years ago
&lt;xep&gt; dc:title "HTTP over XMPP";
dc:creator &lt;PeterWaher&gt;;
dc:publisher &lt;XSF&gt;.</text>
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='3'>
<req xmlns='urn:xmpp:http' method='HEAD' resource='/video/video1.m4' version='1.1'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Host'>example.org</header>
10 years ago
</headers>
10 years ago
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='3'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='4'>
<req xmlns='urn:xmpp:http' method='POST' resource='/sparql/?default-graph-uri=http%3A%2F%2Fexample.org%2Frdf/xep' version='1.1'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Host'>example.org</header>
10 years ago
<header name='User-agent'>Clayster HTTP/XMPP Client</header>
<header name='Content-Type'>application/sparql-query</header>
<header name='Content-Length'>...</header>
</headers>
10 years ago
<data>
10 years ago
<text>PREFIX dc: &lt;http://purl.org/dc/elements/1.1/&gt;
BASE &lt;http://example.org/&gt;
10 years ago
SELECT ?title ?creator ?publisher
WHERE { ?x dc:title ?title .
OPTIONAL { ?x dc:creator ?creator } .
}</text>
10 years ago
</data>
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='4'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
<xml>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
<head>
10 years ago
<variable name="title"/>
<variable name="creator"/>
10 years ago
</head>
<results>
<result>
10 years ago
<binding name="title">
<literal>HTTP over XMPP</literal>
10 years ago
</binding>
10 years ago
<binding name="creator">
<uri>http://example.org/PeterWaher</uri>
10 years ago
</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
10 years ago
(&lt;?xml version="1.0"?&gt;) 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
10 years ago
jabber:client namespace. If in doubt, use another encoding mechanism.
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='5'>
<req xmlns='urn:xmpp:http' method='PUT' resource='/index.html' version='1.1'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Host'>example.org</header>
10 years ago
<header name='Content-Type'>text/html</header>
<header name='Content-Length'>...</header>
</headers>
10 years ago
<data>
<text>&lt;html&gt;&lt;header/&gt;&lt;body&gt;&lt;p&gt;Beautiful home page.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</text>
</data>
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='5'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='204' statusMessage='No Content'>
10 years ago
<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>
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='6'>
<req xmlns='urn:xmpp:http' method='DELETE' resource='/index.html' version='1.1'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Host'>example.org</header>
10 years ago
</headers>
10 years ago
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='6'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='403' statusMessage='Forbidden'>
10 years ago
<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>
10 years ago
<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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='7'>
<req xmlns='urn:xmpp:http' method='TRACE' resource='/rdf/ex1.turtle' version='1.1'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Host'>example.org</header>
10 years ago
</headers>
10 years ago
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='7'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
<text>GET /rdf/ex1.turtle HTTP/1.1
Host: example.org</text>
10 years ago
</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[
10 years ago
<iq type='set'
from='httpclient@example.org/browser'
to='httpserver@example.org'
10 years ago
id='8'>
<req xmlns='urn:xmpp:http' method='PATCH' resource='/file.txt' version='1.1'>
10 years ago
<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>
10 years ago
<data>
[description of changes]
</data>
</req>
</iq>
10 years ago
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='8'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='204' statusMessage='No Content'>
10 years ago
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Content-Location'>/file.txt</header>
<header name='ETag'>e0023aa4e</header>
</headers>
10 years ago
</resp>
</iq>]]>
</example>
</section3>
</section2>
10 years ago
<section2 topic='Encoding formats' anchor='encoding'>
10 years ago
<p>
10 years ago
In the following sub-sections, the different data encoding formats are discussed, each with corresponding examples to illustrate how they work.
10 years ago
The interesting part of these examples is the <strong>data</strong> element and its contents.
</p>
10 years ago
<section3 topic='text'>
10 years ago
<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 &lt;, &gt; and &amp; need to be escaped to &amp;lt;, &amp;gt; and &amp;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>
10 years ago
<example caption='text'>
10 years ago
<![CDATA[
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='2'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
10 years ago
<text>@prefix dc: &lt;http://purl.org/dc/elements/1.1/&gt;.
@base &lt;http://example.org/&gt;.
10 years ago
10 years ago
&lt;xep&gt; dc:title "HTTP over XMPP";
dc:creator &lt;PeterWaher&gt;;
dc:publisher &lt;XSF&gt;.</text>
10 years ago
</data>
</resp>
</iq>]]>
</example>
</section3>
10 years ago
<section3 topic='xml'>
10 years ago
<p>
10 years ago
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>
10 years ago
(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
(&lt;?xml version="1.0"?&gt; as an example). Care has also to be taken to make sure that the generated XML is not invalid XMPP, even though it might
10 years ago
be valid XML. This could happen for instance, if the XML contains illegal elements from the jabber:client namespace.
</p>
<p>
10 years ago
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 &lt;, &gt; and &amp;, 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
10 years ago
gain induced by the encoding is recaptured.
</p>
10 years ago
<example caption='xml'>
10 years ago
<![CDATA[
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='4'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
<xml>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
<head>
10 years ago
<variable name="title"/>
<variable name="creator"/>
10 years ago
</head>
<results>
<result>
10 years ago
<binding name="title">
<literal>HTTP over XMPP</literal>
10 years ago
</binding>
10 years ago
<binding name="creator">
<uri>http://example.org/PeterWaher</uri>
10 years ago
</binding>
</result>
</results>
</sparql>
</xml>
</data>
</resp>
</iq>]]>
</example>
</section3>
10 years ago
<section3 topic='base64'>
10 years ago
<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.
10 years ago
Care has to be taken not to send too large items using this encoding.
10 years ago
</p>
10 years ago
<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
10 years ago
to encode the data only uses 6 bits of information per character, and thus compresses the data back to its original size.
</p>
10 years ago
<p>
The following example shows an image is returned using the <strong>base64</strong> encoding:
</p>
10 years ago
<example caption='base64'>
10 years ago
<![CDATA[
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='9'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
<base64>iVBORw0KGgoAAAANSUhEUgAAASwAAAGQCAYAAAAUdV17AAAAAXNSR0 ... tVWJd+e+y1AAAAABJRU5ErkJggg==</base64>
</data>
</resp>
</iq>]]>
</example>
</section3>
10 years ago
<section3 topic='chunkedBase64'>
10 years ago
<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>
10 years ago
<example caption='chunkedBase64'>
10 years ago
<![CDATA[
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='10'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<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>
10 years ago
</message>
10 years ago
...
<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>
10 years ago
</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
10 years ago
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>.
10 years ago
</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>
10 years ago
<section3 topic='sipub'>
10 years ago
<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
10 years ago
<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>
10 years ago
<example caption='sipub'>
10 years ago
<![CDATA[
<iq type='result'
from='httpserver@example.org'
to='httpclient@example.org/browser'
10 years ago
id='11'>
<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200' statusMessage='OK'>
10 years ago
<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>
10 years ago
<data>
<sipub xmlns='http://jabber.org/protocol/sipub'
from='httpserver@example.org'
10 years ago
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>
10 years ago
</data>
</resp>
</iq>]]>
</example>
</section3>
10 years ago
<section3 topic='ibb' anchor='#streams'>
10 years ago
<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>
10 years ago
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