File Coverage

blib/lib/Mojo/UserAgent/Paranoid.pm
Criterion Covered Total %
statement 51 58 87.9
branch 11 22 50.0
condition n/a
subroutine 8 8 100.0
pod 0 1 0.0
total 70 89 78.6


line stmt bran cond sub pod time code
1             package Mojo::UserAgent::Paranoid 0.01;
2 2     2   214043 use 5.020;
  2         6  
3 2     2   859 use Mojo::Base 'Mojo::UserAgent';
  2         17170  
  2         11  
4 2     2   1118863 use Mojo::IOLoop::Client::Paranoid;
  2         42  
  2         47  
5              
6             =head1 NAME
7              
8             Mojo::UserAgent::Paranoid - paranoid user agent for fetching unknown URLs
9              
10             =head1 SYNOPSIS
11              
12             my $io = Mojo::IOLoop->singleton;
13             my $ua = Mojo::UserAgent::Paranoid->new(
14             paranoid_dns => Net::DNS::Paranoid->new(
15             blocked_hosts => [qr{\.dev.example\.com$}]
16             ),
17             ioloop => $io,
18             );
19              
20             =cut
21              
22             has 'paranoid_dns' => sub { Net::DNS::Paranoid->new() };
23              
24             # Copied from Mojo::IOLoop::client() , and adapted to create a paranoid
25             # client instead
26             sub paranoid_client {
27 4     4 0 7 my $self = shift;
28 4         8 my $ioloop = shift;
29 4         8 my $cb = pop;
30              
31 4         30 my $id = $ioloop->_id;
32 4         126 my $client = $ioloop->{out}{$id}{client} = Mojo::IOLoop::Client::Paranoid->new(
33             paranoid_dns => $self->paranoid_dns,
34             );
35 4         809 weaken $ioloop;
36             $client->on(
37             connect => sub {
38 1     1   130189 delete $ioloop->{out}{$id}{client};
39 1         16 my $stream = Mojo::IOLoop::Stream->new(pop);
40 1         84 $ioloop->_stream($stream => $id);
41 1         204 $ioloop->$cb(undef, $stream);
42             }
43 4         28 );
44 4     3   44 $client->on(error => sub { $ioloop->_remove($id); $ioloop->$cb(pop, undef) });
  3         44  
  3         120  
45 4         36 $client->connect(@_);
46 4         185 return $id;
47             }
48              
49             # Copied from Mojo::UserAgent, with the line ->client(...) changed to ->paranoid_client(...)
50             sub _connect {
51 4     4   251635 my ($self, $loop, $tx, $handle) = @_;
52 4         19 my $t = $self->transactor;
53 4 50       32 my ($proto, $host, $port) = $handle ? $t->endpoint($tx) : $t->peer($tx);
54 4         343 my %options = (timeout => $self->connect_timeout);
55 4 50       34 if ($proto eq 'http+unix') { $options{path} = $host }
  0         0  
56 4         17 else { @options{qw(address port)} = ($host, $port) }
57 4         13 $options{socket_options} = $self->socket_options;
58 4 50       25 $options{handle} = $handle if $handle;
59             # SOCKS
60 4 50       40 if ($proto eq 'socks') {
61 0         0 @options{qw(socks_address socks_port)} = @options{qw(address port)};
62 0         0 ($proto, @options{qw(address port)}) = $t->endpoint($tx);
63 0         0 my $userinfo = $tx->req->via_proxy(0)->proxy->userinfo;
64 0 0       0 @options{qw(socks_user socks_pass)} = split /:/, $userinfo if $userinfo;
65             }
66             # TLS
67 4 100       16 if ($options{tls} = $proto eq 'https') {
68 1         4 map { $options{"tls_$_"} = $self->$_ } qw(ca cert key);
  3         63  
69 1         19 $options{tls_options} = $self->tls_options;
70 1 50       13 $options{tls_options}{SSL_verify_mode} = 0x00 if $self->insecure;
71             }
72 4         36 weaken $self;
73 4         6 my $id;
74             return $id = $self->paranoid_client($loop,
75             %options => sub {
76 4     4   11 my ($loop, $err, $stream) = @_;
77             # Connection error
78 4 50       40 return unless $self;
79 4 100       22 return $self->_error($id, $err) if $err;
80             # Connection established
81 1         10 $stream->on(timeout => sub { $self->_error($id, 'Inactivity timeout') });
  0         0  
82 1 50       14 $stream->on(close => sub { $self && $self->_finish($id, 1) });
  1         3912  
83 1 0       14 $stream->on(error => sub { $self && $self->_error($id, pop) });
  0         0  
84 1         10 $stream->on(read => sub { $self->_read($id, pop) });
  1         34988  
85 1         21 $self->_process($id);
86             }
87 4         39 );
88             }
89              
90             1;
91              
92             =head1 SEE ALSO
93              
94             L
95              
96             L
97              
98             =cut