File Coverage

blib/lib/AnyEvent/Finger/Server.pm
Criterion Covered Total %
statement 93 101 92.0
branch 27 32 84.3
condition 9 10 90.0
subroutine 15 17 88.2
pod 4 4 100.0
total 148 164 90.2


line stmt bran cond sub pod time code
1             package AnyEvent::Finger::Server;
2              
3 5     5   2465 use strict;
  5         10  
  5         174  
4 5     5   28 use warnings;
  5         9  
  5         188  
5 5     5   28 use Carp qw( carp croak );
  5         10  
  5         237  
6 5     5   1063 use AnyEvent;
  5         5586  
  5         123  
7 5     5   1455 use AnyEvent::Handle;
  5         35711  
  5         197  
8 5     5   1155 use AnyEvent::Socket qw( tcp_server );
  5         30352  
  5         270  
9 5     5   2121 use AnyEvent::Finger::Transaction;
  5         14  
  5         147  
10 5     5   2006 use AnyEvent::Finger::Request;
  5         14  
  5         147  
11 5     5   2092 use AnyEvent::Finger::Response;
  5         14  
  5         4867  
12              
13             # ABSTRACT: Simple asynchronous finger server
14             our $VERSION = '0.11'; # VERSION
15              
16              
17             sub new
18             {
19 5     5 1 9946 my $class = shift;
20 5 50       33 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  0         0  
21 5         13 my $port = $args->{port};
22 5 100       19 $port = 79 unless defined $port;
23 5         10 my $forward_deny = $args->{forward_deny};
24 5 100       15 $forward_deny = 0 unless defined $forward_deny;
25 5         8 my $forward = $args->{forward};
26 5 100       16 $forward = 0 unless defined $forward;
27             bless {
28             hostname => $args->{hostname},
29             port => $port,
30 0     0   0 on_error => $args->{on_error} || sub { carp $_[0] },
31       0     on_bind => $args->{on_bind} || sub { },
32 5   50     73 forward_deny => $forward_deny,
      100        
33             forward => $forward,
34             }, $class;
35             }
36              
37              
38             sub start
39             {
40 6     6 1 5801 my $self = shift;
41 6         13 my $callback = shift;
42 6 100       25 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  1         3  
43              
44 6 50       43 croak "already started" if $self->{guard};
45              
46 6         21 for(qw( hostname port on_error on_bind forward forward_deny ))
47             {
48 36 100       81 next if defined $args->{$_};
49 33         68 $args->{$_} = $self->{$_};
50             }
51            
52              
53 6         13 my $forward = $args->{forward};
54 6 50       18 $forward = $self->{forward} unless defined $forward;
55 6 100       19 if($forward)
56             {
57 1 50       4 unless(ref $forward)
58             {
59 0         0 require AnyEvent::Finger::Client;
60 0         0 $args->{forward} = AnyEvent::Finger::Client->new;
61             }
62             }
63            
64             my $cb = sub {
65 20     20   2688 my ($fh, $host, $port) = @_;
66              
67 20         34 my $handle;
68             $handle = AnyEvent::Handle->new(
69             fh => $fh,
70             on_error => sub {
71 0         0 my ($hdl, $fatal, $msg) = @_;
72 0         0 $args->{on_error}->($msg);
73 0         0 $_[0]->destroy;
74             },
75             on_eof => sub {
76 0         0 $handle->destroy;
77             },
78 20         203 );
79              
80             $handle->push_read( line => sub {
81 20         3391 my($handle, $line) = @_;
82 20         48 $line =~ s/\015?\012//g;
83              
84             my $res = sub {
85 43         74 my $lines = shift;
86 43 100       127 $lines = [ $lines ] unless ref $lines eq 'ARRAY';
87 43         89 foreach my $line (@$lines)
88             {
89 65 100       1743 if(defined $line)
90             {
91 45         166 $handle->push_write($line . "\015\012");
92             }
93             else
94             {
95 20         76 $handle->destroy;
96 20         806 return;
97             }
98             }
99 20         105 };
100              
101 20         85 bless $res, 'AnyEvent::Finger::Response';
102 20         107 my $req = AnyEvent::Finger::Request->new($line);
103            
104             my $tx = bless {
105             req => $req,
106             res => $res,
107             remote_port => $port,
108             local_port => $self->{bindport},
109 20         132 remote_address => $host,
110             }, 'AnyEvent::Finger::Transaction';
111            
112 20 100 100     84 if($args->{forward_deny} && $tx->req->forward_request)
113             {
114 4         41 $res->(['finger forwarding service denied', undef]);
115 4         46 return;
116             }
117            
118 16 100 100     64 if($forward && $req->forward_request)
119             {
120 5         8 my $host = pop @{ $req->hostnames };
  5         11  
121 5         13 my $new_request = join '@', $req->username, @{ $req->hostnames };
  5         10  
122 5 100       13 $new_request = '/W ' . $new_request if $req->verbose;
123             $forward->finger($new_request, sub {
124 5         9 my $lines = shift;
125 5         10 push @$lines, undef;
126 5         11 $res->($lines);
127 5         37 }, { hostname => $host });
128 5         26 return;
129             }
130              
131 11         32 $callback->($tx);
132 20         1792 });
133 6         26 };
134            
135 6         13 my $port = $args->{port};
136 6 50       20 undef $port if $port == 0;
137            
138             $self->{guard} = tcp_server $args->{hostname}, $port, $cb, sub {
139 6     6   1465 my($fh, $host, $port) = @_;
140 6         17 $self->{bindport} = $port;
141 6         20 $args->{on_bind}->($self);
142 6         35 };
143            
144 6         562 $self;
145             }
146              
147              
148 10     10 1 145 sub bindport { shift->{bindport} }
149              
150              
151             sub stop
152             {
153 1     1 1 1919 my($self) = @_;
154 1         6 delete $self->{guard};
155 1         44 delete $self->{bindport};
156 1         3 $self;
157             }
158              
159             1;
160              
161             __END__