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   2929 use strict;
  5         13  
  5         166  
4 5     5   28 use warnings;
  5         10  
  5         174  
5 5     5   26 use Carp qw( carp croak );
  5         11  
  5         277  
6 5     5   1083 use AnyEvent;
  5         5847  
  5         148  
7 5     5   1790 use AnyEvent::Handle;
  5         39947  
  5         278  
8 5     5   1516 use AnyEvent::Socket qw( tcp_server );
  5         32032  
  5         352  
9 5     5   2487 use AnyEvent::Finger::Transaction;
  5         13  
  5         173  
10 5     5   2309 use AnyEvent::Finger::Request;
  5         14  
  5         149  
11 5     5   2290 use AnyEvent::Finger::Response;
  5         13  
  5         4917  
12              
13             # ABSTRACT: Simple asynchronous finger server
14             our $VERSION = '0.12'; # VERSION
15              
16              
17             sub new
18             {
19 5     5 1 10037 my $class = shift;
20 5 50       38 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  0         0  
21 5         13 my $port = $args->{port};
22 5 100       22 $port = 79 unless defined $port;
23 5         11 my $forward_deny = $args->{forward_deny};
24 5 100       16 $forward_deny = 0 unless defined $forward_deny;
25 5         12 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     90 forward_deny => $forward_deny,
      100        
33             forward => $forward,
34             }, $class;
35             }
36              
37              
38             sub start
39             {
40 6     6 1 6322 my $self = shift;
41 6         14 my $callback = shift;
42 6 100       27 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  1         4  
43              
44 6 50       38 croak "already started" if $self->{guard};
45              
46 6         22 for(qw( hostname port on_error on_bind forward forward_deny ))
47             {
48 36 100       78 next if defined $args->{$_};
49 33         76 $args->{$_} = $self->{$_};
50             }
51              
52              
53 6         17 my $forward = $args->{forward};
54 6 50       20 $forward = $self->{forward} unless defined $forward;
55 6 100       21 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   3041 my ($fh, $host, $port) = @_;
66              
67 20         35 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         262 );
79              
80             $handle->push_read( line => sub {
81 20         3669 my($handle, $line) = @_;
82 20         46 $line =~ s/\015?\012//g;
83              
84             my $res = sub {
85 43         74 my $lines = shift;
86 43 100       136 $lines = [ $lines ] unless ref $lines eq 'ARRAY';
87 43         89 foreach my $line (@$lines)
88             {
89 65 100       1881 if(defined $line)
90             {
91 45         169 $handle->push_write($line . "\015\012");
92             }
93             else
94             {
95 20         77 $handle->destroy;
96 20         925 return;
97             }
98             }
99 20         111 };
100              
101 20         107 bless $res, 'AnyEvent::Finger::Response';
102 20         110 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         124 remote_address => $host,
110             }, 'AnyEvent::Finger::Transaction';
111              
112 20 100 100     88 if($args->{forward_deny} && $tx->req->forward_request)
113             {
114 4         42 $res->(['finger forwarding service denied', undef]);
115 4         47 return;
116             }
117              
118 16 100 100     87 if($forward && $req->forward_request)
119             {
120 5         11 my $host = pop @{ $req->hostnames };
  5         11  
121 5         23 my $new_request = join '@', $req->username, @{ $req->hostnames };
  5         11  
122 5 100       15 $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         39 }, { hostname => $host });
128 5         25 return;
129             }
130              
131 11         38 $callback->($tx);
132 20         1839 });
133 6         30 };
134              
135 6         15 my $port = $args->{port};
136 6 50       23 undef $port if $port == 0;
137              
138             $self->{guard} = tcp_server $args->{hostname}, $port, $cb, sub {
139 6     6   1679 my($fh, $host, $port) = @_;
140 6         18 $self->{bindport} = $port;
141 6         28 $args->{on_bind}->($self);
142 6         46 };
143              
144 6         546 $self;
145             }
146              
147              
148 10     10 1 147 sub bindport { shift->{bindport} }
149              
150              
151             sub stop
152             {
153 1     1 1 2140 my($self) = @_;
154 1         7 delete $self->{guard};
155 1         57 delete $self->{bindport};
156 1         4 $self;
157             }
158              
159             1;
160              
161             __END__