File Coverage

blib/lib/Plient/Handler/curl.pm
Criterion Covered Total %
statement 6 86 6.9
branch 0 40 0.0
condition 0 21 0.0
subroutine 2 11 18.1
pod 0 6 0.0
total 8 164 4.8


line stmt bran cond sub pod time code
1             package Plient::Handler::curl;
2 5     5   3655 use strict;
  5         11  
  5         187  
3 5     5   26 use warnings;
  5         9  
  5         7958  
4              
5             require Plient::Handler unless $Plient::bundle_mode;
6             our @ISA = 'Plient::Handler';
7              
8             require Plient::Util unless $Plient::bundle_mode;
9             Plient::Util->import;
10              
11             my ( $curl, $curl_config, %all_protocol, %protocol, %method );
12              
13             %all_protocol =
14             map { $_ => undef } qw/http https ftp ftps file telnet ldap dict tftp/;
15 0     0 0   sub all_protocol { return \%all_protocol }
16 0     0 0   sub protocol { return \%protocol }
17 0     0 0   sub method { return \%method }
18              
19             my $inited;
20             sub init {
21 0 0   0 0   return if $inited;
22 0           $inited = 1;
23 0   0       $curl = $ENV{PLIENT_CURL} || which('curl');
24 0   0       $curl_config = $ENV{PLIENT_CURL_CONFIG} || which('curl-config');
25 0 0         return unless $curl;
26 0 0         if ($curl_config) {
27 0 0         if ( my $out = `$curl_config --protocols` ) {
28 0           @protocol{ map { lc } split /\r?\n/, $out } = ();
  0            
29             }
30             else {
31 0           warn $!;
32 0           return;
33             }
34             }
35             else {
36             # by default, curl should support http
37 0           %protocol = ( http => undef );
38             }
39              
40 0 0         if ( exists $protocol{http} ) {
41             $method{http_get} = sub {
42 0     0     my ( $uri, $args ) = @_;
43 0           my $headers = translate_headers( $args );
44 0           my $auth = translate_auth($args);
45 0 0         warn "$curl -k -s -L $headers $auth $uri\n" if $ENV{PLIENT_DEBUG};
46 0 0         if ( open my $fh, "$curl -k -s -L $headers $auth '$uri' |" ) {
47 0           local $/;
48 0           <$fh>;
49             }
50             else {
51 0           warn "failed to get $uri with curl: $!";
52 0           return;
53             }
54 0           };
55              
56             $method{http_post} = sub {
57 0     0     my ( $uri, $args ) = @_;
58              
59              
60 0           my $headers = translate_headers($args);
61 0           my $auth = translate_auth($args);
62              
63 0           my $data = '';
64 0           my $post_opt;
65 0 0 0       if ( $args->{content_type} && $args->{content_type} =~ /form-data/ )
66             {
67 0           $post_opt = '-F';
68             }
69             else {
70 0           $post_opt = '-d';
71             }
72              
73 0 0         if ( $args->{body_array} ) {
74 0           my $body = $args->{body_array};
75              
76 0           for ( my $i = 0 ; $i < $#$body ; $i += 2 ) {
77 0           my $key = $body->[$i];
78 0 0         my $value =
79             defined $body->[ $i + 1 ] ? $body->[ $i + 1 ] : '';
80 0 0 0       if ( ref $value eq 'HASH' && $value->{file} ) {
81              
82             # file upload
83 0           $data .= " $post_opt '$key=\@$value->{file}'";
84             }
85             else {
86 0           $data .= " $post_opt '$key=$value'";
87             }
88             }
89             }
90              
91 0 0         warn "$curl -s -L $data $headers $auth $uri\n" if $ENV{PLIENT_DEBUG};
92 0 0         if ( open my $fh, "$curl -s -L $data $headers $auth '$uri' |" ) {
93 0           local $/;
94 0           <$fh>;
95             }
96             else {
97 0           warn "failed to post $uri with curl: $!";
98 0           return;
99             }
100 0           };
101             $method{http_head} = sub {
102 0     0     my ( $uri, $args ) = @_;
103 0           my $headers = translate_headers( $args );
104 0           my $auth = translate_auth($args);
105 0 0         warn "$curl -s -I -L $headers $auth $uri\n" if $ENV{PLIENT_DEBUG};
106 0 0         if ( open my $fh, "$curl -s -I -L $headers $auth '$uri' |" ) {
107 0           local $/;
108 0           my $head = <$fh>;
109 0           $head =~ s/\r\n$//;
110 0           return $head;
111             }
112             else {
113 0           warn "failed to get head of $uri with curl: $!";
114 0           return;
115             }
116 0           };
117             }
118              
119 0 0         if ( exists $protocol{https} ) {
120 0           for my $m (qw/get post head put/) {
121 0 0         $method{"https_$m"} = $method{"http_$m"}
122             if exists $method{"http_$m"};
123             }
124             }
125 0           return 1;
126             }
127              
128             sub translate_headers {
129 0   0 0 0   my $args = shift || {};
130 0           my $headers = $args->{headers};
131 0 0         return '' unless $headers;
132 0           my $str;
133 0           for my $k ( keys %$headers ) {
134 0           $str .= " -H '$k:$headers->{$k}'";
135             }
136 0           return $str;
137              
138             }
139              
140             sub translate_auth {
141 0   0 0 0   my $args = shift || {};
142 0           my $auth = '';
143 0 0 0       if ( $args->{user} && defined $args->{password} ) {
144 0   0       my $method = lc( $args->{auth_method} || 'basic' );
145 0 0         if ( $method eq 'basic' ) {
146 0           $auth = " -u '$args->{user}:$args->{password}'";
147             }
148             else {
149 0           die "aborting: unsupported auth method: $method";
150             }
151             }
152 0           return $auth;
153             }
154              
155             __PACKAGE__->_add_to_plient if $Plient::bundle_mode;
156              
157             1;
158              
159             __END__