[ejabberd] BOSH / IE7 hanging

Hisham Mardam Bey hisham.mardambey at gmail.com
Tue Aug 7 05:50:24 MSK 2012

Hi folks,

Our Ejabberd project uses the BOSH module coupled with StropheJS to
build a web based IM system. Everything is going great with the
exception of a little snag we hit. When we use Internet Explorer 7 to
hit the BOSH port on Ejabberd the browser spins and spins for a fair
amount of time (30 seconds or more) then finally gets its response.
This happens regardless of issuing a GET or  POST from IE7.

After some digging around I found out that its affected by the
returned HTTP headers. When I dumped the headers from a GET request to
the BOSH module I got:

  HTTP/1.0 200 OK
  Connection: keep-alive
  Content-Length: 502
  Content-Type: text/xml; charset=utf-8
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Headers: Content-Type

I served those headers to IE7 via my web server and it stalled. To be
more precise, this is what I fed it:

  HTTP/1.1 200 OK
  Vary: Accept-Encoding
  Content-Length: 502
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Content-Type: text/xml; charset=utf-8

I included the same data that is served by Ejabberd when a GET request
hits the BOSH (/http-bind/) path. When I changed those headers to the
following I got IE7 working again:

  HTTP/1.1 200 OK
  Date: Tue, 07 Aug 2012 00:43:55 GMT
  Server: Apache/2.2.20 (Ubuntu)
  X-Powered-By: PHP/5.3.6-13ubuntu3.8
  Vary: Accept-Encoding
  Content-Length: 502
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Content-Type: text/html; charset=utf-8

The main difference is the "Content-Type" from "text/xml" to
"text/html". I then sent Ejabberd properly formatted POST requests to
initiate a BOSH session and I included "Accept" headers to try to get
it to send me "text/html" back but it did not respect that.

I also dug a bunch in the Erlang code, specifically
src/web/ejabberd_http.erl around:

  "<?xml version='1.0'?>\n"

  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "


make_xhtml_output(State, Status, Headers, XHTML) ->
    Data = case lists:member(html, Headers) of
         true ->
         _ ->

after which I added the following:

    ?INFO_MSG("HEADERS=~p~nDATA=~p~n", [Headers, Data]),

So I can see the Headers and they turned out to be exactly what's in
?HEADERS defined in another hrl file.

The section above suggests that something can affect the outcome of
the headers, whether they're HTML_DOCTYPE or XHTML_DOCTYPE, and that
thing is the "html" atom that we're checking for in Headers. The
question I have is what gets that "html" into Headers? I've done a bit
more digging in the code but have not found my answer yet. Can anyone
help with this?

Also, I figured out that IE7 can't do XHTML properly as per

Thanks all! (=


Hisham Mardam-Bey

More information about the ejabberd mailing list