ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.19
Committed: Tue Jun 26 08:33:07 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.18: +4 -0 lines
Log Message:
added xml parser error callback

File Contents

# Content
1 package Net::XMPP2::Connection;
2 use strict;
3 use AnyEvent;
4 use IO::Socket::INET;
5 use Net::XMPP2::Parser;
6 use Net::XMPP2::Writer;
7 use Net::XMPP2::Util qw/split_jid/;
8 use Net::XMPP2::Event;
9 use Net::XMPP2::SimpleConnection;
10 use Net::XMPP2::Namespaces qw/xmpp_ns/;
11 use Net::XMPP2::Error;
12 use Net::DNS;
13
14 our @ISA = qw/Net::XMPP2::SimpleConnection Net::XMPP2::Event/;
15
16 =head1 NAME
17
18 Net::XMPP2::Connection - A XML stream that implements the XMPP RFC 3920.
19
20 =head1 SYNOPSIS
21
22 use Net::XMPP2::Connection;
23
24 my $con =
25 Net::XMPP2::Connection->new (
26 username => "abc",
27 domain => "jabber.org",
28 resource => "Net::XMPP2"
29 );
30
31 $con->connect or die "Couldn't connect to jabber.org: $!";
32 $con->init;
33 $con->reg_cb (stream_ready => sub { print "XMPP stream ready!\n" });
34
35 =head1 DESCRIPTION
36
37 This module represents a XMPP stream as described in RFC 3920. You can issue the basic
38 XMPP XML stanzas with methods like C<send_iq>, C<send_message> and C<send_presence>.
39
40 And receive events with the C<reg_cb> event framework from the connection.
41
42 If you need instant messaging stuff please take a look at C<Net::XMPP2::IM::Connection>.
43
44 =head1 METHODS
45
46 =head2 new (%args)
47
48 Following arguments can be passed in C<%args>:
49
50 =over 4
51
52 =item language => $tag
53
54 This should be the language of the human readable contents that
55 will be transmitted over the stream. The default will be 'en'.
56
57 Please look in RFC 3066 how C<$tag> should look like.
58
59 =item jid => $jid
60
61 This can be used to set the settings C<username>, C<domain>
62 (and optionally C<resource>) from a C<$jid>.
63
64 =item register => $mode
65
66 If this settings is given this connection will attempt to register
67 an account in band on the server if C<$mode> is 'auto'.
68
69 If C<$mode> is 'manual' the event C<in_band_register_form> will be
70 emitted (see also EVENTS documentation about the arguments of that
71 event, and how to continue the login procedure).
72
73 =item resource => $resource
74
75 If this argument is given C<$resource> will be passed as desired
76 resource on resource binding.
77
78 Note: You have to take care that the stringprep profile for
79 resources can be applied at: C<$resource>. Otherwise the server
80 might signal an error. See L<Net::XMPP2::Util> for utility functions
81 to check this.
82
83 =item domain => $domain
84
85 This is the destination host we are going to connect to.
86 As the connection won't be automatically connected use C<connect>
87 to initiate the connect.
88
89 Note: A SRV RR lookup will be performed to discover the real hostname
90 and port to connect to. See also C<connect>.
91
92 =item override_host => $host
93 =item override_port => $port
94
95 This will be used as override to connect to.
96
97 =item port => $port
98
99 This is optional, the default port is 5222.
100
101 Note: A SRV RR lookup will be performed to discover the real hostname
102 and port to connect to. See also C<connect>.
103
104 =item username => $username
105
106 This is your C<$username> (the userpart in the JID);
107
108 Note: You have to take care that the stringprep profile for
109 nodes can be applied at: C<$username>. Otherwise the server
110 might signal an error. See L<Net::XMPP2::Util> for utility functions
111 to check this.
112
113 =item password => $password
114
115 This is the password for the C<username> above.
116
117 =item disable_ssl => $bool
118
119 If C<$bool> is true no SSL will be used.
120
121 =back
122
123 =cut
124
125 sub new {
126 my $this = shift;
127 my $class = ref($this) || $this;
128 my $self = { language => 'en', @_ };
129 bless $self, $class;
130
131 $self->{parser} = new Net::XMPP2::Parser;
132 $self->{writer} = Net::XMPP2::Writer->new (
133 write_cb => sub { $self->write_data ($_[0]) }
134 );
135
136 $self->{parser}->set_stanza_cb (sub {
137 $self->handle_stanza (@_);
138 });
139 $self->{parser}->set_error_cb (sub {
140 $self->event (xml_parser_error => $_[0], $_[1]);
141 $self->disconnect ("xml error: $_[0], $_[1]");
142 });
143
144 $self->{iq_id} = 1;
145 $self->{default_iq_timeout} = 60;
146
147 $self->{disconnect_cb} = sub {
148 my ($host, $port, $message) = @_;
149 delete $self->{authenticated};
150 delete $self->{ssl_enabled};
151 $self->event (disconnect => $host, $port, $message);
152 };
153
154 if ($self->{jid}) {
155 my ($user, $host, $res) = split_jid ($self->{jid});
156 $self->{username} = $user;
157 $self->{domain} = $host;
158 $self->{resource} = $res if defined $res;
159 }
160
161 for (qw/username password domain/) {
162 die "No '$_' argument given to new, but '$_' is required\n"
163 unless $self->{$_};
164 }
165
166 return $self;
167 }
168
169 =head2 connect ($no_srv_rr)
170
171 Try to connect to the domain and port passed in C<new>.
172
173 A SRV RR lookup will be performed on the domain to discover
174 the host and port to use. If you don't want this set C<$no_srv_rr>
175 to a true value. C<$no_srv_rr> is false by default.
176
177 As the SRV RR lookup might return multiple host and you fail to
178 connect to one you might just call this function again to try a
179 different host.
180
181 If C<connect> was successful and we connected a true value is returned.
182 If the connect was unsuccessful undef is returned and C<$!> will be set
183 to the error that occured while connecting.
184
185 If you want to know whether further connection attempts might be more
186 successful (as SRV RR lookup may return multiple hosts) call C<may_try_connect>
187 (see also C<may_try_connect>).
188
189 Note that an internal list will be kept of tried hosts. Use
190 C<reset_connect_tries> to reset the internal list of tried hosts.
191
192 =cut
193
194 sub connect {
195 my ($self, $no_srv_rr) = @_;
196
197 my ($host, $port) = ($self->{domain}, $self->{port} || 5222);
198 if ($self->{override_host}) {
199 ($host, $port) = ($self->{override_host}, $self->{override_port} || 5222);
200
201 } else {
202 unless ($no_srv_rr) {
203 my $res = Net::DNS::Resolver->new;
204 my $p = $res->query ('_xmpp-client._tcp.'.$host, 'SRV');
205 if ($p) {
206 my @srvs = grep { $_->type eq 'SRV' } $p->answer;
207 if (@srvs) {
208 @srvs = sort { $a->priority <=> $b->priority } @srvs;
209 @srvs = sort { $b->weight <=> $a->weight } @srvs; # TODO
210 $port = $srvs[0]->port;
211 $host = $srvs[0]->target;
212 }
213 }
214 }
215 }
216
217 if ($self->SUPER::connect ($host, $port)) {
218 $self->event (connect => $host, $port);
219 return 1;
220 } else {
221 return undef;
222 }
223 }
224
225 =head2 may_try_connect
226
227 Returns the number of left alternatives of hosts to connect to for the
228 domain passed to C<new>.
229
230 An internal list of tried hosts will be managed by C<connect> and those
231 hosts will be ignored by a SRV RR lookup (which will be done if you
232 call this function).
233
234 Use C<reset_connect_tries> to reset the internal list of tried hosts.
235
236 =cut
237
238 sub may_try_connect {
239 # TODO
240 }
241
242 =head2 reset_connect_tries
243
244 This function resets the internal list of tried hosts for C<connect>.
245 See also C<connect>.
246
247 =cut
248
249 sub reset_connect_tries {
250 # TODO
251 }
252
253 sub handle_data {
254 my ($self, $buf) = @_;
255 $self->event (debug_recv => $$buf);
256 $self->{parser}->feed (substr $$buf, 0, (length $$buf), '');
257 }
258
259 sub debug_wrote_data {
260 my ($self, $data) = @_;
261 $self->event (debug_send => $data);
262 }
263
264 sub write_data {
265 my ($self, $data) = @_;
266 $self->SUPER::write_data ($data);
267 }
268
269 sub handle_stanza {
270 my ($self, $p, $node) = @_;
271
272 if (not defined $node) { # got stream end
273 $self->disconnect ("end of 'XML' stream encountered");
274 return;
275 }
276
277 if ($node->eq (stream => 'features')) {
278 $self->event (stream_features => $node);
279 $self->handle_stream_features ($node);
280 $self->{features} = $node;
281
282 } elsif ($node->eq (tls => 'proceed')) {
283 $self->enable_ssl;
284 $self->{parser}->init;
285 $self->{writer}->init;
286 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
287
288 } elsif ($node->eq (tls => 'failure')) {
289 $self->event ('tls_error');
290 $self->disconnect ('TLS failure on TLS negotiation.');
291
292 } elsif ($node->eq (sasl => 'challenge')) {
293 $self->handle_sasl_challenge ($node);
294
295 } elsif ($node->eq (sasl => 'success')) {
296 $self->handle_sasl_success ($node);
297
298 } elsif ($node->eq (sasl => 'failure')) {
299 my $error = Net::XMPP2::Error::SASL->new (node => $node);
300 $self->event (sasl_error => $error);
301
302 } elsif ($node->eq (client => 'iq')) {
303 $self->handle_iq ($node);
304
305 } elsif ($node->eq (client => 'message')) {
306 $self->event (message_xml => $node);
307
308 } elsif ($node->eq (client => 'presence')) {
309 $self->event (presence_xml => $node);
310
311 } elsif ($node->eq (stream => 'error')) {
312 $self->handle_error ($node);
313
314 } else {
315 warn "Didn't understood stanza: '" . $node->name . "'";
316 }
317 }
318
319 =head2 init ()
320
321 Initiate the XML stream.
322
323 =cut
324
325 sub init {
326 my ($self) = @_;
327 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
328 }
329
330 =head2 is_connected ()
331
332 Returns true if the connection is still connected and stanzas can be
333 sent.
334
335 =cut
336
337 sub is_connected {
338 my ($self) = @_;
339 $self->{authenticated}
340 }
341
342 =head2 set_default_iq_timeout ($seconds)
343
344 This sets the default timeout for IQ requests. If the timeout runs out
345 the request will be aborted and the callback called with a L<Net::XMPP2::Error::IQ> object
346 where the C<condition> method returns a special value (see also L<Net::XMPP2::Error::IQ::condition>).
347
348 The default timeout for IQ is 60 seconds.
349
350 =cut
351
352 sub set_default_iq_timeout {
353 my ($self, $sec) = @_;
354 $self->{default_iq_timeout} = $sec;
355 }
356
357 =head2 send_iq ($type, $create_cb, $result_cb, %attrs)
358
359 This method sends an IQ XMPP request.
360
361 Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
362 about the meaning of C<$type>, C<$create_cb> and C<%attrs> (with the exception
363 of the 'timeout' key of C<%attrs>, see below).
364
365 C<$result_cb> will be called when a result was received or the timeout reached.
366 The first argument to C<$result_cb> will be a Net::XMPP2::Node instance
367 containing the IQ result stanza contents.
368
369 If the IQ resulted in a stanza error the second argument to C<$result_cb> will
370 be C<undef> (if the error type was not 'continue') and the third argument will
371 be a L<Net::XMPP2::Error::IQ> object.
372
373 The timeout can be set by C<set_default_iq_timeout> or passed seperatly
374 in the C<%attrs> array as the value for the key C<timeout> (timeout in seconds btw.).
375
376 This method returns the newly generated id for this iq request.
377
378 =cut
379
380 sub send_iq {
381 my ($self, $type, $create_cb, $result_cb, %attrs) = @_;
382 my $id = $self->{iq_id}++;
383 $self->{iqs}->{$id} = $result_cb;
384
385 my $timeout = delete $attrs{timeout} || $self->{default_iq_timeout};
386 if ($timeout) {
387 $self->{iq_timers}->{$id} =
388 AnyEvent->timer (after => $timeout, sub {
389 delete $self->{iq_timers}->{$id};
390 my $cb = delete $self->{iqs}->{$id};
391 $cb->(undef, Net::XMPP2::Error::IQ->new)
392 });
393 }
394
395 $self->{writer}->send_iq ($id, $type, $create_cb, %attrs);
396 $id
397 }
398
399 =head2 reply_iq_result ($req_iq_node, $create_cb, %attrs)
400
401 This method will generate a result reply to the iq request C<Net::XMPP2::Node>
402 in C<$req_iq_node>.
403
404 Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
405 about the meaning C<$create_cb> and C<%attrs>.
406
407 Use C<$create_cb> to create the XML for the result.
408
409 The type for this iq reply is 'result'.
410
411 =cut
412
413 sub reply_iq_result {
414 my ($self, $iqnode, $create_cb, %attrs) = @_;
415 $self->{writer}->send_iq ($iqnode->attr ('id'), 'result', $create_cb, %attrs);
416 }
417
418 =head2 reply_iq_error ($req_iq_node, $error_type, $error, %attrs)
419
420 This method will generate an error reply to the iq request C<Net::XMPP2::Node>
421 in C<$req_iq_node>.
422
423 C<$error_type> is one of 'cancel', 'continue', 'modify', 'auth' and 'wait'.
424 C<$error> is one of the defined error conditions described in
425 L<Net::XMPP2::Writer::write_error_tag>.
426
427 Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
428 about the meaning of C<%attrs>.
429
430 The type for this iq reply is 'error'.
431
432 =cut
433
434 sub reply_iq_error {
435 my ($self, $iqnode, $errtype, $error, %attrs) = @_;
436
437 $self->{writer}->send_iq (
438 $iqnode->attr ('id'), 'error',
439 sub { $self->{writer}->write_error_tag ($iqnode, $errtype, $error) },
440 %attrs
441 );
442 }
443
444 sub handle_iq {
445 my ($self, $node) = @_;
446
447 my $type = $node->attr ('type');
448
449 my $id = $node->attr ('id');
450 delete $self->{iq_timers}->{$id} if defined $id;
451
452 if ($type eq 'result') {
453 if (my $cb = delete $self->{iqs}->{$id}) {
454 $cb->($node);
455 }
456
457 } elsif ($type eq 'error') {
458 if (my $cb = delete $self->{iqs}->{$id}) {
459
460 my $error = Net::XMPP2::Error::IQ->new (node => $node);
461 $cb->(($error->type eq 'continue' ? $node : undef), $error);
462 }
463
464 } else {
465 my $handled = 0;
466 $self->event ("iq_${type}_request_xml" => $node, \$handled);
467
468 my @from;
469 push @from, (to => $node->attr ('from')) if $node->attr ('from');
470
471 unless ($handled) {
472 $self->reply_iq_error ($node, undef, 'feature-not-implemented', @from);
473 }
474 }
475 }
476
477 sub send_sasl_auth {
478 my ($self, @mechs) = @_;
479 $self->{writer}->send_sasl_auth (
480 (join ' ', map { $_->text } @mechs),
481 $self->{username}, $self->{domain}, $self->{password}
482 );
483 }
484
485 =head2 request_inband_register_form ($finish_cb)
486
487 This method starts a in-band-registration attempt. When finished C<$finish_cb>
488 will be called with the first argument being a L<Net::XMPP2::Ext::RegisterForm>
489 object (will be undef if an error occured) and the second an optional error
490 object of type L<Net::XMPP2::Error::Ext::Register> if an error occured.
491
492 =cut
493
494 sub request_inband_register_form {
495 my ($self, $finish_cb) = @_;
496
497 $self->send_iq (
498 get =>
499 sub {
500 my ($w) = @_;
501 $w->addPrefix (xmpp_ns ('register'), '');
502 $w->emptyTag ([qw/register query/]);
503 },
504 sub {
505 my ($node, $error) = @_;
506 my $form;
507 $form = Net::XMPP2::Ext::RegisterForm (node => $node, connection => $self)
508 unless $error;
509 $finish_cb->($form, $error);
510 }
511 );
512 }
513
514 sub do_auto_register {
515 my ($self, $mechs) = @_;
516
517 $self->request_inband_register_form (sub {
518 my ($form, $error) = @_;
519
520 if ($error) {
521 $self->event (in_band_register_error => $error);
522
523 } else {
524 if ($self->{register} ne 'manual') {
525 # of course this blows up if the form was more complicated
526 # any ideas?
527 $form->auto_submit (
528 username => $self->{username},
529 password => $self->{password},
530 cb => sub {
531 my ($form, $error) = @_;
532 if ($error) {
533 $self->event (auto_in_band_register_error => $error);
534 } else {
535 $self->event ('auto_in_band_register_ok');
536 $self->send_sasl_auth (@$mechs) if @$mechs;
537 }
538 }
539 );
540
541 } else {
542 $self->event (
543 in_band_register_form =>
544 $form,
545 sub { $self->send_sasl_auth (@$mechs) if @$mechs }
546 )
547 }
548 }
549 });
550
551 }
552
553 sub handle_stream_features {
554 my ($self, $node) = @_;
555 my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
556 my @bind = $node->find_all ([qw/bind bind/]);
557 my @tls = $node->find_all ([qw/tls starttls/]);
558 my @iqa = $node->find_all ([qw/iqauth auth/]);
559
560 # and yet another weird thingie: in XEP-0077 it's said that
561 # the register feature MAY be advertised by the server. That means:
562 # it MAY not be advertised even if it is available... so we don't
563 # care about it...
564 # my @reg = $node->find_all ([qw/register register/]);
565
566 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
567 $self->{writer}->send_starttls;
568
569 } elsif (not $self->{authenticated}) {
570 if ($self->{register}) {
571 $self->do_auto_register (\@mechs);
572 } elsif (@mechs) {
573 $self->send_sasl_auth (@mechs)
574 } elsif (@iqa) {
575 $self->do_iq_auth;
576 }
577
578 } elsif (@bind) {
579 $self->do_rebind ($self->{resource});
580 }
581 }
582
583 sub handle_sasl_challenge {
584 my ($self, $node) = @_;
585 $self->{writer}->send_sasl_response ($node->text);
586 }
587
588 sub handle_sasl_success {
589 my ($self, $node) = @_;
590 $self->{authenticated} = 1;
591 $self->{parser}->init;
592 $self->{writer}->init;
593 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
594 }
595
596 sub handle_error {
597 my ($self, $node) = @_;
598 my $error = Net::XMPP2::Error::Stream->new (node => $node);
599
600 $self->event (stream_error => $error);
601 $self->{writer}->send_end_of_stream;
602 }
603
604 sub do_iq_auth {
605 my ($self) = @_;
606 # TODO
607 }
608
609 =head2 send_presence ($type, $create_cb, %attrs)
610
611 This method sends a presence stanza, for the meanings
612 of C<$type>, C<$create_cb> and C<%attrs> please take a look
613 at the documentation for L<Net::XMPP2::Writer::send_presence>.
614
615 This methods does attach an id attribute to the message stanza and
616 will return the id that was used (so you can react on possible replies).
617
618 =cut
619
620 sub send_presence {
621 my ($self, $type, $create_cb, %attrs) = @_;
622 my $id = $self->{iq_id}++;
623 $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
624 $id
625 }
626
627 =head2 send_message ($to, $type, $create_cb, %attrs)
628
629 This method sends a presence stanza, for the meanings
630 of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
631 at the documentation for L<Net::XMPP2::Writer::send_message>.
632
633 This methods does attach an id attribute to the message stanza and
634 will return the id that was used (so you can react on possible replies).
635
636 =cut
637
638 sub send_message {
639 my ($self, $to, $type, $create_cb, %attrs) = @_;
640 my $id = $self->{iq_id}++;
641 $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
642 $id
643 }
644
645 =head2 do_rebind ($resource)
646
647 In case you got a C<bind_error> event and want to retry
648 binding you can call this function to set a new C<$resource>
649 and retry binding.
650
651 If it fails again you can call this again. Becareful not to
652 end up in a loop!
653
654 If binding was successful the C<stream_ready> event will be generated.
655
656 =cut
657
658 sub do_rebind {
659 my ($self, $resource) = @_;
660 $self->{resource} = $resource;
661 $self->send_iq (
662 set =>
663 sub {
664 my ($w) = @_;
665 if ($self->{resource}) {
666 $w->startTag ([xmpp_ns ('bind'), 'bind']);
667 $w->startTag ([xmpp_ns ('bind'), 'resource']);
668 $w->characters ($self->{resource});
669 $w->endTag;
670 $w->endTag;
671 } else {
672 $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
673 }
674 },
675 sub {
676 my ($ret_iq, $error) = @_;
677
678 if ($error) {
679 my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
680 $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
681
682 } else {
683 my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
684 my $jid = $jid[0]->text;
685 unless ($jid) { die "Got empty JID tag from server!\n" }
686 $self->{jid} = $jid;
687
688 $self->event (stream_ready => $jid);
689 }
690 }
691 );
692 }
693
694 =head2 jid
695
696 After the stream has been bound to a resource the JID can be retrieved via this
697 method.
698
699 =cut
700
701 sub jid { $_[0]->{jid} }
702
703 =head2 features
704
705 Returns the last received <features> tag in form of an L<Net::XMPP2::Node> object.
706
707 =cut
708
709 sub features { $_[0]->{features} }
710
711 =head1 EVENTS
712
713 These events can be registered on with C<reg_cb>:
714
715 =over 4
716
717 =item stream_features => $node
718
719 This event is sent when a stream feature (<features>) tag is received. C<$node> is the
720 L<Net::XMPP2::Node> object that represents the <features> tag.
721
722 =item stream_ready => $jid
723
724 This event is sent if the XML stream has been established (and
725 resources have been bound) and is ready for transmitting regular stanzas.
726
727 C<$jid> is the bound jabber id.
728
729 =item stream_error => $error
730
731 This event is sent if a XML stream error occured. C<$error>
732 is a L<Net::XMPP2::Error::Stream> object.
733
734 =item tls_error
735
736 This event is emitted when a TLS error occured on TLS negotiation.
737 After this the connection will be disconnected.
738
739 =item sasl_error => $error
740
741 This event is emitted on SASL authentication error.
742
743 =item bind_error => $error, $resource
744
745 This event is generated when the stream was unable to bind to
746 any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
747 object. C<$resource> is the errornous resource string or undef if none
748 was received.
749
750 The C<condition> of the C<$error> might be one of: 'bad-request',
751 'not-allowed' or 'conflict'.
752
753 Node: this is untested, i couldn't get the server to send a bind error
754 to test this.
755
756 =item connect => $host, $port
757
758 This event is generated when a successful connect was performed to
759 the domain passed to C<new>.
760
761 Note: C<$host> and C<$port> might be different from the domain you passed to
762 C<new> if C<connect> performed a SRV RR lookup.
763
764 If this connection is lost a C<disconnect> will be generated with the same
765 C<$host> and C<$port>.
766
767 =item disconnect => $host, $port, $message
768
769 This event is generated when the connection was lost or another error
770 occured while writing or reading from it.
771
772 C<$message> is a humand readable error message for the failure.
773 C<$host> and C<$port> were the host and port we were connected to.
774
775 Note: C<$host> and C<$port> might be different from the domain you passed to
776 C<new> if C<connect> performed a SRV RR lookup.
777
778 =item presence_xml => $node
779
780 This event is sent when a presence stanza is received. C<$node> is the
781 L<Net::XMPP2::Node> object that represents the <presence> tag.
782
783 =item message_xml => $node
784
785 This event is sent when a message stanza is received. C<$node> is the
786 L<Net::XMPP2::Node> object that represents the <message> tag.
787
788 =item iq_set_request_xml => $node, $handled_ref
789
790 =item iq_get_request_xml => $node, $handled_ref
791
792 These events are sent when an iq request stanza of type 'get' or 'set' is received.
793 C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
794 object of the iq tag.
795
796 If C<$$handled_ref> is true an event handler should not handle this message anymore.
797
798 If one of the event handlers handled this message the scalar pointed at by
799 the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
800 is still false after all event handlers were executed an error iq will be generated.
801
802 =back
803
804 =head1 AUTHOR
805
806 Robin Redeker, C<< <elmex at ta-sa.org> >>
807
808 =head1 COPYRIGHT & LICENSE
809
810 Copyright 2007 Robin Redeker, all rights reserved.
811
812 This program is free software; you can redistribute it and/or modify it
813 under the same terms as Perl itself.
814
815 =cut
816
817 1; # End of Net::XMPP2