How not to bridge XMPP and HTTP

BOSH is a specification that defines how XMPP can be used over HTTP. It’s obviously written by people who know what they’re talking about, because they’ve got good requirements, and get into great detail about the design choices they’ve made. Unfortunately, BOSH makes the one big mistake that so many others make; treating HTTP as a transport protocol. To wit;

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

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

  <message to='friend@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
</body>

(you might also note that all of their example requests are POSTs to /webclient – a warning sign if ever there was one)

The intent of that message is to send two messages, one to each of the recipients at example.com. If we were treating HTTP as an application protocol, that would be done like this;

POST mailto:contact@example.com HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: nnn

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

POST mailto:friend@example.com HTTP/1.1
Host: httpcm.jabber.org
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: mmm

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

Alternately, if you don’t like proxies, the mailto URIs could be swapped out for an http URI specific to each mail address. But the point is that HTTP semantics be reused by recasting XMPP to them, rather than the current approach of grafting XMPP on top (read: obliterating). Don’t like two messages? Try pipelining them. Can’t pipeline? Does some other feature not map well onto HTTP in this way? Then it wasn’t meant to be.

We use HTTP (and the Web) because we want to be part of the Web; participate in the network effects, make information freely available (like, say, my presence status), etc.. We don’t do it because we need a way to get past firewalls. Good admins will avoid deploying software behind their firewall which subverts the intent of the firewall.

0 thoughts on “How not to bridge XMPP and HTTP

  1. Aadaam

    While I’m most possibly not an authoritive one, but: XMPP uses this method – as a transport method – to enable javascript applications to use presence-based technologies. HOWEVER, the original protocol works over virtual channels – which is not the case of HTTP, made for document retrieval mainly.

    Possibly the authentication part could be done with cookies, and for me it’s sometimes strange it isn’t that way. Otherwise the XMPP itself isn’t meant to be a “public” protocol: of course you can make your presence status freely available, by enabling it – either to a server side component, or a bot-like creature; both has many implementations; if you don’t enable it, XMPP respects your privacy.

    It uses HTTP as a transport protocol because HTTP isn’t a realtime, duplex, authenticated protocol, and while it’s easy to send someone a message, sometimes there are, for example, multiple recipients, etc, which are to be handled well. And because this way existing methodologies don’t need to be rewritten, which is a good thing.

    However, once there WAS a REST-interface to XMPP, it was the main module for punjab (punjab.sf.net). It isn’t used anymore somehow. But you’re still able to create your own transport method using punjab. Do you have a better idea?

Leave a Reply

Your email address will not be published. Required fields are marked *