File Coverage

blib/lib/IO/Callback/HTTP.pm
Criterion Covered Total %
statement 93 100 93.0
branch 25 38 65.7
condition 14 30 46.6
subroutine 23 23 100.0
pod 2 2 100.0
total 157 193 81.3


line stmt bran cond sub pod time code
1             package IO::Callback::HTTP;
2              
3 3     3   266548 use 5.008008;
  3         12  
  3         163  
4 3     3   18 use constant { false => !1, true => !0 };
  3         8  
  3         253  
5 3     3   18 use strict;
  3         10  
  3         109  
6 3     3   17 use warnings;
  3         4  
  3         101  
7 3     3   3057 use utf8;
  3         29  
  3         15  
8              
9             BEGIN {
10 3     3   151 $IO::Callback::HTTP::AUTHORITY = 'cpan:TOBYINK';
11 3         57 $IO::Callback::HTTP::VERSION = '0.003';
12             }
13              
14 3     3   18 use Carp qw();
  3         5  
  3         55  
15 3     3   3237 use Encode qw( encode_utf8 );
  3         39333  
  3         384  
16 3     3   983 use Errno qw( EIO );
  3         1774  
  3         405  
17 3     3   295677 use HTTP::Request::Common qw( GET PUT );
  3         525004  
  3         201  
18 3     3   153452 use LWP::UserAgent qw();
  3         760449  
  3         109  
19 3     3   38 use Scalar::Util qw( blessed );
  3         8  
  3         684  
20 3     3   19 use URI qw();
  3         7  
  3         52  
21              
22 3     3   3121 use namespace::clean;
  3         63701  
  3         23  
23 3     3   778 use base 'IO::Callback';
  3         6  
  3         3052  
24              
25             our $_LAST_CODE;
26              
27             sub USER_AGENT ()
28             {
29 5   66 5 1 247 our $USER_AGENT ||= LWP::UserAgent::->new(
30             agent => sprintf('%s/%s ', __PACKAGE__, __PACKAGE__->VERSION),
31             );
32             }
33              
34             sub open
35             {
36 5     5 1 15296 my ($self, $mode, $code, @args) = @_;
37            
38 5 50       130 unless (ref $code eq 'CODE')
39             {
40 5 100       115 $_LAST_CODE =
41             $code = ($mode eq '<')
42             ? $self->_mk_reader($code, @args)
43             : $self->_mk_writer($code, @args)
44             }
45            
46 5         143 $self->SUPER::open($mode, $code);
47             }
48              
49              
50             sub _process_arg
51             {
52 5     5   19 my ($self, $arg) = @_;
53            
54 5 100 66     136 if (defined $arg->{failure} and not ref $arg->{failure})
55             {
56 1 50       35 my $carpage = Carp::->can($arg->{failure})
57             or Carp::croak("Unknown failure mode: '$arg->{failure}'");
58             $arg->{failure} = sub
59             {
60 1     1   3 my $res = shift;
61 1         5 $carpage->(sprintf(
62             'HTTP %s request for <%s> failed: %s',
63             $res->request->method,
64             $res->request->uri,
65             $res->status_line,
66             ));
67             }
68 1         20 }
69             }
70              
71             sub _mk_reader
72             {
73 3     3   28 my ($self, $code, %args) = @_;
74 3         21 $self->_process_arg(\%args);
75            
76 3 100 33     186 if ((not ref $code)
      66        
77             or (blessed $code and $code->isa('URI')))
78             {
79 1         37 $code = GET($code);
80             }
81            
82 3 50 33     12259 if (blessed $code and $code->isa('HTTP::Request'))
83             {
84 3   33     37 my $ua = $args{agent} || USER_AGENT;
85 3 50       104825 my $bytes = exists $args{bytes} ? $args{bytes} : true;
86 3         17 my $req = $code;
87 3         8 my $done = false;
88            
89             return sub
90             {
91 4 100   4   3977 return undef if $done;
92 3         34 my $res = $ua->request($req);
93 3         1261111 $done = true;
94            
95 3 100       21 if ($res->is_success)
96             {
97 2 50       60 return encode_utf8($res->decoded_content) if $bytes;
98 0         0 return $res->decoded_content;
99             }
100            
101 1         16 $! = EIO;
102 1 50       9 $args{failure}->($res) if $args{failure};
103 0         0 return IO::Callback::Error;
104             }
105 3         37 }
106            
107 0         0 return;
108             }
109              
110             sub _mk_writer
111             {
112 2     2   35 my ($self, $code, %args) = @_;
113 2         18 $self->_process_arg(\%args);
114            
115 2 100 33     33 if ((not ref $code)
      66        
116             or (blessed $code and $code->isa('URI')))
117             {
118 1         24 $code = PUT($code, Content => '');
119             }
120            
121 2 50 33     13368 if (blessed $code and $code->isa('HTTP::Request'))
122             {
123 2   33     24 my $ua = $args{agent} || USER_AGENT;
124 2 50       4309 my $bytes = exists $args{bytes} ? $args{bytes} : true;
125 2         5 my $req = $code;
126 2         3 my $done = false;
127 2         5 my $body = '';
128             return sub
129             {
130 4     4   217 my $str = shift;
131 4 100       14 if (length $str)
132             {
133 2 50       8 $body .= $bytes ? $str : encode_utf8($str);
134 2         6 return;
135             }
136            
137 2         23 $req->content($body);
138 2         90 $req->header(Content_length => length $req->content);
139 2         150 my $res = $ua->request($req);
140            
141 2 50       108609 if ($res->is_success)
142             {
143 2 50       194 $args{success}->($res) if $args{success};
144 2         9153 return;
145             }
146            
147 0           $! = EIO;
148 0 0         $args{failure}->($res) if $args{failure};
149 0           return IO::Callback::Error;
150             }
151 2         33 }
152            
153 0           return;
154             }
155              
156             # Your code goes here
157              
158             true;
159              
160             __END__