ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Handle.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Handle.pm (file contents):
Revision 1.20 by elmex, Sat May 24 08:16:50 2008 UTC vs.
Revision 1.28 by root, Sat May 24 22:27:11 2008 UTC

10use Fcntl (); 10use Fcntl ();
11use Errno qw/EAGAIN EINTR/; 11use Errno qw/EAGAIN EINTR/;
12 12
13=head1 NAME 13=head1 NAME
14 14
15AnyEvent::Handle - non-blocking I/O on filehandles via AnyEvent 15AnyEvent::Handle - non-blocking I/O on file handles via AnyEvent
16 16
17This module is experimental. 17This module is experimental.
18 18
19=cut 19=cut
20 20
145 145
146When this parameter is given, it enables TLS (SSL) mode, that means it 146When this parameter is given, it enables TLS (SSL) mode, that means it
147will start making tls handshake and will transparently encrypt/decrypt 147will start making tls handshake and will transparently encrypt/decrypt
148data. 148data.
149 149
150TLS mode requires Net::SSLeay to be installed (it will be loaded
151automatically when you try to create a TLS handle).
152
150For the TLS server side, use C<accept>, and for the TLS client side of a 153For the TLS server side, use C<accept>, and for the TLS client side of a
151connection, use C<connect> mode. 154connection, use C<connect> mode.
152 155
153You can also provide your own TLS connection object, but you have 156You can also provide your own TLS connection object, but you have
154to make sure that you call either C<Net::SSLeay::set_connect_state> 157to make sure that you call either C<Net::SSLeay::set_connect_state>
155or C<Net::SSLeay::set_accept_state> on it before you pass it to 158or C<Net::SSLeay::set_accept_state> on it before you pass it to
156AnyEvent::Handle. 159AnyEvent::Handle.
157 160
161See the C<starttls> method if you need to start TLs negotiation later.
162
158=item tls_ctx => $ssl_ctx 163=item tls_ctx => $ssl_ctx
159 164
160Use the given Net::SSLeay::CTX object to create the new TLS connection 165Use the given Net::SSLeay::CTX object to create the new TLS connection
161(unless a connection object was specified directly). If this parameter is 166(unless a connection object was specified directly). If this parameter is
162missing, then AnyEvent::Handle will use C<AnyEvent::Handle::TLS_CTX>. 167missing, then AnyEvent::Handle will use C<AnyEvent::Handle::TLS_CTX>.
163 168
164=back 169=back
165 170
166=cut 171=cut
172
173our (%RH, %WH);
174
175sub register_read_type($$) {
176 $RH{$_[0]} = $_[1];
177}
178
179sub register_write_type($$) {
180 $WH{$_[0]} = $_[1];
181}
167 182
168sub new { 183sub new {
169 my $class = shift; 184 my $class = shift;
170 185
171 my $self = bless { @_ }, $class; 186 my $self = bless { @_ }, $class;
212 } 227 }
213} 228}
214 229
215=item $fh = $handle->fh 230=item $fh = $handle->fh
216 231
217This method returns the filehandle of the L<AnyEvent::Handle> object. 232This method returns the file handle of the L<AnyEvent::Handle> object.
218 233
219=cut 234=cut
220 235
221sub fh { $_[0]->{fh} } 236sub fh { $_[0]->{fh} }
222 237
501true, it will be removed from the queue. 516true, it will be removed from the queue.
502 517
503=cut 518=cut
504 519
505sub push_read { 520sub push_read {
506 my ($self, $cb) = @_; 521 my $self = shift;
522 my $cb = pop;
523
524 if (@_) {
525 my $type = shift;
526
527 $cb = ($RH{$type} or Carp::croak "unsupported type passed to AnyEvent::Handle::push_read")
528 ->($self, $cb, @_);
529 }
507 530
508 push @{ $self->{queue} }, $cb; 531 push @{ $self->{queue} }, $cb;
509 $self->_drain_rbuf; 532 $self->_drain_rbuf;
510} 533}
511 534
512sub unshift_read { 535sub unshift_read {
513 my ($self, $cb) = @_; 536 my $self = shift;
537 my $cb = pop;
514 538
539 if (@_) {
540 my $type = shift;
541
542 $cb = ($RH{$type} or Carp::croak "unsupported type passed to AnyEvent::Handle::unshift_read")
543 ->($self, $cb, @_);
544 }
545
546
515 push @{ $self->{queue} }, $cb; 547 unshift @{ $self->{queue} }, $cb;
516 $self->_drain_rbuf; 548 $self->_drain_rbuf;
517} 549}
518 550
519=item $handle->push_read_chunk ($len, $cb->($self, $data)) 551=item $handle->push_read (type => @args, $cb)
520 552
521=item $handle->unshift_read_chunk ($len, $cb->($self, $data)) 553=item $handle->unshift_read (type => @args, $cb)
522 554
523Append the given callback to the end of the queue (C<push_read_chunk>) or 555Instead of providing a callback that parses the data itself you can chose
524prepend it (C<unshift_read_chunk>). 556between a number of predefined parsing formats, for chunks of data, lines
557etc.
525 558
526The callback will be called only once C<$len> bytes have been read, and 559The types currently supported are:
527these C<$len> bytes will be passed to the callback.
528 560
529=cut 561=over 4
530 562
531sub _read_chunk($$) { 563=item chunk => $octets, $cb->($self, $data)
564
565Invoke the callback only once C<$octets> bytes have been read. Pass the
566data read to the callback. The callback will never be called with less
567data.
568
569Example: read 2 bytes.
570
571 $handle->push_read (chunk => 2, sub {
572 warn "yay ", unpack "H*", $_[1];
573 });
574
575=cut
576
577register_read_type chunk => sub {
532 my ($self, $len, $cb) = @_; 578 my ($self, $cb, $len) = @_;
533 579
534 sub { 580 sub {
535 $len <= length $_[0]{rbuf} or return; 581 $len <= length $_[0]{rbuf} or return;
536 $cb->($_[0], substr $_[0]{rbuf}, 0, $len, ""); 582 $cb->($_[0], substr $_[0]{rbuf}, 0, $len, "");
537 1 583 1
538 } 584 }
539} 585};
540 586
587# compatibility with older API
541sub push_read_chunk { 588sub push_read_chunk {
542 $_[0]->push_read (&_read_chunk); 589 $_[0]->push_read (chunk => $_[1], $_[2]);
543} 590}
544
545 591
546sub unshift_read_chunk { 592sub unshift_read_chunk {
547 $_[0]->unshift_read (&_read_chunk); 593 $_[0]->unshift_read (chunk => $_[1], $_[2]);
548} 594}
549 595
550=item $handle->push_read_line ([$eol, ]$cb->($self, $line, $eol)) 596=item line => [$eol, ]$cb->($self, $line, $eol)
551
552=item $handle->unshift_read_line ([$eol, ]$cb->($self, $line, $eol))
553
554Append the given callback to the end of the queue (C<push_read_line>) or
555prepend it (C<unshift_read_line>).
556 597
557The callback will be called only once a full line (including the end of 598The callback will be called only once a full line (including the end of
558line marker, C<$eol>) has been read. This line (excluding the end of line 599line marker, C<$eol>) has been read. This line (excluding the end of line
559marker) will be passed to the callback as second argument (C<$line>), and 600marker) will be passed to the callback as second argument (C<$line>), and
560the end of line marker as the third argument (C<$eol>). 601the end of line marker as the third argument (C<$eol>).
571Partial lines at the end of the stream will never be returned, as they are 612Partial lines at the end of the stream will never be returned, as they are
572not marked by the end of line marker. 613not marked by the end of line marker.
573 614
574=cut 615=cut
575 616
576sub _read_line($$) { 617register_read_type line => sub {
577 my $self = shift; 618 my ($self, $cb, $eol) = @_;
578 my $cb = pop;
579 my $eol = @_ ? shift : qr|(\015?\012)|;
580 my $pos;
581 619
620 $eol = qr|(\015?\012)| if @_ < 3;
582 $eol = quotemeta $eol unless ref $eol; 621 $eol = quotemeta $eol unless ref $eol;
583 $eol = qr|^(.*?)($eol)|s; 622 $eol = qr|^(.*?)($eol)|s;
584 623
585 sub { 624 sub {
586 $_[0]{rbuf} =~ s/$eol// or return; 625 $_[0]{rbuf} =~ s/$eol// or return;
587 626
588 $cb->($_[0], $1, $2); 627 $cb->($_[0], $1, $2);
589 1 628 1
590 } 629 }
591} 630};
592 631
632# compatibility with older API
593sub push_read_line { 633sub push_read_line {
594 $_[0]->push_read (&_read_line); 634 my $self = shift;
635 $self->push_read (line => @_);
595} 636}
596 637
597sub unshift_read_line { 638sub unshift_read_line {
598 $_[0]->unshift_read (&_read_line); 639 my $self = shift;
640 $self->unshift_read (line => @_);
599} 641}
642
643=back
600 644
601=item $handle->stop_read 645=item $handle->stop_read
602 646
603=item $handle->start_read 647=item $handle->start_read
604 648
605In rare cases you actually do not want to read anything from the 649In rare cases you actually do not want to read anything from the
606socket. In this case you can call C<stop_read>. Neither C<on_read> no 650socket. In this case you can call C<stop_read>. Neither C<on_read> no
607any queued callbacks will be executed then. To start readign again, call 651any queued callbacks will be executed then. To start reading again, call
608C<start_read>. 652C<start_read>.
609 653
610=cut 654=cut
611 655
612sub stop_read { 656sub stop_read {
644 688
645sub _dotls { 689sub _dotls {
646 my ($self) = @_; 690 my ($self) = @_;
647 691
648 if (length $self->{tls_wbuf}) { 692 if (length $self->{tls_wbuf}) {
649 my $len = Net::SSLeay::write ($self->{tls}, $self->{tls_wbuf}); 693 while ((my $len = Net::SSLeay::write ($self->{tls}, $self->{tls_wbuf})) > 0) {
650 substr $self->{tls_wbuf}, 0, $len, "" if $len > 0; 694 substr $self->{tls_wbuf}, 0, $len, "";
695 }
651 } 696 }
652 697
653 if (defined (my $buf = Net::SSLeay::BIO_read ($self->{tls_wbio}))) { 698 if (defined (my $buf = Net::SSLeay::BIO_read ($self->{tls_wbio}))) {
654 $self->{wbuf} .= $buf; 699 $self->{wbuf} .= $buf;
655 $self->_drain_wbuf; 700 $self->_drain_wbuf;
656 } 701 }
657 702
658 if (defined (my $buf = Net::SSLeay::read ($self->{tls}))) { 703 while (defined (my $buf = Net::SSLeay::read ($self->{tls}))) {
659 $self->{rbuf} .= $buf; 704 $self->{rbuf} .= $buf;
660 $self->_drain_rbuf; 705 $self->_drain_rbuf;
661 } elsif ( 706 }
707
662 (my $err = Net::SSLeay::get_error ($self->{tls}, -1)) 708 my $err = Net::SSLeay::get_error ($self->{tls}, -1);
709
663 != Net::SSLeay::ERROR_WANT_READ () 710 if ($err!= Net::SSLeay::ERROR_WANT_READ ()) {
664 ) {
665 if ($err == Net::SSLeay::ERROR_SYSCALL ()) { 711 if ($err == Net::SSLeay::ERROR_SYSCALL ()) {
666 $self->error; 712 $self->error;
667 } elsif ($err == Net::SSLeay::ERROR_SSL ()) { 713 } elsif ($err == Net::SSLeay::ERROR_SSL ()) {
668 $! = &Errno::EIO; 714 $! = &Errno::EIO;
669 $self->error; 715 $self->error;
671 717
672 # all others are fine for our purposes 718 # all others are fine for our purposes
673 } 719 }
674} 720}
675 721
722=item $handle->starttls ($tls[, $tls_ctx])
723
724Instead of starting TLS negotiation immediately when the AnyEvent::Handle
725object is created, you can also do that at a later time by calling
726C<starttls>.
727
728The first argument is the same as the C<tls> constructor argument (either
729C<"connect">, C<"accept"> or an existing Net::SSLeay object).
730
731The second argument is the optional C<Net::SSLeay::CTX> object that is
732used when AnyEvent::Handle has to create its own TLS connection object.
733
734=cut
735
676# TODO: maybe document... 736# TODO: maybe document...
677sub starttls { 737sub starttls {
678 my ($self, $ssl, $ctx) = @_; 738 my ($self, $ssl, $ctx) = @_;
739
740 $self->stoptls;
679 741
680 if ($ssl eq "accept") { 742 if ($ssl eq "accept") {
681 $ssl = Net::SSLeay::new ($ctx || TLS_CTX ()); 743 $ssl = Net::SSLeay::new ($ctx || TLS_CTX ());
682 Net::SSLeay::set_accept_state ($ssl); 744 Net::SSLeay::set_accept_state ($ssl);
683 } elsif ($ssl eq "connect") { 745 } elsif ($ssl eq "connect") {
684 $ssl = Net::SSLeay::new ($ctx || TLS_CTX ()); 746 $ssl = Net::SSLeay::new ($ctx || TLS_CTX ());
685 Net::SSLeay::set_connect_state ($ssl); 747 Net::SSLeay::set_connect_state ($ssl);
686 } 748 }
687 749
688 $self->{tls} = $ssl; 750 $self->{tls} = $ssl;
751
752 # basically, this is deep magic (because SSL_read should have the same issues)
753 # but the openssl maintainers basically said: "trust us, it just works".
754 # (unfortunately, we have to hardcode constants because the abysmally misdesigned
755 # and mismaintained ssleay-module doesn't even offer them).
756 # http://www.mail-archive.com/openssl-dev@openssl.org/msg22420.html
757 Net::SSLeay::CTX_set_mode ($self->{tls},
758 (eval { Net::SSLeay::MODE_ENABLE_PARTIAL_WRITE () } || 1)
759 | (eval { Net::SSLeay::MODE_ACCEPT_MOVING_WRITE_BUFFER () } || 2));
689 760
690 $self->{tls_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); 761 $self->{tls_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
691 $self->{tls_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); 762 $self->{tls_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
692 763
693 Net::SSLeay::set_bio ($ssl, $self->{tls_rbio}, $self->{tls_wbio}); 764 Net::SSLeay::set_bio ($ssl, $self->{tls_rbio}, $self->{tls_wbio});
700 Net::SSLeay::BIO_write ($_[0]{tls_rbio}, ${$_[1]}); 771 Net::SSLeay::BIO_write ($_[0]{tls_rbio}, ${$_[1]});
701 &_dotls; 772 &_dotls;
702 }; 773 };
703} 774}
704 775
776=item $handle->stoptls
777
778Destroys the SSL connection, if any. Partial read or write data will be
779lost.
780
781=cut
782
783sub stoptls {
784 my ($self) = @_;
785
786 Net::SSLeay::free (delete $self->{tls}) if $self->{tls};
787 delete $self->{tls_rbio};
788 delete $self->{tls_wbio};
789 delete $self->{tls_wbuf};
790 delete $self->{filter_r};
791 delete $self->{filter_w};
792}
793
705sub DESTROY { 794sub DESTROY {
706 my $self = shift; 795 my $self = shift;
707 796
708 Net::SSLeay::free (delete $self->{tls}) if $self->{tls}; 797 $self->stoptls;
709} 798}
710 799
711=item AnyEvent::Handle::TLS_CTX 800=item AnyEvent::Handle::TLS_CTX
712 801
713This function creates and returns the Net::SSLeay::CTX object used by 802This function creates and returns the Net::SSLeay::CTX object used by

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines