ejabberd_http_bind: ding dong
Posted: 25 September 2007 05:11 PM   [ Ignore ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11

Hi,http-bind developers.

I try to use last version of http-bind from svn (349 revision).
For this i use also ejabberd from svn.

I do only 3 action.

1) get sid
2) iq get auth
3) iq set auth

but after 3-th request I see that ejabberd_c2s put answer in stream, but ejabberd_http_bind dont receive it.

=INFO REPORT==== 2007-09-25 18:57:14 ===
D(<0.335.0>:ejabberd_c2s:1283) : Send XML on stream = “<iq type=‘result’ id=‘auth2’>“

=INFO REPORT==== 2007-09-25 18:57:43 ===
D(<0.333.0>:ejabberd_http_bind:529) : ding dong

As I see in sources “ding dong” places only in one place

527: handle_info({timeout, Timer, _}, _StateName,
528:      #state{timer = Timer} = StateData) ->
529:    ?DEBUG(“ding dong”, []),
530:    {stop, normal, StateData};

and cause timeout occurs, but why?

Profile
 
 
Posted: 25 September 2007 06:01 PM   [ Ignore ]   [ # 1 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  151
Joined  2006-11-12

Hello,

The problem might code from your client side implementation. Which library do you use ?

 Signature 

Mickaël Rémond
ProcessOne

Profile
 
 
Posted: 25 September 2007 10:08 PM   [ Ignore ]   [ # 2 ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11
Mickaël Rémond - 25 September 2007 06:01 PM

Hello,

The problem might code from your client side implementation. Which library do you use ?

Fo my testing purpose i use test utility jhbtest.pl from http-bind repository.

POST /http-bind/ HTTP/1.1
TE
: deflate,gzip;q=0.3
Connection
: TE, close
Host
: localhost:5280
User
-Agent: libwww-perl/5.805
Content
-Type: text/xml; charset=utf-8
Content
-Length: 150

<body content='text/xml; charset=utf-8' hold='0' rid='31974' to='myserver.com' wait='60' xml:lang='en' xmlns='http://jabber.org/protocol/httpbind'/>

HTTP/1.1 200 OK
Content
-Length: 304
Content
-Type: text/xml; charset=utf-8

<body xmlns='http://jabber.org/protocol/httpbind' sid='92593ffe6779a9a9b2903dd235d28f3ae2f1b033' wait='60' requests='1' inactivity='30' maxpause='120' polling='2' ver='1.6' from='myserver.com' secure='true' authid='88092523' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams'/>

==================

POST /http-bind/ HTTP/1.1
TE
: deflate,gzip;q=0.3
Connection
: TE, close
Host
: localhost:5280
User
-Agent: libwww-perl/5.805
Content
-Type: text/xml; charset=utf-8
Content
-Length: 211

<body rid='31975' sid='92593ffe6779a9a9b2903dd235d28f3ae2f1b033' xmlns='http://jabber.org/protocol/httpbind'><iq type='get' id='auth1'><query xmlns='jabber:iq:auth'><username>test</username></query></iq></body>

HTTP/1.1 200 OK
Content
-Length: 208
Content
-Type: text/xml; charset=utf-8

<body xmlns='http://jabber.org/protocol/httpbind'><iq xmlns='jabber:client' type='result' id='auth1'><query xmlns='jabber:iq:auth'><username>test</username><password/><digest/><resource/></query></iq></body>

=====================

POST /http-bind/ HTTP/1.1
TE
: deflate,gzip;q=0.3
Connection
: TE, close
Host
: localhost:5280
User
-Agent: libwww-perl/5.805
Content
-Type: text/xml; charset=utf-8
Content
-Length: 293

<body rid='31976' sid='92593ffe6779a9a9b2903dd235d28f3ae2f1b033' xmlns='http://jabber.org/protocol/httpbind'><iq type='set' id='auth2'><query xmlns='jabber:iq:auth'><username>test</username><digest>3f209161fac90f2318fd8610bac5c9b093184d2d</digest><resource>my</resource></query></iq></body>

HTTP/1.1 200 OK
Content
-Length: 51
Content
-Type: text/xml; charset=utf-8

<body xmlns='http://jabber.org/protocol/httpbind'/>

Profile
 
 
Posted: 26 September 2007 08:47 AM   [ Ignore ]   [ # 3 ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11

I found wrong sequence

ejabberd_http_bind:439) : really sending now: <iq type=‘set’ id=‘auth2’>....</iq>
ejabberd_receiver:280) : Received XML on stream = “<iq type=‘set’ id=‘auth2’>....</iq>“
ejabberd_http_bind:647) : OutPacket:
ejabberd_c2s:1283) : Send XML on stream = “<iq type=‘result’ id=‘auth2’>“
ejabberd_http_bind:529) : ding dong

instead of

ejabberd_http_bind:439) : really sending now: <iq type=‘set’ id=‘auth2’>....</iq>
ejabberd_receiver:280) : Received XML on stream = “<iq type=‘set’ id=‘auth2’>....</iq>“
ejabberd_c2s:1283) : Send XML on stream = “<iq type=‘result’ id=‘auth2’>“       
ejabberd_http_bind:647) : OutPacket: <iq type=‘result’ id=‘auth2’>

that is why we recieved timeout and as result
<body xmlns=‘http://jabber.org/protocol/httpbind’/>

We can fix it?

Profile
 
 
Posted: 26 September 2007 03:07 PM   [ Ignore ]   [ # 4 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  151
Joined  2006-11-12

Hello Victor,

Sorry, I do not understand what you mean here.

 Signature 

Mickaël Rémond
ProcessOne

Profile
 
 
Posted: 26 September 2007 03:47 PM   [ Ignore ]   [ # 5 ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11

it means that ejabberd_http_bind(:prepare_response function) calls before really data arrived (ejabberd_c2s:send_text function)

and as I understand “ding dong” - it is timeout event

ejabberd_http_bind module doesn’t wait for this event again

BTW when session terminated in StateData we can find lost “<iq type=‘result’...“

Profile
 
 
Posted: 26 September 2007 04:07 PM   [ Ignore ]   [ # 6 ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11

it is code of my short version http-bind util

#!/usr/bin/perl -w

use strict; # har har

use constant ERR => 0;
use
constant WARN => 1;
use
constant INFO => 2;
use
constant DEBUG => 3;

use
constant RID => 31974;

### ### ### conf ### ### ###

my $BASE_ADDRESS = "http://localhost:5280/http-bind/";
my $JABBER_SERVER = "localhost";

my $RID = RID;

my $WAIT = 60;

my $USER = "user_name";
my $UPW = "user_password";
my $RESOURCE = "user_resource";

use
Digest::SHA1;
my $sha1 = Digest::SHA1->new;
my $DIGEST;


my $DEBUG = DEBUG;

### ### ### END conf ### ### ###

# create an agent we can use for our requests
use LWP::UserAgent;
my $ua = new LWP::UserAgent();

# create a tree parser to parse response content
use XML::Parser;
my $p = new XML::Parser(Style => 'Tree');


### ### ### subs ### ### ###
sub doSend() {
    my $content
= shift;
    
    
# create a request
    
my $req = new HTTP::Request(POST => $BASE_ADDRESS);
    
$req->content_type('text/xml; charset=utf-8');
    
$req->content($content);

    
debug(DEBUG,"<< Request\n".$req->as_string."<< END Request");

    
# send request
    
my $res = $ua->request($req);

    
debug(DEBUG,">> Response\n" . $res->as_string .">> END Response");
    return
$res;
}

# getChildEls
# used to strip enclosing body element
# PARAMS: @tree - tree style array from XML::Parser
# RETURN: @children - child elements of top level element
sub getChildEls
{
    my $t
= $_[0];

    
shift @{$t->[1]};
    return @
{$t->[1]};
}

sub debug
{
    my $lvl
= shift;
    
my $msg = shift;

    return if (
$DEBUG < $lvl);

    
my $prefix = "[";
    
$prefix .= "ERROR" if ($lvl == ERR);
    
$prefix .= "WARNING" if ($lvl == WARN);
    
$prefix .= "INFO" if ($lvl == INFO);
    
$prefix .= "DEBUG" if ($lvl == DEBUG);
    
$prefix .= "] ";

    
$msg =~ s/\n/\n$prefix/g;
    print
STDERR $prefix . $msg . "\n";
}
### ### ### main ### ### ###

$| = 1; # set streaming output

my $res;

my &#xse;ss;
sub getSess
{
    $sess{rid}
= RID; # a rid to start
    
$res = &doSend("<body content='text/xml; charset=utf-8' hold='0' rid='$sess{rid}' to='$JABBER_SERVER' wait='$WAIT' xml:lang='en' xmlns='http://jabber.org/protocol/httpbind'/>");
    if (
$res->is_success) {
    my $t
= $p->parse($res->content);
    &
#xse;ss = %{$t->[1]->[0]};
    
$sess{rid} = RID; # a rid to start

    
if (defined($sess{sid}) && $sess{sid} ne "" && defined($sess{wait}) && $sess{wait} ne '' && $sess{wait} <= $WAIT) {
        debug
(INFO,"sid: $sess{sid}");
        
debug(INFO, "authid: $sess{authid}") if (defined($sess{authid}));
        
debug(INFO, "wait: $sess{wait}");
        
debug(INFO, "inactivity: $sess{inactivity}") if (defined($sess{inactivity}));
        
debug(INFO, "polling: $sess{polling}") if (defined($sess{polling}));
        
debug(INFO, "requests: $sess{requests}") if (defined($sess{requests}));
        
debug(INFO, "accept: $sess{accept}") if (defined($sess{accept}));
        
debug(INFO, "charsets: $sess{charsets}") if (defined($sess{charsets}));

        
debug (WARN, "authid missing") unless (defined($sess{authid}) && $sess{authid} ne '');
        
debug (WARN, "server indicates polling mode") if (defined($sess{requests}) && $sess{requests} == 1);
        return
1;
    
}

    }

    debug
(ERR, "sid missing") unless (defined($sess{sid}) && $sess{sid} ne "");
    
debug(ERR, "wait missing") unless (defined($sess{wait}) && $sess{wait} ne '');
    
debug(ERR, "wait bigger then requested") unless (defined($sess{wait}) && $sess{wait} ne '' && $sess{wait} <= $WAIT);

    
debug(DEBUG, $res->as_string);
    return
0;
}

sub doAuth
{
# query auth
    
$sess{rid}++;
    
$res = &doSend("<body rid='$sess{rid}' sid='$sess{sid}' xmlns='http://jabber.org/protocol/httpbind'><iq type='get' id='auth1'><query xmlns='jabber:iq:auth'><username>$USER</username></query></iq></body>");
    
my @els = (&getChildEls($p->parse($res->content)));
    
unless ($els[0] eq 'iq' && $els[1]->[0]->{'type'} eq 'result') {
    debug
(ERR, $res->content);
    return
0;
    
}
     
# send auth
    
$sess{rid}++;
    
$sha1->add($sess{authid}, $UPW);
    
$DIGEST = $sha1->hexdigest;
    
$res = &doSend("<body rid='$sess{rid}' sid='$sess{sid}' xmlns='http://jabber.org/protocol/httpbind'><iq type='set' id='auth2'><query xmlns='jabber:iq:auth'><username>$USER</username><digest>$DIGEST</digest><resource>$RESOURCE</resource></query></iq></body>");
    @
els = (&getChildEls($p->parse($res->content)));
    
unless ($els[0] eq 'iq' && $els[1]->[0]->{'type'} eq 'result') {
        debug
(ERR, $res->content);
        return
0;
    
}

    
return 1;
}

sub doPoll
{
    $sess{rid}
++;
    return &
doSend("<body rid='$sess{rid}' sid='$sess{sid}' xmlns='http://jabber.org/protocol/httpbind'/>");
}


print "Create a new session: ";
if (&
getSess()) {
    
print "OK.\n";
} else {
    debug
(ERR, "Aborting.");
    exit(
1);
}

print "Authenticating: ";
if (&
doAuth()) {
    
print "OK.\n";
} else {
    
print "FAILED!\n";
    
debug(ERR, "Aborting.");
    exit(
1);
}

# disconnect
print "logout\n";
$sess{rid}++;
$res = &doSend("<body rid='$sess{rid}' sid='$sess{sid}' type='terminate' xmlns='http://jabber.org/protocol/httpbind'><presence type='unavailable'/></body>");
debug(INFO, $res->content);

print
"Checking if session terminated: ";
$res = &doPoll();
if (
$res->code != 404) {
    
print "FAILED!\n";
    
debug(ERR, "Aborting.");
    exit(
1);    
}
print "OK.\n";

Profile
 
 
Posted: 27 September 2007 09:43 AM   [ Ignore ]   [ # 7 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  151
Joined  2006-11-12

You should try with a real client such as JWChat. To my understandng the client code is not correct.

 Signature 

Mickaël Rémond
ProcessOne

Profile
 
 
Posted: 27 September 2007 09:37 PM   [ Ignore ]   [ # 8 ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11

i don’t understand why? and what is the difference if you can see xml packets?
my tests show me that after revision 243 ejabberd_http_bind was modified and not work properly.

It is only one reason why it can works incorrect is it - we use higher(?) version other modules ejabberd.
Tell me please what is your revision number of ejabberd? I will test


And which version of jwchat you propose to use?

Today(28.09) I make many test with last (and not) revision of ejabberd and http_bind, but result it still negative. It doesn’t work properly.

Profile
 
 
Posted: 29 September 2007 08:49 AM   [ Ignore ]   [ # 9 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  151
Joined  2006-11-12

My view is that your client is wrong.
http bind has been updated to support the new version of the spec (now called Bosh: http://www.xmpp.org/extensions/xep-0124.html).

To my knowledge, the test Perl client has not been updated. That come back to my initial suggestion: Use a real client known to work with it such as JWchat for example.

 Signature 

Mickaël Rémond
ProcessOne

Profile
 
 
Posted: 02 October 2007 03:56 PM   [ Ignore ]   [ # 10 ]
Newbie
Rank
Total Posts:  27
Joined  2007-04-11

in my case it was mistake behaviour in ejabberd_http_bind was

start(Sid, Key) ->
    
Result = mnesia:create_table(http_bind,
                        
[{ram_copies, [node()]},
                         
{attributes, record_info(fields, http_bind)}]),

here create_table return already exists, but in old version http_bind table was 5 fields, and in
new version we have 6

and as result in

process_request(Data) ->
...
mnesia:transaction(
                      
fun() ->
                              
mnesia:write(
                                
#http_bind{id = Sid,
                                           
pid = Pid,
                                           
to = {XmppDomain, XmppVersion},
                                           
hold = Hold,
                                           
wait = Wait,
                                           
version = Version
                                          }
)
                      
end),


return {aborted, bad_args}

but in this plase of code no check on error!

and as result session was created but next request not find any linked recored in http_bind table…

So, I think question can be closed.

Profile
 
 
Posted: 02 October 2007 04:00 PM   [ Ignore ]   [ # 11 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  151
Joined  2006-11-12

Yes, but remember you are using development version of unreleased code. This version is supposed to be deployed on a clean instance, yes.

 Signature 

Mickaël Rémond
ProcessOne

Profile
 
 
Posted: 11 October 2007 10:40 AM   [ Ignore ]   [ # 12 ]
Newbie
Rank
Total Posts:  1
Joined  2007-10-11

Hi,
I did the following during installation..
Ejabberd - ejabberd.cfg file
{Listen, [
...
{5280, ejabberd_http, [http-poll, http_bind, web_admin]},
...
]}

and

{modules, [
...
{mod_yaws, [
{logdir, “/tmp/“},
{servers, [
{“QKAN00191117A”, 5224,
“C:\Program Files/Apache Software Foundation/Tomcat 6.0/webapps/www/“,
[{dir_listing, true}, {ip, {127, 0, 0, 1}}]
}
]}
]},
..
]}

I am using Apache tomcat..and I deployed the JabberHttpBind-1.1
This is working fine and I am getting the following msg..


Jabber HTTP Binding Servlet v1.1
This is an implementation of JEP-0124 (HTTP-Binding). Please see http://www.jabber.org/jeps/jep-0124.html for details.

Active sessions: 0
“ I copied the www directory of the yaws in the webapps directory of tomcat..Then I have in my mukl the following settings in config.js,

var BACKENDTYPE = ‘binding’;
var HTTPBASE = “/tomcat/JabberHTTPBind-1.1/“;
var XMPPDOMAIN = “QKAN00191117A”;
var timerval = 2000;

Then the .htaccess file in MUCKl has the following settings..

RewriteEngine On
RewriteRule http-poll/ http://QKAN00191117A:5280/http-poll/ [P]
RewriteRule http-bind/ http://QKAN00191117A:5280/JabberHTTPBind-1.1/ [P]

and when I open the multi user chat by..

http://localhost:8080/www/muckl

I am getting the following error..

“Internal Server error
Reconnect
Ok / cancel

The muckl debugger says..
level 1
no body element or incorrect body in initial response

and the error report was..

=ERROR REPORT==== 2007-10-11 11:36:44 ===
E(<0.36.0>:gen_mod:47): {undef,
                  [{mod_yaws,
                      start,
                      [“qkan00191117a”,
                      [{logdir,“/tmp/“},
                        {servers,
                          [{“QKAN00191117A”,
                            5224,
                            “C:Program Files/Apache Software Foundation/Tomcat 6.0/webapps/www/“,
                            [{dir_listing,true},
&nbs