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   2410 use strict;
  5         11  
  5         134  
4 5     5   24 use warnings;
  5         7  
  5         122  
5 5     5   22 use Carp qw( carp croak );
  5         8  
  5         207  
6 5     5   898 use AnyEvent;
  5         5130  
  5         165  
7 5     5   1557 use AnyEvent::Handle;
  5         32810  
  5         156  
8 5     5   1259 use AnyEvent::Socket qw( tcp_server );
  5         30631  
  5         342  
9 5     5   2065 use AnyEvent::Finger::Transaction;
  5         11  
  5         138  
10 5     5   1744 use AnyEvent::Finger::Request;
  5         10  
  5         127  
11 5     5   1918 use AnyEvent::Finger::Response;
  5         12  
  5         4114  
12              
13             # ABSTRACT: Simple asynchronous finger server
14             our $VERSION = '0.14'; # VERSION
15              
16              
17             sub new
18             {
19 5     5 1 7918 my $class = shift;
20 5 50       27 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  0         0  
21 5         13 my $port = $args->{port};
22 5 100       14 $port = 79 unless defined $port;
23 5         9 my $forward_deny = $args->{forward_deny};
24 5 100       12 $forward_deny = 0 unless defined $forward_deny;
25 5         8 my $forward = $args->{forward};
26 5 100       14 $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     86 forward_deny => $forward_deny,
      100        
33             forward => $forward,
34             }, $class;
35             }
36              
37              
38             sub start
39             {
40 6     6 1 4777 my $self = shift;
41 6         10 my $callback = shift;
42 6 100       20 my $args = ref $_[0] eq 'HASH' ? (\%{$_[0]}) : ({@_});
  1         3  
43              
44 6 50       26 croak "already started" if $self->{guard};
45              
46 6         15 for(qw( hostname port on_error on_bind forward forward_deny ))
47             {
48 36 100       68 next if defined $args->{$_};
49 33         57 $args->{$_} = $self->{$_};
50             }
51              
52              
53 6         10 my $forward = $args->{forward};
54 6 50       15 $forward = $self->{forward} unless defined $forward;
55 6 100       15 if($forward)
56             {
57 1 50       3 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   2283 my ($fh, $host, $port) = @_;
66              
67 20         26 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         162 );
79              
80             $handle->push_read( line => sub {
81 20         2852 my($handle, $line) = @_;
82 20         32 $line =~ s/\015?\012//g;
83              
84             my $res = sub {
85 43         55 my $lines = shift;
86 43 100       115 $lines = [ $lines ] unless ref $lines eq 'ARRAY';
87 43         72 foreach my $line (@$lines)
88             {
89 65 100       1338 if(defined $line)
90             {
91 45         141 $handle->push_write($line . "\015\012");
92             }
93             else
94             {
95 20         97 $handle->destroy;
96 20         663 return;
97             }
98             }
99 20         81 };
100              
101 20         72 bless $res, 'AnyEvent::Finger::Response';
102 20         84 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         91 remote_address => $host,
110             }, 'AnyEvent::Finger::Transaction';
111              
112 20 100 100     77 if($args->{forward_deny} && $tx->req->forward_request)
113             {
114 4         13 $res->(['finger forwarding service denied', undef]);
115 4         19 return;
116             }
117              
118 16 100 100     48 if($forward && $req->forward_request)
119             {
120 5         10 my $host = pop @{ $req->hostnames };
  5         32  
121 5         24 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         7 my $lines = shift;
125 5         9 push @$lines, undef;
126 5         7 $res->($lines);
127 5         28 }, { hostname => $host });
128 5         21 return;
129             }
130              
131 11         31 $callback->($tx);
132 20         1476 });
133 6         22 };
134              
135 6         11 my $port = $args->{port};
136 6 50       13 undef $port if $port == 0;
137              
138             $self->{guard} = tcp_server $args->{hostname}, $port, $cb, sub {
139 6     6   1179 my($fh, $host, $port) = @_;
140 6         15 $self->{bindport} = $port;
141 6         15 $args->{on_bind}->($self);
142 6         33 };
143              
144 6         446 $self;
145             }
146              
147              
148 10     10 1 116 sub bindport { shift->{bindport} }
149              
150              
151             sub stop
152             {
153 1     1 1 1574 my($self) = @_;
154 1         5 delete $self->{guard};
155 1         37 delete $self->{bindport};
156 1         3 $self;
157             }
158              
159             1;
160              
161             __END__