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.140 by root, Mon Jul 6 00:45:00 2009 UTC vs.
Revision 1.143 by root, Mon Jul 6 21:02:34 2009 UTC

296 296
297Instead of an object, you can also specify a hash reference with C<< key 297Instead of an object, you can also specify a hash reference with C<< key
298=> value >> pairs. Those will be passed to L<AnyEvent::TLS> to create a 298=> value >> pairs. Those will be passed to L<AnyEvent::TLS> to create a
299new TLS context object. 299new TLS context object.
300 300
301=item on_starttls => $cb->($handle, $success[, $error_message])
302
303This callback will be invoked when the TLS/SSL handshake has finished. If
304C<$success> is true, then the TLS handshake succeeded, otherwise it failed
305(C<on_stoptls> will not be called in this case).
306
307The session in C<< $handle->{tls} >> can still be examined in this
308callback, even when the handshake was not successful.
309
310TLS handshake failures will not cause C<on_error> to be invoked when this
311callback is in effect, instead, the error message will be passed to C<on_starttls>.
312
313Without this callback, handshake failures lead to C<on_error> being
314called, as normal.
315
316Note that you cannot call C<starttls> right again in this callback. If you
317need to do that, start an zero-second timer instead whose callback can
318then call C<< ->starttls >> again.
319
320=item on_stoptls => $cb->($handle)
321
322When a SSLv3/TLS shutdown/close notify/EOF is detected and this callback is
323set, then it will be invoked after freeing the TLS session. If it is not,
324then a TLS shutdown condition will be treated like a normal EOF condition
325on the handle.
326
327The session in C<< $handle->{tls} >> can still be examined in this
328callback.
329
330This callback will only be called on TLS shutdowns, not when the
331underlying handle signals EOF.
332
301=item json => JSON or JSON::XS object 333=item json => JSON or JSON::XS object
302 334
303This is the json coder object used by the C<json> read and write types. 335This is the json coder object used by the C<json> read and write types.
304 336
305If you don't supply it, then AnyEvent::Handle will create and use a 337If you don't supply it, then AnyEvent::Handle will create and use a
327 $self->no_delay (delete $self->{no_delay}) if exists $self->{no_delay}; 359 $self->no_delay (delete $self->{no_delay}) if exists $self->{no_delay};
328 360
329 $self->starttls (delete $self->{tls}, delete $self->{tls_ctx}) 361 $self->starttls (delete $self->{tls}, delete $self->{tls_ctx})
330 if $self->{tls}; 362 if $self->{tls};
331 363
332 $self->on_drain (delete $self->{on_drain}) if exists $self->{on_drain}; 364 $self->on_drain (delete $self->{on_drain}) if $self->{on_drain};
333 365
334 $self->start_read 366 $self->start_read
335 if $self->{on_read}; 367 if $self->{on_read};
336 368
337 $self->{fh} && $self 369 $self->{fh} && $self
425 457
426 eval { 458 eval {
427 local $SIG{__DIE__}; 459 local $SIG{__DIE__};
428 setsockopt $_[0]{fh}, &Socket::IPPROTO_TCP, &Socket::TCP_NODELAY, int $_[1]; 460 setsockopt $_[0]{fh}, &Socket::IPPROTO_TCP, &Socket::TCP_NODELAY, int $_[1];
429 }; 461 };
462}
463
464=item $handle->on_starttls ($cb)
465
466Replace the current C<on_starttls> callback (see the C<on_starttls> constructor argument).
467
468=cut
469
470sub on_starttls {
471 $_[0]{on_starttls} = $_[1];
472}
473
474=item $handle->on_stoptls ($cb)
475
476Replace the current C<on_stoptls> callback (see the C<on_stoptls> constructor argument).
477
478=cut
479
480sub on_starttls {
481 $_[0]{on_stoptls} = $_[1];
430} 482}
431 483
432############################################################################# 484#############################################################################
433 485
434=item $handle->timeout ($seconds) 486=item $handle->timeout ($seconds)
683 735
684=item $handle->push_shutdown 736=item $handle->push_shutdown
685 737
686Sometimes you know you want to close the socket after writing your data 738Sometimes you know you want to close the socket after writing your data
687before it was actually written. One way to do that is to replace your 739before it was actually written. One way to do that is to replace your
688C<on_drain> handler by a callback that shuts down the socket. This method 740C<on_drain> handler by a callback that shuts down the socket (and set
689is a shorthand for just that, and replaces the C<on_drain> callback with: 741C<low_water_mark> to C<0>). This method is a shorthand for just that, and
742replaces the C<on_drain> callback with:
690 743
691 sub { shutdown $_[0]{fh}, 1 } # for push_shutdown 744 sub { shutdown $_[0]{fh}, 1 } # for push_shutdown
692 745
693This simply shuts down the write side and signals an EOF condition to the 746This simply shuts down the write side and signals an EOF condition to the
694the peer. 747the peer.
697afterwards. This is the cleanest way to close a connection. 750afterwards. This is the cleanest way to close a connection.
698 751
699=cut 752=cut
700 753
701sub push_shutdown { 754sub push_shutdown {
755 my ($self) = @_;
756
757 delete $self->{low_water_mark};
702 $_[0]->{on_drain} = sub { shutdown $_[0]{fh}, 1 }; 758 $self->on_drain (sub { shutdown $_[0]{fh}, 1 });
703} 759}
704 760
705=item AnyEvent::Handle::register_write_type type => $coderef->($handle, @args) 761=item AnyEvent::Handle::register_write_type type => $coderef->($handle, @args)
706 762
707This function (not method) lets you add your own types to C<push_write>. 763This function (not method) lets you add your own types to C<push_write>.
1377 } 1433 }
1378} 1434}
1379 1435
1380our $ERROR_SYSCALL; 1436our $ERROR_SYSCALL;
1381our $ERROR_WANT_READ; 1437our $ERROR_WANT_READ;
1382our $ERROR_ZERO_RETURN;
1383 1438
1384sub _tls_error { 1439sub _tls_error {
1385 my ($self, $err) = @_; 1440 my ($self, $err) = @_;
1386 1441
1387 return $self->_error ($!, 1) 1442 return $self->_error ($!, 1)
1390 my $err =Net::SSLeay::ERR_error_string (Net::SSLeay::ERR_get_error ()); 1445 my $err =Net::SSLeay::ERR_error_string (Net::SSLeay::ERR_get_error ());
1391 1446
1392 # reduce error string to look less scary 1447 # reduce error string to look less scary
1393 $err =~ s/^error:[0-9a-fA-F]{8}:[^:]+:([^:]+):/\L$1: /; 1448 $err =~ s/^error:[0-9a-fA-F]{8}:[^:]+:([^:]+):/\L$1: /;
1394 1449
1450 if ($self->{_on_starttls}) {
1451 (delete $self->{_on_starttls})->($self, undef, $err);
1452 &_freetls;
1453 } else {
1454 &_freetls;
1395 $self->_error (&Errno::EPROTO, 1, $err); 1455 $self->_error (&Errno::EPROTO, 1, $err);
1456 }
1396} 1457}
1397 1458
1398# poll the write BIO and send the data if applicable 1459# poll the write BIO and send the data if applicable
1399# also decode read data if possible 1460# also decode read data if possible
1400# this is basiclaly our TLS state machine 1461# this is basiclaly our TLS state machine
1411 } 1472 }
1412 1473
1413 $tmp = Net::SSLeay::get_error ($self->{tls}, $tmp); 1474 $tmp = Net::SSLeay::get_error ($self->{tls}, $tmp);
1414 return $self->_tls_error ($tmp) 1475 return $self->_tls_error ($tmp)
1415 if $tmp != $ERROR_WANT_READ 1476 if $tmp != $ERROR_WANT_READ
1416 && ($tmp != $ERROR_SYSCALL || $!) 1477 && ($tmp != $ERROR_SYSCALL || $!);
1417 && $tmp != $ERROR_ZERO_RETURN;
1418 } 1478 }
1419 1479
1420 while (defined ($tmp = Net::SSLeay::read ($self->{tls}))) { 1480 while (defined ($tmp = Net::SSLeay::read ($self->{tls}))) {
1421 unless (length $tmp) { 1481 unless (length $tmp) {
1422 # let's treat SSL-eof as we treat normal EOF 1482 $self->{_on_starttls}
1423 delete $self->{_rw}; 1483 and (delete $self->{_on_starttls})->($self, undef, "EOF during handshake"); # ???
1424 $self->{_eof} = 1;
1425 &_freetls; 1484 &_freetls;
1485
1486 if ($self->{on_stoptls}) {
1487 $self->{on_stoptls}($self);
1488 return;
1489 } else {
1490 # let's treat SSL-eof as we treat normal EOF
1491 delete $self->{_rw};
1492 $self->{_eof} = 1;
1493 }
1426 } 1494 }
1427 1495
1428 $self->{_tls_rbuf} .= $tmp; 1496 $self->{_tls_rbuf} .= $tmp;
1429 $self->_drain_rbuf unless $self->{_in_drain}; 1497 $self->_drain_rbuf unless $self->{_in_drain};
1430 $self->{tls} or return; # tls session might have gone away in callback 1498 $self->{tls} or return; # tls session might have gone away in callback
1431 } 1499 }
1432 1500
1433 $tmp = Net::SSLeay::get_error ($self->{tls}, -1); 1501 $tmp = Net::SSLeay::get_error ($self->{tls}, -1);
1434 return $self->_tls_error ($tmp) 1502 return $self->_tls_error ($tmp)
1435 if $tmp != $ERROR_WANT_READ 1503 if $tmp != $ERROR_WANT_READ
1436 && ($tmp != $ERROR_SYSCALL || $!) 1504 && ($tmp != $ERROR_SYSCALL || $!);
1437 && $tmp != $ERROR_ZERO_RETURN;
1438 1505
1439 while (length ($tmp = Net::SSLeay::BIO_read ($self->{_wbio}))) { 1506 while (length ($tmp = Net::SSLeay::BIO_read ($self->{_wbio}))) {
1440 $self->{wbuf} .= $tmp; 1507 $self->{wbuf} .= $tmp;
1441 $self->_drain_wbuf; 1508 $self->_drain_wbuf;
1442 } 1509 }
1510
1511 $self->{_on_starttls}
1512 and Net::SSLeay::state ($self->{tls}) == Net::SSLeay::ST_OK ()
1513 and (delete $self->{_on_starttls})->($self, 1, "TLS/SSL connection established");
1443} 1514}
1444 1515
1445=item $handle->starttls ($tls[, $tls_ctx]) 1516=item $handle->starttls ($tls[, $tls_ctx])
1446 1517
1447Instead of starting TLS negotiation immediately when the AnyEvent::Handle 1518Instead of starting TLS negotiation immediately when the AnyEvent::Handle
1474 require Net::SSLeay; 1545 require Net::SSLeay;
1475 1546
1476 Carp::croak "it is an error to call starttls more than once on an AnyEvent::Handle object" 1547 Carp::croak "it is an error to call starttls more than once on an AnyEvent::Handle object"
1477 if $self->{tls}; 1548 if $self->{tls};
1478 1549
1479 $ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL (); 1550 $ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL ();
1480 $ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ (); 1551 $ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ ();
1481 $ERROR_ZERO_RETURN = Net::SSLeay::ERROR_ZERO_RETURN ();
1482 1552
1483 $ctx ||= $self->{tls_ctx}; 1553 $ctx ||= $self->{tls_ctx};
1484 1554
1485 if ("HASH" eq ref $ctx) { 1555 if ("HASH" eq ref $ctx) {
1486 require AnyEvent::TLS; 1556 require AnyEvent::TLS;
1518 $self->{_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); 1588 $self->{_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
1519 $self->{_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); 1589 $self->{_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
1520 1590
1521 Net::SSLeay::set_bio ($ssl, $self->{_rbio}, $self->{_wbio}); 1591 Net::SSLeay::set_bio ($ssl, $self->{_rbio}, $self->{_wbio});
1522 1592
1593 $self->{_on_starttls} = sub { $_[0]{on_starttls}(@_) }
1594 if $self->{on_starttls};
1595
1523 &_dotls; # need to trigger the initial handshake 1596 &_dotls; # need to trigger the initial handshake
1524 $self->start_read; # make sure we actually do read 1597 $self->start_read; # make sure we actually do read
1525} 1598}
1526 1599
1527=item $handle->stoptls 1600=item $handle->stoptls
1539 if ($self->{tls}) { 1612 if ($self->{tls}) {
1540 Net::SSLeay::shutdown ($self->{tls}); 1613 Net::SSLeay::shutdown ($self->{tls});
1541 1614
1542 &_dotls; 1615 &_dotls;
1543 1616
1544 # we don't give a shit. no, we do, but we can't. no... 1617# # we don't give a shit. no, we do, but we can't. no...#d#
1545 # we, we... have to use openssl :/ 1618# # we, we... have to use openssl :/#d#
1546 &_freetls; 1619# &_freetls;#d#
1547 } 1620 }
1548} 1621}
1549 1622
1550sub _freetls { 1623sub _freetls {
1551 my ($self) = @_; 1624 my ($self) = @_;
1552 1625
1553 return unless $self->{tls}; 1626 return unless $self->{tls};
1554 1627
1555 $self->{tls_ctx}->_put_session (delete $self->{tls}); 1628 $self->{tls_ctx}->_put_session (delete $self->{tls});
1556 1629
1557 delete @$self{qw(_rbio _wbio _tls_wbuf)}; 1630 delete @$self{qw(_rbio _wbio _tls_wbuf _on_starttls)};
1558} 1631}
1559 1632
1560sub DESTROY { 1633sub DESTROY {
1561 my ($self) = @_; 1634 my ($self) = @_;
1562 1635
1586} 1659}
1587 1660
1588=item $handle->destroy 1661=item $handle->destroy
1589 1662
1590Shuts down the handle object as much as possible - this call ensures that 1663Shuts down the handle object as much as possible - this call ensures that
1591no further callbacks will be invoked and resources will be freed as much 1664no further callbacks will be invoked and as many resources as possible
1592as possible. You must not call any methods on the object afterwards. 1665will be freed. You must not call any methods on the object afterwards.
1593 1666
1594Normally, you can just "forget" any references to an AnyEvent::Handle 1667Normally, you can just "forget" any references to an AnyEvent::Handle
1595object and it will simply shut down. This works in fatal error and EOF 1668object and it will simply shut down. This works in fatal error and EOF
1596callbacks, as well as code outside. It does I<NOT> work in a read or write 1669callbacks, as well as code outside. It does I<NOT> work in a read or write
1597callback, so when you want to destroy the AnyEvent::Handle object from 1670callback, so when you want to destroy the AnyEvent::Handle object from
1698 $handle->on_drain (sub { 1771 $handle->on_drain (sub {
1699 warn "all data submitted to the kernel\n"; 1772 warn "all data submitted to the kernel\n";
1700 undef $handle; 1773 undef $handle;
1701 }); 1774 });
1702 1775
1776If you just want to queue some data and then signal EOF to the other side,
1777consider using C<< ->push_shutdown >> instead.
1778
1779=item I want to contact a TLS/SSL server, I don't care about security.
1780
1781If your TLS server is a pure TLS server (e.g. HTTPS) that only speaks TLS,
1782simply connect to it and then create the AnyEvent::Handle with the C<tls>
1783parameter:
1784
1785 my $handle = new AnyEvent::Handle
1786 fh => $fh,
1787 tls => "connect",
1788 on_error => sub { ... };
1789
1790 $handle->push_write (...);
1791
1792=item I want to contact a TLS/SSL server, I do care about security.
1793
1794Then you #x##TODO#
1795
1796
1797
1703=back 1798=back
1704 1799
1705 1800
1706=head1 SUBCLASSING AnyEvent::Handle 1801=head1 SUBCLASSING AnyEvent::Handle
1707 1802

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines