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   249182 use 5.008008;
  3         12  
  3         143  
4 3     3   20 use constant { false => !1, true => !0 };
  3         4  
  3         233  
5 3     3   16 use strict;
  3         9  
  3         94  
6 3     3   15 use warnings;
  3         5  
  3         90  
7 3     3   1923 use utf8;
  3         6  
  3         15  
8              
9             BEGIN {
10 3     3   6 $IO::Callback::HTTP::AUTHORITY = 'cpan:TOBYINK';
11 3         68 $IO::Callback::HTTP::VERSION = '0.002';
12             }
13              
14 3     3   15 use Carp qw();
  3         6  
  3         54  
15 3     3   4529 use Encode qw( encode_utf8 );
  3         47388  
  3         346  
16 3     3   915 use Errno qw( EIO );
  3         1574  
  3         674  
17 3     3   1332 use HTTP::Request::Common qw( GET PUT );
  3         43012  
  3         199  
18 3     3   3783 use LWP::UserAgent qw();
  3         95594  
  3         98  
19 3     3   38 use Scalar::Util qw( blessed );
  3         6  
  3         563  
20 3     3   17 use URI qw();
  3         6  
  3         56  
21              
22 3     3   3118 use namespace::clean;
  3         84165  
  3         19  
23 3     3   695 use base 'IO::Callback';
  3         8  
  3         3292  
24              
25             our $_LAST_CODE;
26              
27             sub USER_AGENT ()
28             {
29 5   66 5 1 323 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 15005 my ($self, $mode, $code, @args) = @_;
37            
38 5 50       153 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         152 $self->SUPER::open($mode, $code);
47             }
48              
49              
50             sub _process_arg
51             {
52 5     5   24 my ($self, $arg) = @_;
53            
54 5 100 66     275 if (defined $arg->{failure} and not ref $arg->{failure})
55             {
56 1 50       33 my $carpage = Carp::->can($arg->{failure})
57             or Carp::croak("Unknown failure mode: '$arg->{failure}'");
58             $arg->{failure} = sub
59             {
60 1     1   4 my $res = shift;
61 1         7 $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         191 }
69             }
70              
71             sub _mk_reader
72             {
73 3     3   10 my ($self, $code, %args) = @_;
74 3         20 $self->_process_arg(\%args);
75            
76 3 100 33     165 if ((not ref $code)
      66        
77             or (blessed $code and $code->isa('URI')))
78             {
79 1         35 $code = GET($code);
80             }
81            
82 3 50 33     12703 if (blessed $code and $code->isa('HTTP::Request'))
83             {
84 3   33     35 my $ua = $args{agent} || USER_AGENT;
85 3 50       4638 my $bytes = exists $args{bytes} ? $args{bytes} : true;
86 3         13 my $req = $code;
87 3         7 my $done = false;
88            
89             return sub
90             {
91 4 100   4   4189 return undef if $done;
92 3         39 my $res = $ua->request($req);
93 3         63896 $done = true;
94            
95 3 100       21 if ($res->is_success)
96             {
97 2 50       68 return encode_utf8($res->decoded_content) if $bytes;
98 0         0 return $res->decoded_content;
99             }
100            
101 1         16 $! = EIO;
102 1 50       12 $args{failure}->($res) if $args{failure};
103 0         0 return IO::Callback::Error;
104             }
105 3         42 }
106            
107 0         0 return;
108             }
109              
110             sub _mk_writer
111             {
112 2     2   15 my ($self, $code, %args) = @_;
113 2         18 $self->_process_arg(\%args);
114            
115 2 100 33     178 if ((not ref $code)
      66        
116             or (blessed $code and $code->isa('URI')))
117             {
118 1         27 $code = PUT($code, Content => '');
119             }
120            
121 2 50 33     13634 if (blessed $code and $code->isa('HTTP::Request'))
122             {
123 2   33     17 my $ua = $args{agent} || USER_AGENT;
124 2 50       4442 my $bytes = exists $args{bytes} ? $args{bytes} : true;
125 2         6 my $req = $code;
126 2         5 my $done = false;
127 2         4 my $body = '';
128             return sub
129             {
130 4     4   247 my $str = shift;
131 4 100       15 if (length $str)
132             {
133 2 50       8 $body .= $bytes ? $str : encode_utf8($str);
134 2         5 return;
135             }
136            
137 2         28 $req->content($body);
138 2         53 $req->header(Content_length => length $req->content);
139 2         184 my $res = $ua->request($req);
140            
141 2 50       50136 if ($res->is_success)
142             {
143 2 50       61 $args{success}->($res) if $args{success};
144 2         12393 return;
145             }
146            
147 0           $! = EIO;
148 0 0         $args{failure}->($res) if $args{failure};
149 0           return IO::Callback::Error;
150             }
151 2         31 }
152            
153 0           return;
154             }
155              
156             # Your code goes here
157              
158             true;
159              
160             __END__