ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.36
Committed: Tue Jul 24 13:05:55 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.35: +39 -18 lines
Log Message:
changed some events to reflect the new meaning of event callback return values.

File Contents

# User Rev Content
1 elmex 1.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 elmex 1.10 use Net::XMPP2::Util qw/split_jid/;
8 elmex 1.9 use Net::XMPP2::Event;
9     use Net::XMPP2::SimpleConnection;
10 elmex 1.1 use Net::XMPP2::Namespaces qw/xmpp_ns/;
11 elmex 1.28 use Net::XMPP2::Extendable;
12 elmex 1.10 use Net::XMPP2::Error;
13 elmex 1.1 use Net::DNS;
14 elmex 1.2
15 elmex 1.28 our @ISA = qw/Net::XMPP2::SimpleConnection Net::XMPP2::Event Net::XMPP2::Extendable/;
16 elmex 1.1
17     =head1 NAME
18    
19 elmex 1.23 Net::XMPP2::Connection - XML stream that implements the XMPP RFC 3920.
20 elmex 1.1
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 elmex 1.20 =over 4
48    
49     =item B<new (%args)>
50 elmex 1.1
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 elmex 1.10 =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 elmex 1.1 =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 elmex 1.9 =item override_host => $host
87     =item override_port => $port
88    
89     This will be used as override to connect to.
90    
91 elmex 1.1 =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 elmex 1.5 =item disable_ssl => $bool
112    
113     If C<$bool> is true no SSL will be used.
114    
115 elmex 1.1 =back
116    
117     =cut
118    
119     sub new {
120     my $this = shift;
121     my $class = ref($this) || $this;
122 elmex 1.34 my $self =
123     $class->SUPER::new (
124     language => 'en',
125     stream_namespace => 'client',
126     @_
127     );
128 elmex 1.1
129     $self->{parser} = new Net::XMPP2::Parser;
130     $self->{writer} = Net::XMPP2::Writer->new (
131 elmex 1.33 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 elmex 1.1 );
136    
137     $self->{parser}->set_stanza_cb (sub {
138     $self->handle_stanza (@_);
139     });
140 elmex 1.19 $self->{parser}->set_error_cb (sub {
141 elmex 1.29 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 elmex 1.19 });
154 elmex 1.1
155 elmex 1.15 $self->{iq_id} = 1;
156     $self->{default_iq_timeout} = 60;
157 elmex 1.1
158     $self->{disconnect_cb} = sub {
159     my ($host, $port, $message) = @_;
160 elmex 1.7 delete $self->{authenticated};
161     delete $self->{ssl_enabled};
162 elmex 1.1 $self->event (disconnect => $host, $port, $message);
163     };
164    
165 elmex 1.10 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 elmex 1.28 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 elmex 1.31 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 elmex 1.28 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 elmex 1.1 return $self;
199     }
200    
201 elmex 1.20 =item B<connect ($no_srv_rr)>
202 elmex 1.1
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 elmex 1.9 if ($self->{override_host}) {
231 elmex 1.34 $host = $self->{override_host};
232     $port = $self->{override_port} if defined $self->{override_port};
233 elmex 1.1
234 elmex 1.9 } 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 elmex 1.1 }
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 elmex 1.20 =item B<may_try_connect>
259 elmex 1.1
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 elmex 1.20 =item B<reset_connect_tries>
276 elmex 1.1
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 elmex 1.5 sub debug_wrote_data {
293     my ($self, $data) = @_;
294     $self->event (debug_send => $data);
295     }
296    
297 elmex 1.1 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 elmex 1.18 if (not defined $node) { # got stream end
306     $self->disconnect ("end of 'XML' stream encountered");
307     return;
308     }
309    
310 elmex 1.31 $self->event (recv_stanza_xml => $node);
311    
312 elmex 1.1 if ($node->eq (stream => 'features')) {
313     $self->event (stream_features => $node);
314 elmex 1.28 $self->{features} = $node;
315 elmex 1.1 $self->handle_stream_features ($node);
316 elmex 1.5
317 elmex 1.2 } elsif ($node->eq (tls => 'proceed')) {
318     $self->enable_ssl;
319     $self->{parser}->init;
320     $self->{writer}->init;
321 elmex 1.34 $self->{writer}->send_init_stream (
322     $self->{language}, $self->{domain}, $self->{stream_namespace}
323     );
324 elmex 1.2
325 elmex 1.11 } elsif ($node->eq (tls => 'failure')) {
326     $self->event ('tls_error');
327     $self->disconnect ('TLS failure on TLS negotiation.');
328    
329 elmex 1.1 } elsif ($node->eq (sasl => 'challenge')) {
330     $self->handle_sasl_challenge ($node);
331 elmex 1.11
332 elmex 1.1 } elsif ($node->eq (sasl => 'success')) {
333     $self->handle_sasl_success ($node);
334 elmex 1.11
335     } elsif ($node->eq (sasl => 'failure')) {
336     my $error = Net::XMPP2::Error::SASL->new (node => $node);
337     $self->event (sasl_error => $error);
338 elmex 1.28 $self->disconnect ('SASL authentication failure: ' . $error->string);
339 elmex 1.11
340 elmex 1.1 } elsif ($node->eq (client => 'iq')) {
341 elmex 1.32 $self->event (iq_xml => $node);
342 elmex 1.1 $self->handle_iq ($node);
343 elmex 1.11
344 elmex 1.4 } elsif ($node->eq (client => 'message')) {
345 elmex 1.6 $self->event (message_xml => $node);
346 elmex 1.11
347 elmex 1.4 } elsif ($node->eq (client => 'presence')) {
348 elmex 1.6 $self->event (presence_xml => $node);
349 elmex 1.11
350 elmex 1.1 } elsif ($node->eq (stream => 'error')) {
351     $self->handle_error ($node);
352     }
353     }
354    
355 elmex 1.20 =item B<init ()>
356 elmex 1.1
357     Initiate the XML stream.
358    
359     =cut
360    
361     sub init {
362     my ($self) = @_;
363 elmex 1.34 $self->{writer}->send_init_stream ($self->{language}, $self->{domain}, $self->{stream_namespace});
364 elmex 1.1 }
365    
366 elmex 1.20 =item B<is_connected ()>
367 elmex 1.10
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 elmex 1.20 =item B<set_default_iq_timeout ($seconds)>
379 elmex 1.15
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 elmex 1.22 where the C<condition> method returns a special value (see also C<condition> method of L<Net::XMPP2::Error::IQ>).
383 elmex 1.15
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 elmex 1.20 =item B<send_iq ($type, $create_cb, $result_cb, %attrs)>
394 elmex 1.1
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 elmex 1.15 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 elmex 1.1
401 elmex 1.15 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 elmex 1.1
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 elmex 1.10 be a L<Net::XMPP2::Error::IQ> object.
408 elmex 1.1
409 elmex 1.15 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 elmex 1.4 This method returns the newly generated id for this iq request.
413    
414 elmex 1.1 =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 elmex 1.15
421     my $timeout = delete $attrs{timeout} || $self->{default_iq_timeout};
422     if ($timeout) {
423     $self->{iq_timers}->{$id} =
424 elmex 1.25 AnyEvent->timer (after => $timeout, cb => sub {
425 elmex 1.16 delete $self->{iq_timers}->{$id};
426 elmex 1.15 my $cb = delete $self->{iqs}->{$id};
427 elmex 1.16 $cb->(undef, Net::XMPP2::Error::IQ->new)
428 elmex 1.15 });
429     }
430    
431 elmex 1.1 $self->{writer}->send_iq ($id, $type, $create_cb, %attrs);
432 elmex 1.4 $id
433     }
434    
435 elmex 1.20 =item B<reply_iq_result ($req_iq_node, $create_cb, %attrs)>
436 elmex 1.4
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 elmex 1.6 Use C<$create_cb> to create the XML for the result.
444    
445 elmex 1.4 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 elmex 1.20 =item B<reply_iq_error ($req_iq_node, $error_type, $error, %attrs)>
455 elmex 1.4
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 elmex 1.22 C<write_error_tag> method of L<Net::XMPP2::Writer>.
462 elmex 1.4
463     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
464 elmex 1.6 about the meaning of C<%attrs>.
465 elmex 1.4
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 elmex 1.1 }
479    
480     sub handle_iq {
481     my ($self, $node) = @_;
482    
483 elmex 1.4 my $type = $node->attr ('type');
484    
485 elmex 1.15 my $id = $node->attr ('id');
486     delete $self->{iq_timers}->{$id} if defined $id;
487    
488 elmex 1.4 if ($type eq 'result') {
489 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
490 elmex 1.27 eval {
491     $cb->($node);
492     };
493     if ($@) { $self->event (iq_result_cb_exception => $@) }
494 elmex 1.1 }
495 elmex 1.9
496 elmex 1.4 } elsif ($type eq 'error') {
497 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
498 elmex 1.1
499 elmex 1.10 my $error = Net::XMPP2::Error::IQ->new (node => $node);
500     $cb->(($error->type eq 'continue' ? $node : undef), $error);
501 elmex 1.1 }
502 elmex 1.4
503     } else {
504     my $handled = 0;
505 elmex 1.6 $self->event ("iq_${type}_request_xml" => $node, \$handled);
506 elmex 1.4
507     my @from;
508     push @from, (to => $node->attr ('from')) if $node->attr ('from');
509    
510     unless ($handled) {
511 elmex 1.21 $self->reply_iq_error ($node, undef, 'service-unavailable', @from);
512 elmex 1.4 }
513 elmex 1.1 }
514     }
515    
516 elmex 1.12 sub send_sasl_auth {
517     my ($self, @mechs) = @_;
518 elmex 1.34
519     for (qw/username password domain/) {
520     die "No '$_' argument given to new, but '$_' is required\n"
521     unless $self->{$_};
522     }
523    
524 elmex 1.12 $self->{writer}->send_sasl_auth (
525     (join ' ', map { $_->text } @mechs),
526     $self->{username}, $self->{domain}, $self->{password}
527     );
528     }
529    
530 elmex 1.1 sub handle_stream_features {
531     my ($self, $node) = @_;
532     my @bind = $node->find_all ([qw/bind bind/]);
533 elmex 1.2 my @tls = $node->find_all ([qw/tls starttls/]);
534 elmex 1.13
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 elmex 1.1
541 elmex 1.5 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
542 elmex 1.2 $self->{writer}->send_starttls;
543    
544 elmex 1.12 } elsif (not $self->{authenticated}) {
545 elmex 1.28 my $continue = 1;
546 elmex 1.36 my (@ret) = $self->event (stream_pre_authentication => \$continue);
547     $continue = pop @ret if @ret;
548 elmex 1.28 if ($continue) {
549     $self->authenticate;
550 elmex 1.12 }
551 elmex 1.1
552     } elsif (@bind) {
553     $self->do_rebind ($self->{resource});
554     }
555     }
556    
557 elmex 1.28 =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 elmex 1.1 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 elmex 1.34 $self->{writer}->send_init_stream ($self->{language}, $self->{domain}, $self->{stream_namespace});
592 elmex 1.1 }
593    
594     sub handle_error {
595     my ($self, $node) = @_;
596 elmex 1.10 my $error = Net::XMPP2::Error::Stream->new (node => $node);
597    
598 elmex 1.18 $self->event (stream_error => $error);
599 elmex 1.1 $self->{writer}->send_end_of_stream;
600     }
601    
602 elmex 1.18 sub do_iq_auth {
603     my ($self) = @_;
604     # TODO
605     }
606    
607 elmex 1.20 =item B<send_presence ($type, $create_cb, %attrs)>
608 elmex 1.4
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 elmex 1.22 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
612 elmex 1.4
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 elmex 1.20 =item B<send_message ($to, $type, $create_cb, %attrs)>
626 elmex 1.4
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 elmex 1.22 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
630 elmex 1.4
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 elmex 1.20 =item B<do_rebind ($resource)>
644 elmex 1.1
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 elmex 1.13 my ($ret_iq, $error) = @_;
675 elmex 1.1
676 elmex 1.13 if ($error) {
677 elmex 1.28 # TODO: make bind error into a seperate error class?
678 elmex 1.30 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 elmex 1.1
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 elmex 1.36
698 elmex 1.20 =item B<jid>
699 elmex 1.1
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 elmex 1.20 =item B<features>
708 elmex 1.4
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 elmex 1.20 =back
716    
717 elmex 1.1 =head1 EVENTS
718    
719     These events can be registered on with C<reg_cb>:
720    
721     =over 4
722    
723 elmex 1.11 =item stream_features => $node
724 elmex 1.1
725 elmex 1.4 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 elmex 1.1
728 elmex 1.36 =item stream_pre_authentication
729 elmex 1.28
730     This event is emitted after TLS/SSL was initiated (if enabled) and before any
731 elmex 1.36 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 elmex 1.28
738     This event is usually used when you want to do in-band registration,
739     see also L<Net::XMPP2::Ext::Registration>.
740    
741 elmex 1.1 =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 elmex 1.28 =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 elmex 1.35 $con->reg_cb (error => sub { warn "xmpp error: " . $_[1]->string . "\n" });
755 elmex 1.28
756     Basically this event is a collect event for all other error events.
757    
758 elmex 1.10 =item stream_error => $error
759 elmex 1.6
760     This event is sent if a XML stream error occured. C<$error>
761 elmex 1.10 is a L<Net::XMPP2::Error::Stream> object.
762 elmex 1.6
763 elmex 1.28 =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 elmex 1.11 =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 elmex 1.10 =item bind_error => $error, $resource
778 elmex 1.6
779 elmex 1.10 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 elmex 1.6
784 elmex 1.10 The C<condition> of the C<$error> might be one of: 'bad-request',
785     'not-allowed' or 'conflict'.
786 elmex 1.1
787 elmex 1.20 Node: this is untested, I couldn't get the server to send a bind error
788 elmex 1.1 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 elmex 1.31 =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 elmex 1.6 =item presence_xml => $node
848 elmex 1.4
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 elmex 1.6 =item message_xml => $node
853 elmex 1.4
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 elmex 1.32 =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 elmex 1.6 =item iq_set_request_xml => $node, $handled_ref
863 elmex 1.4
864 elmex 1.6 =item iq_get_request_xml => $node, $handled_ref
865 elmex 1.4
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 C<$$handled_ref> is true an event handler should not handle this message anymore.
871    
872     If one of the event handlers handled this message the scalar pointed at by
873     the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
874     is still false after all event handlers were executed an error iq will be generated.
875    
876 elmex 1.27 =item iq_result_cb_exception => $exception
877    
878     If the C<$result_cb> of a C<send_iq> operation somehow threw a exception
879     or failed this event will be generated.
880    
881 elmex 1.36 =item send_iq_hook => $id, $type, $attrs
882 elmex 1.33
883     This event lets you add any desired number of additional create callbacks
884     to a IQ stanza that is about to be sent.
885    
886 elmex 1.36 C<$id>, C<$type> are described in the documentation of C<send_iq> of
887     L<Net::XMPP2::Writer>. C<$attrs> is the hashref to the C<%attrs> hash that can
888     be passed to C<send_iq> and also has the exact same semantics as described in
889     the documentation of C<send_iq>.
890    
891     The return values of the event callbacks are interpreted as C<$create_cb> value as
892     documented for C<send_iq>. (That means you can for example return a callback
893     that fills the IQ).
894    
895     Example:
896    
897     # this appends a <test/> element to all outgoing IQs
898     # and also a <test2/> element to all outgoing IQs
899     $con->reg_cb (send_iq_hook => sub {
900     my ($id, $type, $attrs) = @_;
901     (sub {
902     my $w = shift; # $w is a XML::Writer instance
903     $w->emptyTag ('test');
904     }, {
905     node => { name => "test2" } # see also simxml() defined in Net::XMPP2::Util
906     })
907     });
908 elmex 1.33
909 elmex 1.36 =item send_message_hook => $id, $to, $type, $attrs
910 elmex 1.33
911     This event lets you add any desired number of additional create callbacks
912     to a message stanza that is about to be sent.
913    
914     C<$id>, C<$to>, C<$type> and the hashref C<$attrs> are described in the documentation
915     for C<send_message> of L<Net::XMPP2::Writer> (C<$attrs> is C<%attrs> there).
916    
917 elmex 1.36 To actually append something you need to return something, what you need to return
918     is described in the C<send_iq_hook> event above.
919 elmex 1.33
920 elmex 1.36 =item send_presence_hook => $id, $type, $attrs
921 elmex 1.33
922     This event lets you add any desired number of additional create callbacks
923     to a presence stanza that is about to be sent.
924    
925     C<$id>, C<$type> and the hashref C<$attrs> are described in the documentation
926     for C<send_presence> of L<Net::XMPP2::Writer> (C<$attrs> is C<%attrs> there).
927    
928 elmex 1.36 To actually append something you need to return something, what you need to return
929     is described in the C<send_iq_hook> event above.
930 elmex 1.33
931 elmex 1.1 =back
932    
933     =head1 AUTHOR
934    
935 elmex 1.20 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
936 elmex 1.1
937     =head1 COPYRIGHT & LICENSE
938    
939     Copyright 2007 Robin Redeker, all rights reserved.
940    
941     This program is free software; you can redistribute it and/or modify it
942     under the same terms as Perl itself.
943    
944     =cut
945    
946     1; # End of Net::XMPP2