BOSH support

ATM this wiki page serves as notes on  GSoC 2008 project, there's also something on my  blog

relevant XEPs:  XEP-0124 - Bidirectional-streams Over Synchronous HTTP,  XEP-0206 - XMPP Over BOSH

Overview

BOSH (or HTTP binding) is a technique designed for asynchronous XMPP communication between client and server using HTTP. Unlike Jabber HTTP Polling ( XEP-0025), it uses multiple request/response pairs to improve responsiveness and to avoid unnecessary polling. Besides client and server, there is a Connection Manager entity in BOSH architecture, that serves as a mediator handling HTTP requests from clients and communicating with server. In practice, CM can be standalone HTTP server or extension of XMPP server.

Server implementations supporting BOSH

Idea

BOSH implementation should ideally concern the xmpppy library only (does anyone else use it instead of original xmpppy? No). There is one common.connection.Connection instance for each account. BOSH connection should be account-specific. Ordinar XMPP Connection has one common.xmpp.NonBlockingClient instance with certain socket wrapper. My first concept is making a BOSHClient class derived from !NBCommonClient holding NonBlockingHttp? instance(s).

existing gajim.common and xmppy classes (yellow) and suggested BOSH class (blue)

BOSHClient - handling of BOSH sessions, building the <body> element or _BOSH_() JavaScript function call with alternative syntax, wrapping the XMPP in HTTP, authentication ... if some functionality won't fit to xmpppy Client level, I will create a BOSHConnection class in a manner similar to how the ConnectionZeroconf is done. While in that, it would be nice to refactor Connection class and create abstract CommonConnection class deriving specific connection-type classes (Asterix's suggestion).

possible redesign of Connection class

TODO

  • ☑ What about connection handlers classes? Is it even possible/necessary to have all of them in all connection-types? At the moment, ConnectionZeroconf implements two of them - ConnectionVcard and ConnectionByteStream. As for BOSH, existing XMPP handlers can be used. Child stanzas from <body> are passed to dispatcher that calls appropriate handlers
  • ☑ Can existing SASL module be used for BOSH authentication?? - they can, as long as (plugged) *Client.send() will wrap sent data in body tag before putting them on wire
  • ☑ Connection._event_dispatcher is called from NonBlockingTcp?._do_receive (well via Dispatcher.Event resp. Dispatcher._eventHandler) and all received data are passed to there - in BOSH case it's whole HTTP message.. How to workaround that?? Possibly - assign other method to Dispatcher._eventHandler in BOSHClinet.StreamInit?(). Solved with callback reference in Transport constructor
  • ☑ Due to  spec it should be possible to employ two HTTP connections for one "client->ConnectionManager?" connection. Scenario: Client sends request to connection manager that doesn't support persistent connections (hence can't do pipelining either), CM forwards message to server and waits for answer. Now client wants to send another message and thus has to open another TCP connection to CM. In current xmpppy, roughly said, one TCP connection is represented by one transport class instance and only one transport of a kind can be plugged to a client.
    • New transport class for both connections (.send() and other exported methods in Transport class) to be plugged to client NonBlockingClient? or BOSHClient
      • – code duplication between the new transport class and NonBlockingTcp? -
      • + could be plugged to NonBlockingClient? - no need for BOSHClient maybe?
      • The right way - NonBlockingBOSH in xmpp/bosh.py. No code dupe with new NonBlockingTransport interface, no need for BOSHClient
    • Two NonBlockingTcp? instances owned (but not plugged to) by BOSHClient (would have to implement methods that are exported from transports).
      • would be messy
  • ☑ implement autodetect of capability of persistent HTTP connections - if Connection Manager/Proxy? force disconnect after first req-resp pair, fall back to nonpersistent connections
  • ☑ make zeroconf running again - I had to broke it during xmpppy refactoring and didn't try yet
  • ☑ make SOCKS5 proxy running again, same reason as above.
  • ☑ implement SSL connection to Conenction Mangaer. to achieve this, NonBlockingTLS has to be plugged to NonBlockingTCP and ancestors instead of to Client class.
  • ☑ better handle of disconnect - if stream terminating stanza is sent, don't allow send on any of the HTTP connections. Force disconnect after timeout.
  • ☑ BOSH over HTTP proxy, Basic Authentication
  • ☐ nonblocking getaddrinfo -  Damien Thebault's libasyncns-python
  • ☐ HTTP encodings in BOSH requests - can save some traffic
  • ☐ implement XEP-0156 - DNS TXT records about alternative connection methods
    • $ dig +short txt _xmppconnect.jabber.cz
    • either button in Accounts Config window or automatic connect when hosts from SRV fails. latter is better  comments
  • ☐ merge trunk to bosh_support branch

Attachments