Http-bind polling interval check violates spec

According to XEP-0124 BOSH spec section 12 ([http://www.xmpp.org/extensions/xep-0124.html#poll]) , http-bind should check client polling interval only for “polling sessions”.A polling session is defined at the beginning of section 12. There are 2 bugs involved:

  1. Openfire checks polling interval even for non-polling sessions.

  2. Even for polling sessions , Openfire ignores the clause in section 12 which says “and if the connection manager’s response to the first request contained no stanzas."

The consequence of these bugs is unnecessary delay and breaks the essential technique of the BOSH spec which says "As soon as the client receives a response from the connection manager it sends another request, thereby ensuring that the connection manager is (almost) always holding a request that it can use to 'push' data to the client. ". A compliant client will be disconnected by Openfire http-bind incorrectly due to this incorrect check of polling interval.

To fix it, in HttpSession.java, method addConnection(), checkPollingInterval should be called only if this session is a polling session AND http-bind’s response to the last poll

request contained no stanzas.

No response from Openfire developers?

Openfire implements an older version of the XEP. http://www.xmpp.org/extensions/attic/xep-0124-1.5.html

The conditions you mention are not in this version, Openfire will behave accordingly when it is upgraded to utilized the latest version of the XEP.

I see, so this is a flaw in the old version of spec that has been fixed in the latest version.

Another minor bug: in the follwoing packet sent from http-bind, type should be “terminate”, not “terminal”:

<body type='terminal'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

By the way,the condition “policy-violation” is only in the new version, so Openfire has some new features from the latest BOSH spec.

Yes, we began the migration a while ago to the newest version but have not had teh time to completely implement it.

Cheers,

Alex

Yes, and this is incredibly annoying for any developer working on a client.

Combined with these problems of 100% CPU usage in the HTTP Bind component, deadlocks, and incomplete spec implementation has us possibly looking elsewhere. Can anyone recommend an alternate HTTP binding (proxy, hopefully, so it can at least be used with Openfire) component?

AWenckus wrote:

Openfire implements an older version of the XEP. XEP-0124: HTTP Binding

The conditions you mention are not in this version, Openfire will behave accordingly when it is upgraded to utilized the latest version of the XEP.

That spec version also states that the client “SHOULD make a new request as soon as possible.” That draft and the accepted spec work in the same way. It’s how binding was designed from the start. The client submits an empty stanza, and waits for data. Upon receiving data it immediately connects again in the same way. The problem is when 2 messages are received a couple seconds apart (for example) - the client HAS to disconnect and reconnect to see the second message. The “checkPollingInterval()” in HttpSession.java is not smart enough to handle this case.

Hey Jason,

We ran into the same problem while investigating some work for a potential client. As a potential work around instead of sending an empty stanza you can send a stanza with an empty presence packet. Such as the following:

<body rid='1249243563'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'>
   <presence></presence>
</body>

It’s not an ideal solution, and we didn’t investigate what (if any) side effects this may cause but it will keep Openfire from sending a 403 when it mistakenly thinks it is being polled too frequently.

Hope that helps,

Ryan

ryang wrote:

Hey Jason,

We ran into the same problem while investigating some work for a potential client. As a potential work around instead of sending an empty stanza you can send a stanza with an empty presence packet. Such as the following:

> 
> <body rid='1249243563'
>       sid='SomeSID'
>       xmlns='http://jabber.org/protocol/httpbind'>
>    <presence></presence>
> </body>

It’s not an ideal solution, and we didn’t investigate what (if any) side effects this may cause but it will keep Openfire from sending a 403 when it mistakenly thinks it is being polled too frequently.

Hope that helps,

Ryan

Ryan,

Although a potential, temporary solution, the problem with this is that anyone with subscription to this user will receive a presence packet. This will cause these users to have to constantly poll the BOSH server, sending more presence packets and perpetuating the problem.

Although a potential, temporary solution, the problem with this is that anyone with subscription to this user will receive a presence packet. This will cause these users to have to constantly poll the BOSH server, sending more presence packets and perpetuating the problem.

Like we’ve both said, it is just a potential, short-term solution and sending empty presence packets was the quickest way to implement it. If we had gone forward with an Openfire/BOSH solution we might have had the client send a custom iq packet to an Openfire plugin that would basically discard the packet upon receiving it.

Ideally, of course, it would nice if the spec was fully implemented within Openfire. Have you studied the Openfire code to see how close it is to being 1.5 or 1.6 compliant? Are you aware of any BOSH testing tools that could be used to speed along development of making it standards compliant?

Cheers,

Ryan

No, unfortunately (fortunately? =D) I am not a Java developer. Right now I’m actually dealing with a polling issue that is basically causing our client to appear slow because we can’t ask for data fast enough (upon login). I’m considering reverting to an older version of Openfire where I might be able to look at the way Sparkweb went about grabbing the roster so quickly.

Hmmm… I have checked the code and Openfire should only be checking the poll interval on polling connections:

From HttpSession:

if (isPoll) {
            checkPollingInterval();
        }

This is checkPollingInterval:

private void checkPollingInterval() throws HttpBindException {
        long time = System.currentTimeMillis();
        if (((time - lastPoll) / 1000) < maxPollingInterval) {
            throw new HttpBindException("Too frequent polling minimum interval is "
                    + maxPollingInterval + ", current interval " + ((time - lastPoll) / 1000),
                    BoshBindingError.policyViolation);
        }
        lastPoll = time;
    }

isPoll is determined at line 514 in HttpSession:

packetsToBeSent.size() <= 0

Alex,

The code you showed indicates that it checks only for “polling packets”, which is used by both “polling connection” and non-polling connection. My first posting has details on what exactly the spec says. If you have questions, please continue the discussion here. This is definitely a problem.

Hey Alex,

Thanks for taking the time to look into this. Looking at the spec and the code I believe that isPoll should be determined by:

getHold() == 0 || getWait() == 0

Cheers,

Ryan

Oh, sure, play the “I’m not a Java developer” card.

Yeah… not like it’d be something difficult to learn (Java) but I don’t have time to with my current project(s) =)

Ryan,

Thanks for the clarification. That makes sense.

Cheers,

Alex

I have created the following issues:

JM-1245

JM-1246

Cheers,

Alex

I’m using a javascript client with openfire http-bind and xmpp.httpbind.client.requests.polling property set to 0!file:///C:/DOCUME%7E1/Ofir/LOCALS%7E1/Temp/moz-screenshot.jpg!

I have issues with and I’m not sure if it is a client bug or related to this discussion.

Can you please explain in what circumstances the current implementation of BOSH should end a client connection and what will be written in the error log?

Is there a temporary workaround?

In my case clients are being disconnected once per few hours with no evident reason.

Thanks.