File Coverage

blib/lib/AnyEvent/Whois/Raw.pm
Criterion Covered Total %
statement 102 191 53.4
branch 24 52 46.1
condition 9 31 29.0
subroutine 18 26 69.2
pod 2 10 20.0
total 155 310 50.0


line stmt bran cond sub pod time code
1             package AnyEvent::Whois::Raw;
2              
3 6     6   345653 use base 'Exporter';
  6         76  
  6         920  
4 6     6   5964 use AnyEvent;
  6         33693  
  6         204  
5 6     6   3582 use AnyEvent::Socket;
  6         163554  
  6         689  
6 6     6   4670 use AnyEvent::Handle;
  6         47905  
  6         248  
7 6     6   3813 use AnyEvent::HTTP;
  6         55468  
  6         475  
8 6     6   51 use strict;
  6         8  
  6         169  
9 6     6   31 no warnings 'redefine';
  6         13  
  6         1710  
10              
11             our $VERSION = '0.08';
12             our @EXPORT = qw(whois get_whois);
13             our $stash;
14              
15             BEGIN {
16             sub Net::Whois::Raw::smart_eval(&) {
17 0     0 0 0 my @rv = eval {
18 0         0 $_[0]->();
19             };
20 0 0 0     0 if ($@ && $@ =~ /^Call me later/) {
21 0         0 die $@;
22             }
23            
24 0         0 return @rv;
25             }
26            
27             sub require_hook {
28 176     176 0 854420 my ($self, $fname) = @_;
29            
30 176 100       159633 return if $fname ne 'Net/Whois/Raw.pm';
31 6         26 for my $i (1..$#INC) {
32 48 100       717 if (-e (my $tname = $INC[$i] . '/Net/Whois/Raw.pm')) {
33 6 50       266 open(my $fh, $tname) or next;
34 6         567 return ($fh, \&eval_filter);
35             }
36             }
37 0         0 return;
38             }
39            
40             sub eval_filter {
41 2820 50   2820 0 99907 return 0 if $_ eq '';
42 2820         4512 s/\beval\s*{/smart_eval{/;
43 2820         34714 return 1;
44             }
45            
46 6     6   31 unshift @INC, \&require_hook;
47 6         73 require Net::Whois::Raw;
48             }
49              
50             sub _extract_known_params {
51 5     5   122 my $args = shift;
52 5         43 my %known_params = (
53             timeout => 1,
54             on_prepare => 1,
55             );
56            
57 5         16 my %params;
58 5         10 eval {
59 5         23 for my $i (-2, -2) {
60 6 100       30 if (exists($known_params{$args->[$i-1]})) {
61 1         11 $params{$args->[$i-1]} = $args->[$i];
62 1         5 delete $known_params{$args->[$i-1]};
63 1         5 splice @$args, $i-1, 2;
64             }
65             else {
66 5         11 last;
67             }
68             }
69             };
70            
71 5         63 return \%params;
72             }
73              
74             sub whois {
75 5     5 1 1585 local $stash = {
76             caller => \&_whois,
77             params => _extract_known_params(\@_),
78             args => [@_],
79             };
80            
81 5         14 &_whois;
82             }
83              
84             sub _whois {
85 10     10   29 my $cb = pop;
86            
87 10         24 my ($res_text, $res_srv);
88 10         19 eval {
89 10         60 ($res_text, $res_srv) = Net::Whois::Raw::whois(@_);
90             };
91 10 100       1785 if (!$@) {
    100          
92 4         21 $cb->($res_text, $res_srv);
93             }
94             elsif ($@ !~ /^Call me later/) {
95 1         9 $cb->('', $@);
96             }
97             }
98              
99             sub get_whois {
100 0     0 1 0 local $stash = {
101             caller => \&_get_whois,
102             params => _extract_known_params(\@_),
103             args => [@_],
104             };
105            
106 0         0 &_get_whois;
107             }
108              
109             sub _get_whois {
110 0     0   0 my $cb = pop;
111            
112 0         0 my ($res_text, $res_srv);
113 0         0 eval {
114 0         0 ($res_text, $res_srv) = Net::Whois::Raw::get_whois(@_);
115             };
116 0 0       0 if (!$@) {
    0          
117 0         0 $cb->($res_text, $res_srv);
118             }
119             elsif ($@ !~ /^Call me later/) {
120 0         0 $cb->('', $@);
121             }
122             }
123              
124             sub Net::Whois::Raw::whois_query {
125 10     10 0 626 my $call = $stash->{calls}{whois_query}++;
126 10 100       19 if ($call <= $#{$stash->{results}{whois_query}}) {
  10         53  
127 5   100     43 return $stash->{results}{whois_query}[$call] || die $stash->{errors}{whois_query}[$call], "\n";
128             }
129            
130 5         19 whois_query_ae(@_);
131 5         793 die "Call me later";
132             }
133              
134             sub whois_query_ae {
135 5     5 0 12 my ($dom, $srv_and_port, $is_ns) = @_;
136              
137            
138 5         37 my $whoisquery = Net::Whois::Raw::Common::get_real_whois_query($dom, $srv_and_port, $is_ns);
139 5         52 my $stash_ref = $stash;
140              
141 5         19 my ($srv, $port) = split /:/, $srv_and_port;
142            
143             tcp_connect $srv, $port || 43, sub {
144 5     5   868 my $fh = shift;
145 5 50       14 unless ($fh) {
146 0         0 local $stash = $stash_ref;
147 0         0 $stash->{calls}{whois_query} = 0;
148 0         0 my $i = push @{$stash->{results}{whois_query}}, undef;
  0         0  
149 0         0 $stash->{errors}{whois_query}[$i-1] = "Connection to $srv failed: $!";
150 0         0 $stash->{caller}->(@{$stash->{args}});
  0         0  
151 0         0 return;
152             }
153            
154 5         9 my @lines;
155             my $handle;
156             my $timer = AnyEvent->timer(
157             after => exists $stash_ref->{params}{timeout} ?
158             $stash_ref->{params}{timeout} :
159             $Net::Whois::Raw::TIMEOUT||30,
160             cb => sub {
161 1 50 33     995374 if ($handle && !$handle->destroyed) {
162 1         20 $handle->destroy();
163 1         214 local $stash = $stash_ref;
164 1         6 $stash->{calls}{whois_query} = 0;
165 1         4 my $i = push @{$stash->{results}{whois_query}}, undef;
  1         8  
166 1         16 $stash->{errors}{whois_query}[$i-1] = "Connection to $srv timed out";
167 1         4 $stash->{caller}->(@{$stash->{args}});
  1         8  
168             }
169             }
170 5 100 50     72 );
171             $handle = AnyEvent::Handle->new(
172             fh => $fh,
173             on_read => sub {
174 4         2003416 my @l = split /(?<=\n)/, $_[0]->{rbuf};
175 4 50 33     30 if (@lines && substr($lines[-1], -1) ne "\n") {
176 0         0 $lines[-1] .= shift(@l);
177             }
178 4         18 push @lines, @l;
179 4         17 $_[0]->{rbuf} = '';
180             },
181             on_error => sub {
182 0         0 undef $timer;
183 0         0 $handle->destroy();
184 0         0 local $stash = $stash_ref;
185 0         0 $stash->{calls}{whois_query} = 0;
186 0         0 my $i = push @{$stash->{results}{whois_query}}, undef;
  0         0  
187 0         0 $stash->{errors}{whois_query}[$i-1] = "Read error from $srv: $!";
188 0         0 $stash->{caller}->(@{$stash->{args}});
  0         0  
189             },
190             on_eof => sub {
191 4         395 undef $timer;
192 4         14 local $stash = $stash_ref;
193 4         30 $handle->destroy();
194 4         165 $stash->{calls}{whois_query} = 0;
195 4         9 push @{$stash->{results}{whois_query}}, \@lines;
  4         17  
196 4         9 $stash->{caller}->(@{$stash->{args}});
  4         20  
197             }
198 5         203 );
199            
200 5         698 $handle->push_write($whoisquery."\015\012");
201             }, sub {
202 5     5   1599 my $fh = shift;
203 5         11 local $stash = $stash_ref;
204 5         12 _sock_prepare_cb($fh, $srv);
205 5   50     102 };
206             }
207              
208             sub _sock_prepare_cb {
209 5     5   12 my ($fh, $srv) = @_;
210            
211 5         40 my $sockname = getsockname($fh);
212 5   50     32 my $timeout = $Net::Whois::Raw::TIMEOUT||30;
213            
214 5 50       15 if (exists $stash->{params}{on_prepare}) {
215 0         0 $timeout = $stash->{params}{on_prepare}->($fh);
216             }
217            
218 5         9 my $rotate_reference = eval { Net::Whois::Raw::get_ips_for_query($srv) };
  5         24  
219            
220 5 50 33     70 if (!$rotate_reference && @Net::Whois::Raw::SRC_IPS && $sockname eq getsockname($fh)) {
      33        
221             # we have ip and there was no bind request in on_prepare callback
222 0         0 $rotate_reference = \@Net::Whois::Raw::SRC_IPS;
223             }
224            
225 5 50       12 if ($rotate_reference) {
226 0         0 my $ip = shift @$rotate_reference;
227 0         0 bind $fh, AnyEvent::Socket::pack_sockaddr(0, parse_address($ip));
228 0         0 push @$rotate_reference, $ip; # rotate ips
229             }
230            
231             return exists $stash->{params}{timeout} ?
232             $stash->{params}{timeout} :
233 5 100       20 $timeout;
234             }
235              
236             sub Net::Whois::Raw::www_whois_query {
237 0     0 0   my $call = $stash->{calls}{www_whois_query}++;
238 0 0         if ($call <= $#{$stash->{results}{www_whois_query}}) {
  0            
239 0           return $stash->{results}{www_whois_query}[$call];
240             }
241            
242 0           www_whois_query_ae(@_);
243 0           die "Call me later";
244             }
245              
246             sub www_whois_query_ae {
247 0     0 0   my ($dom) = (lc shift);
248            
249 0           my ($resp, $url);
250 0           my ($name, $tld) = Net::Whois::Raw::Common::split_domain( $dom );
251 0           my @http_query_urls = @{Net::Whois::Raw::Common::get_http_query_url($dom)};
  0            
252            
253 0           www_whois_query_ae_request(\@http_query_urls, $tld, $dom);
254             }
255              
256             sub www_whois_query_ae_request {
257 0     0 0   my ($urls, $tld, $dom) = @_;
258            
259 0           my $qurl = shift @$urls;
260 0 0         unless ($qurl) {
261 0           push @{$stash->{results}{www_whois_query}}, undef;
  0            
262 0           $stash->{calls}{www_whois_query} = 0;
263 0           $stash->{caller}->(@{$stash->{args}});
  0            
264 0           return;
265             }
266            
267 0 0 0       my $referer = delete $qurl->{form}{referer} if $qurl->{form} && defined $qurl->{form}{referer};
268 0 0 0       my $method = ( $qurl->{form} && scalar(keys %{$qurl->{form}}) ) ? 'POST' : 'GET';
269 0           my $stash_ref = $stash;
270            
271             my $cb = sub {
272 0     0     my ($resp, $headers) = @_;
273 0           local $stash = $stash_ref;
274            
275 0 0 0       if (!$resp || $headers->{Status} > 299) {
276 0           www_whois_query_ae_request($urls, $tld, $dom);
277             }
278             else {
279 0           chomp $resp;
280 0           $resp = Net::Whois::Raw::Common::parse_www_content($resp, $tld, $qurl->{url}, $Net::Whois::Raw::CHECK_EXCEED);
281 0           push @{$stash->{results}{www_whois_query}}, $resp;
  0            
282 0           $stash->{calls}{www_whois_query} = 0;
283 0           $stash->{caller}->(@{$stash->{args}});
  0            
284             }
285 0           };
286            
287 0           my $headers = {Referer => $referer};
288 0           my @params;
289             push @params, on_prepare => sub {
290 0     0     my $fh = shift;
291 0           local $stash = $stash_ref;
292 0           _sock_prepare_cb($fh, 'www_whois');
293 0           };
294            
295 0 0         if (exists $stash->{params}{timeout}) {
296 0           push @params, timeout => $stash->{params}{timeout};
297             }
298            
299 0 0         if ($method eq 'POST') {
300 0           require URI::URL;
301            
302 0           my $curl = URI::URL->new("http:");
303 0           $curl->query_form( %{$qurl->{form}} );
  0            
304 0           http_post $qurl->{url}, $curl->equery, headers => $headers, @params, $cb;
305             }
306             else {
307 0           http_get $qurl->{url}, headers => $headers, @params, $cb;
308             }
309             }
310              
311             1;
312              
313             __END__