File Coverage

blib/lib/AnyEvent/Ident/Server.pm
Criterion Covered Total %
statement 59 66 89.3
branch 5 8 62.5
condition 2 4 50.0
subroutine 15 17 88.2
pod 3 4 75.0
total 84 99 84.8


line stmt bran cond sub pod time code
1             package AnyEvent::Ident::Server;
2              
3 3     3   779 use strict;
  3         4  
  3         104  
4 3     3   13 use warnings;
  3         2  
  3         72  
5 3     3   9 use AnyEvent;
  3         3  
  3         63  
6 3     3   698 use AnyEvent::Socket qw( tcp_server );
  3         26035  
  3         147  
7 3     3   675 use AnyEvent::Handle;
  3         5155  
  3         53  
8 3     3   904 use AnyEvent::Ident::Request;
  3         3  
  3         58  
9 3     3   934 use AnyEvent::Ident::Response;
  3         4  
  3         57  
10 3     3   843 use AnyEvent::Ident::Transaction;
  3         5  
  3         61  
11 3     3   11 use Carp qw( croak carp );
  3         2  
  3         1229  
12              
13             # ABSTRACT: Simple asynchronous ident server
14             our $VERSION = '0.07'; # VERSION
15              
16              
17             sub new
18             {
19 3     3 0 5778 my $class = shift;
20 3 50       18 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  0         0  
21 3         5 my $port = $args->{port};
22 3 50       10 $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     0   0 on_bind => $args->{on_bind} || sub { },
28 3   50     47 }, $class;
      50        
29             }
30              
31              
32             sub start
33             {
34 4     4 1 1290 my($self, $callback) = @_;
35            
36 4 50       22 croak "already started" if $self->{guard};
37            
38             my $cb = sub {
39 6     6   573 my ($fh, $host, $port) = @_;
40              
41 6         7 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         48 );
53            
54             $handle->on_read(sub {
55             $handle->push_read( line => sub {
56 11         548 my($handle, $line) = @_;
57 11         17 $line =~ s/\015?\012//g;
58 11         10 my $req = eval { AnyEvent::Ident::Request->new($line) };
  11         56  
59 11 100       38 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         11 my($res) = @_;
67 7         26 $handle->push_write($res->as_string . "\015\012");
68             },
69 7         65 }, 'AnyEvent::Ident::Transaction';
70 7         21 $callback->($tx);
71             })
72 6         235 });
  11         705  
73 4         21 };
74              
75             $self->{guard} = tcp_server $self->{hostname}, $self->{port}, $cb, sub {
76 4     4   668 my($fh, $host, $port) = @_;
77 4         9 $self->{bindport} = $port;
78 4         11 $self->{on_bind}->($self);
79 4         29 };
80            
81 4         333 $self;
82             }
83              
84              
85 8     8 1 142 sub bindport { shift->{bindport} }
86              
87              
88             sub stop
89             {
90 1     1 1 479 my($self) = @_;
91 1         10 delete $self->{guard};
92 1         58 delete $self->{bindport};
93 1         2 $self;
94             }
95              
96             1;
97              
98             __END__