ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.37
Committed: Wed Jul 25 13:53:33 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.36: +8 -10 lines
Log Message:
implemented OOB and fixed bugs in Disco and further developed in band registration.

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