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.141 by root, Mon Jul 6 01:03:09 2009 UTC vs.
Revision 1.142 by root, Mon Jul 6 20:24:47 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)
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
310=item on_stoptls => $cb->($handle)
311
312When a SSLv3/TLS shutdown/close notify/EOF is detected and this callback is
313set, then it will be invoked after freeing the TLS session. If it is not,
314then a TLS shutdown condition will be treated like a normal EOF condition
315on the handle.
316
317The session in C<< $handle->{tls} >> can still be examined in this
318callback.
319
320This callback will only be called on TLS shutdowns, not when the
321underlying handle signals EOF.
322
301=item json => JSON or JSON::XS object 323=item json => JSON or JSON::XS object
302 324
303This is the json coder object used by the C<json> read and write types. 325This is the json coder object used by the C<json> read and write types.
304 326
305If you don't supply it, then AnyEvent::Handle will create and use a 327If you don't supply it, then AnyEvent::Handle will create and use a
425 447
426 eval { 448 eval {
427 local $SIG{__DIE__}; 449 local $SIG{__DIE__};
428 setsockopt $_[0]{fh}, &Socket::IPPROTO_TCP, &Socket::TCP_NODELAY, int $_[1]; 450 setsockopt $_[0]{fh}, &Socket::IPPROTO_TCP, &Socket::TCP_NODELAY, int $_[1];
429 }; 451 };
452}
453
454=item $handle->on_starttls ($cb)
455
456Replace the current C<on_starttls> callback (see the C<on_starttls> constructor argument).
457
458=cut
459
460sub on_starttls {
461 $_[0]{on_starttls} = $_[1];
462}
463
464=item $handle->on_stoptls ($cb)
465
466Replace the current C<on_stoptls> callback (see the C<on_stoptls> constructor argument).
467
468=cut
469
470sub on_starttls {
471 $_[0]{on_stoptls} = $_[1];
430} 472}
431 473
432############################################################################# 474#############################################################################
433 475
434=item $handle->timeout ($seconds) 476=item $handle->timeout ($seconds)
683 725
684=item $handle->push_shutdown 726=item $handle->push_shutdown
685 727
686Sometimes you know you want to close the socket after writing your data 728Sometimes 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 729before 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 730C<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: 731C<low_water_mark> to C<0>). This method is a shorthand for just that, and
732replaces the C<on_drain> callback with:
690 733
691 sub { shutdown $_[0]{fh}, 1 } # for push_shutdown 734 sub { shutdown $_[0]{fh}, 1 } # for push_shutdown
692 735
693This simply shuts down the write side and signals an EOF condition to the 736This simply shuts down the write side and signals an EOF condition to the
694the peer. 737the peer.
697afterwards. This is the cleanest way to close a connection. 740afterwards. This is the cleanest way to close a connection.
698 741
699=cut 742=cut
700 743
701sub push_shutdown { 744sub push_shutdown {
745 my ($self) = @_;
746
747 delete $self->{low_water_mark};
702 $_[0]->{on_drain} = sub { shutdown $_[0]{fh}, 1 }; 748 $self->on_drain (sub { shutdown $_[0]{fh}, 1 });
703} 749}
704 750
705=item AnyEvent::Handle::register_write_type type => $coderef->($handle, @args) 751=item AnyEvent::Handle::register_write_type type => $coderef->($handle, @args)
706 752
707This function (not method) lets you add your own types to C<push_write>. 753This function (not method) lets you add your own types to C<push_write>.
1377 } 1423 }
1378} 1424}
1379 1425
1380our $ERROR_SYSCALL; 1426our $ERROR_SYSCALL;
1381our $ERROR_WANT_READ; 1427our $ERROR_WANT_READ;
1382our $ERROR_ZERO_RETURN;
1383 1428
1384sub _tls_error { 1429sub _tls_error {
1385 my ($self, $err) = @_; 1430 my ($self, $err) = @_;
1386 1431
1387 return $self->_error ($!, 1) 1432 return $self->_error ($!, 1)
1411 } 1456 }
1412 1457
1413 $tmp = Net::SSLeay::get_error ($self->{tls}, $tmp); 1458 $tmp = Net::SSLeay::get_error ($self->{tls}, $tmp);
1414 return $self->_tls_error ($tmp) 1459 return $self->_tls_error ($tmp)
1415 if $tmp != $ERROR_WANT_READ 1460 if $tmp != $ERROR_WANT_READ
1416 && ($tmp != $ERROR_SYSCALL || $!) 1461 && ($tmp != $ERROR_SYSCALL || $!);
1417 && $tmp != $ERROR_ZERO_RETURN;
1418 } 1462 }
1419 1463
1420 while (defined ($tmp = Net::SSLeay::read ($self->{tls}))) { 1464 while (defined ($tmp = Net::SSLeay::read ($self->{tls}))) {
1421 unless (length $tmp) { 1465 unless (length $tmp) {
1422 # let's treat SSL-eof as we treat normal EOF
1423 delete $self->{_rw};
1424 $self->{_eof} = 1;
1425 &_freetls; 1466 &_freetls;
1467 if ($self->{on_stoptls}) {
1468 $self->{on_stoptls}($self);
1469 return;
1470 } else {
1471 # let's treat SSL-eof as we treat normal EOF
1472 delete $self->{_rw};
1473 $self->{_eof} = 1;
1474 }
1426 } 1475 }
1427 1476
1428 $self->{_tls_rbuf} .= $tmp; 1477 $self->{_tls_rbuf} .= $tmp;
1429 $self->_drain_rbuf unless $self->{_in_drain}; 1478 $self->_drain_rbuf unless $self->{_in_drain};
1430 $self->{tls} or return; # tls session might have gone away in callback 1479 $self->{tls} or return; # tls session might have gone away in callback
1431 } 1480 }
1432 1481
1433 $tmp = Net::SSLeay::get_error ($self->{tls}, -1); 1482 $tmp = Net::SSLeay::get_error ($self->{tls}, -1);
1434 return $self->_tls_error ($tmp) 1483 return $self->_tls_error ($tmp)
1435 if $tmp != $ERROR_WANT_READ 1484 if $tmp != $ERROR_WANT_READ
1436 && ($tmp != $ERROR_SYSCALL || $!) 1485 && ($tmp != $ERROR_SYSCALL || $!);
1437 && $tmp != $ERROR_ZERO_RETURN;
1438 1486
1439 while (length ($tmp = Net::SSLeay::BIO_read ($self->{_wbio}))) { 1487 while (length ($tmp = Net::SSLeay::BIO_read ($self->{_wbio}))) {
1440 $self->{wbuf} .= $tmp; 1488 $self->{wbuf} .= $tmp;
1441 $self->_drain_wbuf; 1489 $self->_drain_wbuf;
1442 } 1490 }
1491
1492 $self->{_on_starttls}
1493 and Net::SSLeay::state ($self->{tls}) == Net::SSLeay::ST_OK ()
1494 and (delete $self->{_on_starttls})->($self, 1);
1443} 1495}
1444 1496
1445=item $handle->starttls ($tls[, $tls_ctx]) 1497=item $handle->starttls ($tls[, $tls_ctx])
1446 1498
1447Instead of starting TLS negotiation immediately when the AnyEvent::Handle 1499Instead of starting TLS negotiation immediately when the AnyEvent::Handle
1474 require Net::SSLeay; 1526 require Net::SSLeay;
1475 1527
1476 Carp::croak "it is an error to call starttls more than once on an AnyEvent::Handle object" 1528 Carp::croak "it is an error to call starttls more than once on an AnyEvent::Handle object"
1477 if $self->{tls}; 1529 if $self->{tls};
1478 1530
1479 $ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL (); 1531 $ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL ();
1480 $ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ (); 1532 $ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ ();
1481 $ERROR_ZERO_RETURN = Net::SSLeay::ERROR_ZERO_RETURN ();
1482 1533
1483 $ctx ||= $self->{tls_ctx}; 1534 $ctx ||= $self->{tls_ctx};
1484 1535
1485 if ("HASH" eq ref $ctx) { 1536 if ("HASH" eq ref $ctx) {
1486 require AnyEvent::TLS; 1537 require AnyEvent::TLS;
1518 $self->{_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); 1569 $self->{_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
1519 $self->{_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); 1570 $self->{_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
1520 1571
1521 Net::SSLeay::set_bio ($ssl, $self->{_rbio}, $self->{_wbio}); 1572 Net::SSLeay::set_bio ($ssl, $self->{_rbio}, $self->{_wbio});
1522 1573
1574 $self->{_on_starttls} = sub { $_[0]{on_starttls}(@_) }
1575 if exists $self->{on_starttls};
1576
1523 &_dotls; # need to trigger the initial handshake 1577 &_dotls; # need to trigger the initial handshake
1524 $self->start_read; # make sure we actually do read 1578 $self->start_read; # make sure we actually do read
1525} 1579}
1526 1580
1527=item $handle->stoptls 1581=item $handle->stoptls
1539 if ($self->{tls}) { 1593 if ($self->{tls}) {
1540 Net::SSLeay::shutdown ($self->{tls}); 1594 Net::SSLeay::shutdown ($self->{tls});
1541 1595
1542 &_dotls; 1596 &_dotls;
1543 1597
1544 # we don't give a shit. no, we do, but we can't. no... 1598# # we don't give a shit. no, we do, but we can't. no...#d#
1545 # we, we... have to use openssl :/ 1599# # we, we... have to use openssl :/#d#
1546 &_freetls; 1600# &_freetls;#d#
1547 } 1601 }
1548} 1602}
1549 1603
1550sub _freetls { 1604sub _freetls {
1551 my ($self) = @_; 1605 my ($self) = @_;
1552 1606
1553 return unless $self->{tls}; 1607 return unless $self->{tls};
1608
1609 $self->{_on_starttls}
1610 and (delete $self->{_on_starttls})->($self, undef);
1554 1611
1555 $self->{tls_ctx}->_put_session (delete $self->{tls}); 1612 $self->{tls_ctx}->_put_session (delete $self->{tls});
1556 1613
1557 delete @$self{qw(_rbio _wbio _tls_wbuf)}; 1614 delete @$self{qw(_rbio _wbio _tls_wbuf)};
1558} 1615}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines