XMPP interleaved binary
----
S: <stream:features>
S: <interleaved xmlns='ns:interleaved'/>
S: </stream:features>
C: <enable xmlns='ns:interleaved'/>
S: <enabled xmlns='ns:interleaved'/>
Starting after the final '>' character, all data exchanged with the server
must use this framing format:
[header] [value bytes]
The header contains the type of data and the number of value bytes. The
format of the header is: 1 bit type section, X bits length section. The
header is byte-aligned, with the length section expanding as necessary.
The length section is always at least 15 bits, and increases in increments
of 8. The first 7 bits of the length section are part of the length value.
For the remaining bytes, Bit 8 is set to one, except for the last byte in
the series. This means that every byte can at most represent 7 bits of
the overall length value. The length value bits are ordered starting with
the most significant bit. Since the length section may expand to align the
header, it may be necessary to pad the most significant bits with 0 for the
value to align properly. E.g: Type 0, Length 12 = 00000000 00001100;
Type 1, Length 1025 = 10001000 00000001; Type 0, Length 65536 =
00000100 10000000 00000000; Type 0, Length 16383 = 01111111 01111111.
For example:
00 0B 3C 70 72 65 73 65 6E 63 65 2F 3E
Would mean:
Type: 0
Value: <presence/>
Type 0 is XML, type 1 is binary. The binary type can be used in place
of base64 encoded data.
The following two transmissions are equivalent (whitespace added for clarity)
C0: <iq from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony'
C0: type='set' id='ibb1'>
C0: <data xmlns='http://jabber.org/protocol/ibb' sid='mySID' seq='0'>
C0: SGVsbG8gd29ybGQ=
C0: </data>
C0: </iq>
C0: <iq from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony'
C0: type='set' id='ibb1'>
C0: <data xmlns='http://jabber.org/protocol/ibb' sid='mySID' seq='0'>
C1: Hello world
C0: </data>
C0: </iq>
The framing protocol sits under the XML stream, however it is always above
all other layer negotiations. For example, if TLS or compression is
negotiated, then the entire interleaved stream is encrypted or compressed,
not simply the type 0 XML data. These layer negotiation protocols have an
indicator for where the new layer should begin (for example, with TLS, this
is after the final '>' of '<proceed/>'). When using interleaved, the new
layer begins after the frame containing this indicator. Since the
interleaved framing protocol has no footer, this point is mostly moot (the
last byte in the frame containing '<proceed/>' would be '>', so it works out
the same whether or not interleaved framing is used).