ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.32
Committed: Wed Jul 11 18:52:07 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.31: +6 -0 lines
Log Message:
further improved devcl and added iq_xml

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.26 my $self = $class->SUPER::new (language => 'en', @_);
123 elmex 1.1
124     $self->{parser} = new Net::XMPP2::Parser;
125     $self->{writer} = Net::XMPP2::Writer->new (
126     write_cb => sub { $self->write_data ($_[0]) }
127     );
128    
129     $self->{parser}->set_stanza_cb (sub {
130     $self->handle_stanza (@_);
131     });
132 elmex 1.19 $self->{parser}->set_error_cb (sub {
133 elmex 1.29 my ($ex, $data, $type) = @_;
134     if ($type eq 'xml') {
135     my $pe = Net::XMPP2::Error::Parser->new (exception => $_[0], data => $_[1]);
136     $self->event (xml_parser_error => $pe);
137     $self->disconnect ("xml error: $_[0], $_[1]");
138     } else {
139     my $pe = Net::XMPP2::Error->new (
140     text => "uncaught exception in stanza handling: $ex"
141     );
142     $self->event (uncaught_exception_error => $pe);
143     $self->disconnect ($pe->string);
144     }
145 elmex 1.19 });
146 elmex 1.1
147 elmex 1.15 $self->{iq_id} = 1;
148     $self->{default_iq_timeout} = 60;
149 elmex 1.1
150     $self->{disconnect_cb} = sub {
151     my ($host, $port, $message) = @_;
152 elmex 1.7 delete $self->{authenticated};
153     delete $self->{ssl_enabled};
154 elmex 1.1 $self->event (disconnect => $host, $port, $message);
155     };
156    
157 elmex 1.10 if ($self->{jid}) {
158     my ($user, $host, $res) = split_jid ($self->{jid});
159     $self->{username} = $user;
160     $self->{domain} = $host;
161     $self->{resource} = $res if defined $res;
162     }
163    
164 elmex 1.7 for (qw/username password domain/) {
165     die "No '$_' argument given to new, but '$_' is required\n"
166     unless $self->{$_};
167     }
168    
169 elmex 1.28 my $proxy_cb = sub {
170     my ($self, $er) = @_;
171     $self->event (error => $er);
172     1
173     };
174    
175     $self->reg_cb (
176     xml_parser_error => $proxy_cb,
177     sasl_error => $proxy_cb,
178     stream_error => $proxy_cb,
179     bind_error => $proxy_cb,
180 elmex 1.31 iq_result_cb_exception => sub {
181     my ($self, $ex) = @_;
182     $self->event (error =>
183     Net::XMPP2::Error::Exception->new (
184     exception => $ex, context => 'iq result callback execution'
185     )
186     );
187     1
188     },
189 elmex 1.28 tls_error => sub {
190     my ($self) = @_;
191     $self->event (error =>
192     Net::XMPP2::Error->new (text => 'tls_error: tls negotiation failed')
193     );
194     1
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     ($host, $port) = ($self->{override_host}, $self->{override_port} || 5222);
232 elmex 1.1
233 elmex 1.9 } else {
234     unless ($no_srv_rr) {
235     my $res = Net::DNS::Resolver->new;
236     my $p = $res->query ('_xmpp-client._tcp.'.$host, 'SRV');
237     if ($p) {
238     my @srvs = grep { $_->type eq 'SRV' } $p->answer;
239     if (@srvs) {
240     @srvs = sort { $a->priority <=> $b->priority } @srvs;
241     @srvs = sort { $b->weight <=> $a->weight } @srvs; # TODO
242     $port = $srvs[0]->port;
243     $host = $srvs[0]->target;
244     }
245 elmex 1.1 }
246     }
247     }
248    
249     if ($self->SUPER::connect ($host, $port)) {
250     $self->event (connect => $host, $port);
251     return 1;
252     } else {
253     return undef;
254     }
255     }
256    
257 elmex 1.20 =item B<may_try_connect>
258 elmex 1.1
259     Returns the number of left alternatives of hosts to connect to for the
260     domain passed to C<new>.
261    
262     An internal list of tried hosts will be managed by C<connect> and those
263     hosts will be ignored by a SRV RR lookup (which will be done if you
264     call this function).
265    
266     Use C<reset_connect_tries> to reset the internal list of tried hosts.
267    
268     =cut
269    
270     sub may_try_connect {
271     # TODO
272     }
273    
274 elmex 1.20 =item B<reset_connect_tries>
275 elmex 1.1
276     This function resets the internal list of tried hosts for C<connect>.
277     See also C<connect>.
278    
279     =cut
280    
281     sub reset_connect_tries {
282     # TODO
283     }
284    
285     sub handle_data {
286     my ($self, $buf) = @_;
287     $self->event (debug_recv => $$buf);
288     $self->{parser}->feed (substr $$buf, 0, (length $$buf), '');
289     }
290    
291 elmex 1.5 sub debug_wrote_data {
292     my ($self, $data) = @_;
293     $self->event (debug_send => $data);
294     }
295    
296 elmex 1.1 sub write_data {
297     my ($self, $data) = @_;
298     $self->SUPER::write_data ($data);
299     }
300    
301     sub handle_stanza {
302     my ($self, $p, $node) = @_;
303    
304 elmex 1.18 if (not defined $node) { # got stream end
305     $self->disconnect ("end of 'XML' stream encountered");
306     return;
307     }
308    
309 elmex 1.31 $self->event (recv_stanza_xml => $node);
310    
311 elmex 1.1 if ($node->eq (stream => 'features')) {
312     $self->event (stream_features => $node);
313 elmex 1.28 $self->{features} = $node;
314 elmex 1.1 $self->handle_stream_features ($node);
315 elmex 1.5
316 elmex 1.2 } elsif ($node->eq (tls => 'proceed')) {
317     $self->enable_ssl;
318     $self->{parser}->init;
319     $self->{writer}->init;
320     $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
321    
322 elmex 1.11 } elsif ($node->eq (tls => 'failure')) {
323     $self->event ('tls_error');
324     $self->disconnect ('TLS failure on TLS negotiation.');
325    
326 elmex 1.1 } elsif ($node->eq (sasl => 'challenge')) {
327     $self->handle_sasl_challenge ($node);
328 elmex 1.11
329 elmex 1.1 } elsif ($node->eq (sasl => 'success')) {
330     $self->handle_sasl_success ($node);
331 elmex 1.11
332     } elsif ($node->eq (sasl => 'failure')) {
333     my $error = Net::XMPP2::Error::SASL->new (node => $node);
334     $self->event (sasl_error => $error);
335 elmex 1.28 $self->disconnect ('SASL authentication failure: ' . $error->string);
336 elmex 1.11
337 elmex 1.1 } elsif ($node->eq (client => 'iq')) {
338 elmex 1.32 $self->event (iq_xml => $node);
339 elmex 1.1 $self->handle_iq ($node);
340 elmex 1.11
341 elmex 1.4 } elsif ($node->eq (client => 'message')) {
342 elmex 1.6 $self->event (message_xml => $node);
343 elmex 1.11
344 elmex 1.4 } elsif ($node->eq (client => 'presence')) {
345 elmex 1.6 $self->event (presence_xml => $node);
346 elmex 1.11
347 elmex 1.1 } elsif ($node->eq (stream => 'error')) {
348     $self->handle_error ($node);
349 elmex 1.11
350 elmex 1.1 } else {
351     warn "Didn't understood stanza: '" . $node->name . "'";
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     $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
364     }
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     $self->{writer}->send_sasl_auth (
519     (join ' ', map { $_->text } @mechs),
520     $self->{username}, $self->{domain}, $self->{password}
521     );
522     }
523    
524 elmex 1.1 sub handle_stream_features {
525     my ($self, $node) = @_;
526     my @bind = $node->find_all ([qw/bind bind/]);
527 elmex 1.2 my @tls = $node->find_all ([qw/tls starttls/]);
528 elmex 1.13
529     # and yet another weird thingie: in XEP-0077 it's said that
530     # the register feature MAY be advertised by the server. That means:
531     # it MAY not be advertised even if it is available... so we don't
532     # care about it...
533     # my @reg = $node->find_all ([qw/register register/]);
534 elmex 1.1
535 elmex 1.5 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
536 elmex 1.2 $self->{writer}->send_starttls;
537    
538 elmex 1.12 } elsif (not $self->{authenticated}) {
539 elmex 1.28 my $continue = 1;
540     $self->event (stream_pre_authentication => \$continue);
541     if ($continue) {
542     $self->authenticate;
543 elmex 1.12 }
544 elmex 1.1
545     } elsif (@bind) {
546     $self->do_rebind ($self->{resource});
547     }
548     }
549    
550 elmex 1.28 =item B<authenticate>
551    
552     This method should be called after the C<stream_pre_authentication> event
553     was emitted to continue authentication of the stream.
554    
555     Usually this method only has to be called when you want to register before
556     you authenticate. See also the documentation of the C<stream_pre_authentication>
557     event below.
558    
559     =cut
560    
561     sub authenticate {
562     my ($self) = @_;
563     my $node = $self->{features};
564     my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
565     my @iqa = $node->find_all ([qw/iqauth auth/]);
566    
567     if (@mechs) {
568     $self->send_sasl_auth (@mechs)
569     } elsif (@iqa) {
570     $self->do_iq_auth;
571     }
572     }
573    
574 elmex 1.1 sub handle_sasl_challenge {
575     my ($self, $node) = @_;
576     $self->{writer}->send_sasl_response ($node->text);
577     }
578    
579     sub handle_sasl_success {
580     my ($self, $node) = @_;
581     $self->{authenticated} = 1;
582     $self->{parser}->init;
583     $self->{writer}->init;
584     $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
585     }
586    
587     sub handle_error {
588     my ($self, $node) = @_;
589 elmex 1.10 my $error = Net::XMPP2::Error::Stream->new (node => $node);
590    
591 elmex 1.18 $self->event (stream_error => $error);
592 elmex 1.1 $self->{writer}->send_end_of_stream;
593     }
594    
595 elmex 1.18 sub do_iq_auth {
596     my ($self) = @_;
597     # TODO
598     }
599    
600 elmex 1.20 =item B<send_presence ($type, $create_cb, %attrs)>
601 elmex 1.4
602     This method sends a presence stanza, for the meanings
603     of C<$type>, C<$create_cb> and C<%attrs> please take a look
604 elmex 1.22 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
605 elmex 1.4
606     This methods does attach an id attribute to the message stanza and
607     will return the id that was used (so you can react on possible replies).
608    
609     =cut
610    
611     sub send_presence {
612     my ($self, $type, $create_cb, %attrs) = @_;
613     my $id = $self->{iq_id}++;
614     $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
615     $id
616     }
617    
618 elmex 1.20 =item B<send_message ($to, $type, $create_cb, %attrs)>
619 elmex 1.4
620     This method sends a presence stanza, for the meanings
621     of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
622 elmex 1.22 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
623 elmex 1.4
624     This methods does attach an id attribute to the message stanza and
625     will return the id that was used (so you can react on possible replies).
626    
627     =cut
628    
629     sub send_message {
630     my ($self, $to, $type, $create_cb, %attrs) = @_;
631     my $id = $self->{iq_id}++;
632     $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
633     $id
634     }
635    
636 elmex 1.20 =item B<do_rebind ($resource)>
637 elmex 1.1
638     In case you got a C<bind_error> event and want to retry
639     binding you can call this function to set a new C<$resource>
640     and retry binding.
641    
642     If it fails again you can call this again. Becareful not to
643     end up in a loop!
644    
645     If binding was successful the C<stream_ready> event will be generated.
646    
647     =cut
648    
649     sub do_rebind {
650     my ($self, $resource) = @_;
651     $self->{resource} = $resource;
652     $self->send_iq (
653     set =>
654     sub {
655     my ($w) = @_;
656     if ($self->{resource}) {
657     $w->startTag ([xmpp_ns ('bind'), 'bind']);
658     $w->startTag ([xmpp_ns ('bind'), 'resource']);
659     $w->characters ($self->{resource});
660     $w->endTag;
661     $w->endTag;
662     } else {
663     $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
664     }
665     },
666     sub {
667 elmex 1.13 my ($ret_iq, $error) = @_;
668 elmex 1.1
669 elmex 1.13 if ($error) {
670 elmex 1.28 # TODO: make bind error into a seperate error class?
671 elmex 1.30 if ($error->xml_node ()) {
672     my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
673     $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
674     } else {
675     $self->event (bind_error => $error);
676     }
677 elmex 1.1
678     } else {
679     my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
680     my $jid = $jid[0]->text;
681     unless ($jid) { die "Got empty JID tag from server!\n" }
682     $self->{jid} = $jid;
683    
684     $self->event (stream_ready => $jid);
685     }
686     }
687     );
688     }
689    
690 elmex 1.20 =item B<jid>
691 elmex 1.1
692     After the stream has been bound to a resource the JID can be retrieved via this
693     method.
694    
695     =cut
696    
697     sub jid { $_[0]->{jid} }
698    
699 elmex 1.20 =item B<features>
700 elmex 1.4
701     Returns the last received <features> tag in form of an L<Net::XMPP2::Node> object.
702    
703     =cut
704    
705     sub features { $_[0]->{features} }
706    
707 elmex 1.20 =back
708    
709 elmex 1.1 =head1 EVENTS
710    
711     These events can be registered on with C<reg_cb>:
712    
713     =over 4
714    
715 elmex 1.11 =item stream_features => $node
716 elmex 1.1
717 elmex 1.4 This event is sent when a stream feature (<features>) tag is received. C<$node> is the
718     L<Net::XMPP2::Node> object that represents the <features> tag.
719 elmex 1.1
720 elmex 1.28 =item stream_pre_authentication => $rcontinue
721    
722     This event is emitted after TLS/SSL was initiated (if enabled) and before any
723     authentication happened. C<$rcontinue> is a reference to a scalar that per default
724     holds a true value. If that scalar is true the authentication will continue
725     after handling this event. If you set C<$$rcontinue> to a false value
726     the authentication will stop and you have to call the C<authenticate>
727     method later.
728    
729     This event is usually used when you want to do in-band registration,
730     see also L<Net::XMPP2::Ext::Registration>.
731    
732 elmex 1.1 =item stream_ready => $jid
733    
734     This event is sent if the XML stream has been established (and
735     resources have been bound) and is ready for transmitting regular stanzas.
736    
737     C<$jid> is the bound jabber id.
738    
739 elmex 1.28 =item error => $error
740    
741     This event is generated whenever some error occured.
742     C<$error> is an instance of L<Net::XMPP2::Error>.
743     Trivial error reporting may look like this:
744    
745     $con->reg_cb (error => sub { warn "xmpp error: " . $_[1]->string . "\n"; 1 });
746    
747     Basically this event is a collect event for all other error events.
748    
749 elmex 1.10 =item stream_error => $error
750 elmex 1.6
751     This event is sent if a XML stream error occured. C<$error>
752 elmex 1.10 is a L<Net::XMPP2::Error::Stream> object.
753 elmex 1.6
754 elmex 1.28 =item xml_parser_error => $error
755    
756     This event is generated whenever the parser trips over XML that it can't
757     read. C<$error> is a L<Net::XMPP2::Error::Parser> object.
758    
759 elmex 1.11 =item tls_error
760    
761     This event is emitted when a TLS error occured on TLS negotiation.
762     After this the connection will be disconnected.
763    
764     =item sasl_error => $error
765    
766     This event is emitted on SASL authentication error.
767    
768 elmex 1.10 =item bind_error => $error, $resource
769 elmex 1.6
770 elmex 1.10 This event is generated when the stream was unable to bind to
771     any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
772     object. C<$resource> is the errornous resource string or undef if none
773     was received.
774 elmex 1.6
775 elmex 1.10 The C<condition> of the C<$error> might be one of: 'bad-request',
776     'not-allowed' or 'conflict'.
777 elmex 1.1
778 elmex 1.20 Node: this is untested, I couldn't get the server to send a bind error
779 elmex 1.1 to test this.
780    
781     =item connect => $host, $port
782    
783     This event is generated when a successful connect was performed to
784     the domain passed to C<new>.
785    
786     Note: C<$host> and C<$port> might be different from the domain you passed to
787     C<new> if C<connect> performed a SRV RR lookup.
788    
789     If this connection is lost a C<disconnect> will be generated with the same
790     C<$host> and C<$port>.
791    
792     =item disconnect => $host, $port, $message
793    
794     This event is generated when the connection was lost or another error
795     occured while writing or reading from it.
796    
797     C<$message> is a humand readable error message for the failure.
798     C<$host> and C<$port> were the host and port we were connected to.
799    
800     Note: C<$host> and C<$port> might be different from the domain you passed to
801     C<new> if C<connect> performed a SRV RR lookup.
802    
803 elmex 1.31 =item recv_stanza_xml => $node
804    
805     This event is generated before any processing of a "XML" stanza happens.
806     C<$node> is the node of the stanza that is being processed, it's of
807     type L<Net::XMPP2::Node>.
808    
809     This method might not be as handy for debuggin purposes as C<debug_recv>.
810    
811     =item send_stanza_data => $data
812    
813     This event is generated shortly before data is sent to the socket.
814     C<$data> contains a complete "XML" stanza or the end of stream closing
815     tag. This method is useful for debugging purposes and I recommend
816     using XML::Twig or something like that to display it nicely.
817    
818     See also the event C<debug_send>.
819    
820     =item debug_send => $data
821    
822     This method is invoked whenever data is written out. This event
823     is mostly the same as C<send_stanza_data>.
824    
825     =item debug_recv => $data
826    
827     This method is incoked whenever a chunk of data was received.
828    
829     It works to filter C<$data> through L<XML::Twig> for debugging
830     display purposes sometimes, but as C<$data> is some arbitrary chunk
831     of bytes you might get a XML parse error (did I already mention that XMPP's
832     application of "XML" sucks?).
833    
834     So you might want to use C<recv_stanza_xml> to detect
835     complete stanzas. Unfortunately C<recv_stanza_xml> doesn't have the
836     bytes anymore and just a datastructure (L<Net::XMPP2::Node>).
837    
838 elmex 1.6 =item presence_xml => $node
839 elmex 1.4
840     This event is sent when a presence stanza is received. C<$node> is the
841     L<Net::XMPP2::Node> object that represents the <presence> tag.
842    
843 elmex 1.6 =item message_xml => $node
844 elmex 1.4
845     This event is sent when a message stanza is received. C<$node> is the
846     L<Net::XMPP2::Node> object that represents the <message> tag.
847    
848 elmex 1.32 =item iq_xml => $node
849    
850     This event is emitted when a iq stanza arrives. C<$node> is the
851     L<Net::XMPP2::Node> object that represents the <iq> tag.
852    
853 elmex 1.6 =item iq_set_request_xml => $node, $handled_ref
854 elmex 1.4
855 elmex 1.6 =item iq_get_request_xml => $node, $handled_ref
856 elmex 1.4
857     These events are sent when an iq request stanza of type 'get' or 'set' is received.
858     C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
859     object of the iq tag.
860    
861     If C<$$handled_ref> is true an event handler should not handle this message anymore.
862    
863     If one of the event handlers handled this message the scalar pointed at by
864     the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
865     is still false after all event handlers were executed an error iq will be generated.
866    
867 elmex 1.27 =item iq_result_cb_exception => $exception
868    
869     If the C<$result_cb> of a C<send_iq> operation somehow threw a exception
870     or failed this event will be generated.
871    
872 elmex 1.1 =back
873    
874     =head1 AUTHOR
875    
876 elmex 1.20 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
877 elmex 1.1
878     =head1 COPYRIGHT & LICENSE
879    
880     Copyright 2007 Robin Redeker, all rights reserved.
881    
882     This program is free software; you can redistribute it and/or modify it
883     under the same terms as Perl itself.
884    
885     =cut
886    
887     1; # End of Net::XMPP2