File Coverage

blib/lib/AnyEvent/Ident/Server.pm
Criterion Covered Total %
statement 59 65 90.7
branch 5 8 62.5
condition 2 4 50.0
subroutine 15 17 88.2
pod 3 4 75.0
total 84 98 85.7


line stmt bran cond sub pod time code
1             package AnyEvent::Ident::Server;
2              
3 4     4   2057 use strict;
  4         11  
  4         131  
4 4     4   23 use warnings;
  4         7  
  4         171  
5 4     4   22 use AnyEvent;
  4         8  
  4         108  
6 4     4   614 use AnyEvent::Socket qw( tcp_server );
  4         25386  
  4         248  
7 4     4   747 use AnyEvent::Handle;
  4         7882  
  4         112  
8 4     4   1358 use AnyEvent::Ident::Request;
  4         8  
  4         127  
9 4     4   1424 use AnyEvent::Ident::Response;
  4         10  
  4         119  
10 4     4   1746 use AnyEvent::Ident::Transaction;
  4         10  
  4         130  
11 4     4   26 use Carp qw( croak carp );
  4         8  
  4         2766  
12              
13             # ABSTRACT: Simple asynchronous ident server
14             our $VERSION = '0.08'; # VERSION
15              
16              
17             sub new
18             {
19 3     3 0 9737 my $class = shift;
20 3 50       22 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  0         0  
21 3         9 my $port = $args->{port};
22 3 50       13 $port = 113 unless defined $port;
23             bless {
24             hostname => $args->{hostname},
25             port => $port,
26 0     0   0 on_error => $args->{on_error} || sub { carp $_[0] },
27       0     on_bind => $args->{on_bind} || sub { },
28 3   50     45 }, $class;
      50        
29             }
30              
31              
32             sub start
33             {
34 4     4 1 1376 my($self, $callback) = @_;
35            
36 4 50       25 croak "already started" if $self->{guard};
37            
38             my $cb = sub {
39 6     6   902 my ($fh, $host, $port) = @_;
40              
41 6         11 my $handle;
42             $handle = AnyEvent::Handle->new(
43             fh => $fh,
44             on_error => sub {
45 0         0 my ($hdl, $fatal, $msg) = @_;
46 0         0 $self->{on_error}->($msg);
47 0         0 $_[0]->destroy;
48             },
49             on_eof => sub {
50 0         0 $handle->destroy;
51             },
52 6         75 );
53            
54             $handle->on_read(sub {
55             $handle->push_read( line => sub {
56 11         600 my($handle, $line) = @_;
57 11         24 $line =~ s/\015?\012//g;
58 11         16 my $req = eval { AnyEvent::Ident::Request->new($line) };
  11         68  
59 11 100       50 return $handle->push_write("$line:ERROR:INVALID-PORT\015\012") if $@;
60             my $tx = bless {
61             req => $req,
62             remote_port => $port,
63             local_port => $self->{bindport},
64             remote_address => $host,
65             cb => sub {
66 7         17 my($res) = @_;
67 7         21 $handle->push_write($res->as_string . "\015\012");
68             },
69 7         61 }, 'AnyEvent::Ident::Transaction';
70 7         39 $callback->($tx);
71             })
72 6         520 });
  11         1222  
73 4         19 };
74              
75             $self->{guard} = tcp_server $self->{hostname}, $self->{port}, $cb, sub {
76 4     4   1072 my($fh, $host, $port) = @_;
77 4         12 $self->{bindport} = $port;
78 4         18 $self->{on_bind}->($self);
79 4         33 };
80            
81 4         350 $self;
82             }
83              
84              
85 8     8 1 197 sub bindport { shift->{bindport} }
86              
87              
88             sub stop
89             {
90 1     1 1 609 my($self) = @_;
91 1         8 delete $self->{guard};
92 1         66 delete $self->{bindport};
93 1         5 $self;
94             }
95              
96             1;
97              
98             __END__