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.

198 lines
10 KiB

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<title>JSON Encodings for XMPP</title>
<abstract>This specification defines an alternative JSON encoding for XMPP stanzas and other elements.</abstract>
<spec>XMPP Core</spec>
<initials>ks, mw</initials>
<remark><p>April Fools!</p></remark>
<section1 topic='Introduction' anchor='intro'>
<p>It has long been known that XML is an outdated, failed format for interchangeable data serialization. While it does, admittedly, provide all the features that XMPP needs, XML is not without its share of detractors. Indeed, some years ago this led to the (sadly short-lived) attempt to provide a binary encoding for XMPP given in &xep0239;. Unfortunately, the binary encoding lacked the main advantages of XML in its human readability, so the search for better encodings has led us to JSON. JSON is a very popular format and it is sensible to utilize this popularity by reframing XMPP stanzas in JSON. JSON is not as expressive as XML in terms of namespacing, so this document presents a method of encoding stanzas, including namespaces in JSON.</p>
<section1 topic='Protocol' anchor='protocol'>
<p>The recently updated &xmppcore; documents the legacy XML encoding of XMPP, and readers are urged to refer to that spec not just for other details of the protocol but also to appreciate the relative elegance of the encoding contained within this extension.</p>
<p>Let us consider a fairly standard XMPP message stanza:</p>
<example caption='XML-encoded XMPP stanza'><![CDATA[
<message to="alice@wonderland.lit" id="if00lu" >
<body>Hi you</body>
<body xml:lang="cy">Prynhawn da</body>
<nick xmlns="">Alice</nick>
<active xmlns=""/>
<p>Given the need to include the namespaces within the JSON, an immediately obvious structure may be something like::</p>
<example caption='Na&#239;ve JSON representation'><![CDATA[
{"stanza-name": "message",
"stanza-namespace": "jabber:client",
"stanza-attributes": {
"stanza-children": [
"element-name": "body",
"element-namespace": "jabber:client",
"element-value": "Hi you"
"element-name": "body",
"element-namespace": "jabber:client",
"element-language": "cy",
"element-value": "Prynhawn da"
"element-name": "nick",
"element-namespace": "",
"element-value": "Alice"
"element-name": "active",
"element-namespace": "",
<p>While many of the advantages of JSON over XML can be observed in this encoding (particularly the inherent brevity), an even more compact representation has been developed. Instead of reserializing the traditional XML stanzas in this manner, it is possible to wrap the stanzas within JSON, thereby enjoying the best of both worlds:</p>
<example caption='Advanced JSON-encoding'><![CDATA[
{"s":"<message to='alice@wonderland.lit' id='if00lu'><body>Hi you</body><body xml:lang='cy'>Prynhawn da</body><nick xmlns=''>Alice</nick><active xmlns=''/></message>"}
<p>To use this improved encoding (eminently suitable both for c2s and s2s connections), entities should follow the connection rules defined in &xmppcore; and immediately start sending JSON-encoded data. Receiving entities should detect the presence of an open-brace ('{') character as the first octet received on a stream to be a signal to continue with JSON encoding. Servers supporting only the legacy XML encoding will necessarily respond with an error when receiving the improved JSON format, and entities will know to reconnect and continue with the legacy format.</p>
<section1 topic='Examples' anchor='examples'>
<p>Hopefully the beauty of this approach will be apparent at this stage, but in case some lingering doubts remain (and with the hope of aiding interoperability), more examples are provided here:</p>
<example caption='XML-encoded Message with Security Label'><![CDATA[
<message to='' from=''>
<body>This content is classified.</body>
<securitylabel xmlns='urn:xmpp:sec-label:0'>
<displaymarking fgcolor='black' bgcolor='red'>SECRET</displaymarking>
<label><esssecuritylabel xmlns='urn:xmpp:sec-label:ess:0'>
<example caption='JSON-encoded Message with Security Label'><![CDATA[
{"s":"<message to='' from=''><body>This content is classified.</body><securitylabel xmlns='urn:xmpp:sec-label:0'><displaymarking fgcolor='black' bgcolor='red'>SECRET</displaymarking><label><esssecuritylabel xmlns='urn:xmpp:sec-label:ess:0'>MQYCAQQGASk=</esssecuritylabel></label></securitylabel></message>"}
<example caption='XML-encoded XHTML-IM message'><![CDATA[
<message from='ladymacbeth@shakespeare.lit/castle'
<body>Yet here's a spot.</body>
<html xmlns=''>
<body xmlns=''>
Yet here's a spot.
<img alt='A spot'
<example caption='JSON-encoded XHTML-IM message'><![CDATA[
{"s":"<message from='ladymacbeth@shakespeare.lit/castle' to='macbeth@chat.shakespeare.lit' type='groupchat'><body>Yet here's a spot.</body><html xmlns=''><body xmlns=''><p>Yet here's a spot.<img alt='A spot' src=''/></p></body></html></message>"}
<example caption='XML-encoded Dialback Key Transmission'><![CDATA[
<example caption='JSON-encoded Dialback Key Transmission'><![CDATA[
{"s":"<db:result from='sender.tld' to='target.tld'>1e701f120f66824b57303384e83b51feba858024fd2221d39f7acc52dcf767a9</db:result>"}
<example caption='XML-encoded Event Publication'><![CDATA[
<iq from='juliet@capulet.lit/balcony' type='set' id='pub1'>
<pubsub xmlns=''>
<publish node=''>
<tune xmlns=''>
<artist>Gerald Finzi</artist>
<source>Music for 'Love's Labors Lost' (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<example caption='JSON-encoded Event Publication'><![CDATA[
{"s":"<iq from='juliet@capulet.lit/balcony' type='set' id='pub1'><pubsub xmlns=''><publish node=''><item><tune xmlns=''><artist>Gerald Finzi</artist><length>255</length><source>Music for 'Love's Labors Lost' (Suite for small orchestra)</source><title>Introduction (Allegro vigoroso)</title><track>1</track></tune></item></publish></pubsub></iq>"}
<example caption='XML-encoded Stream Header'><![CDATA[
<example caption='JSON-encoded Stream Header'><![CDATA[
{"s":"<stream:stream from='' to='' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream=''>"}
<p>Beautiful, elegant <em>and</em> efficient at the same time.</p>
<section1 topic='Internationalization Considerations' anchor='i18n'>
<p>It is hoped that this representation introduces no new internationalization considerations, although it is acknowledged that if there are cultures where the symbols <tt>{}:</tt> are considered to be more offensive than <tt>&lt;>=</tt> the legacy XML encoding may be preferred.</p>
<section1 topic='Security Considerations' anchor='security'>
<p>Implementors should be aware that the JSON encoding involves 8 additional bytes for each stanza, and this introduces a considerable risk of buffer over-flow attacks. While new codebases will hopefully be designed with this in mind, existing codebases will need to be entirely upgraded, with every buffer increased in size by at least 8 bytes to address this potentially serious potential vulnerability.</p>
<section1 topic='IANA Considerations' anchor='iana'>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>The XMPP Registrar may wish to consider maintenance of dual registries - for both XML and JSON encodings, but this is OPTIONAL.</p>
<section1 topic='JSON Schema' anchor='schema'>
"type": "object",
"additionalProperties": false,
"properties": {
"s": {
"type": "string",
"required": true,
"format": "xml"
<section1 topic='Acknowledgements' anchor='ack'>
<p>Thanks to Waqas Hussain for implementation feedback.</p>