File Coverage

blib/lib/WebService/Simple.pm
Criterion Covered Total %
statement 68 153 44.4
branch 11 60 18.3
condition 9 19 47.3
subroutine 15 25 60.0
pod 8 8 100.0
total 111 265 41.8


line stmt bran cond sub pod time code
1             package WebService::Simple;
2 8     8   151153 use strict;
  8         21  
  8         316  
3 8     8   36 use warnings;
  8         11  
  8         287  
4 8     8   38 use base qw(LWP::UserAgent Class::Data::ConfigHash);
  8         19  
  8         6179  
5 8     8   336328 use Class::Inspector;
  8         25530  
  8         273  
6 8     8   5217 use Data::Dumper ();
  8         45036  
  8         219  
7 8     8   66 use Digest::MD5 ();
  8         14  
  8         117  
8 8     8   28 use URI::Escape;
  8         11  
  8         635  
9 8     8   4005 use URI::QueryParam;
  8         4795  
  8         238  
10 8     8   46 use HTTP::Message;
  8         10  
  8         165  
11 8     8   4281 use Hash::MultiValue;
  8         17030  
  8         269  
12 8     8   3963 use WebService::Simple::Response;
  8         16  
  8         235  
13 8     8   4122 use UNIVERSAL::require;
  8         10088  
  8         70  
14              
15             our $VERSION = '0.23';
16              
17             __PACKAGE__->config(
18             base_url => '',
19             response_parser => { module => "XML::Simple" },
20             );
21              
22             sub new {
23 7     7 1 1794 my $class = shift;
24 7         29 my %args = @_;
25 7   33     45 my $base_url = delete $args{base_url}
26             || $class->config->{base_url}
27             || Carp::croak("base_url is required");
28 7         63 $base_url = URI->new($base_url);
29 7   100     55217 my $basic_params = delete $args{params} || delete $args{param} || {};
30 7   50     46 my $debug = delete $args{debug} || 0;
31              
32 7   66     119 my $response_parser = delete $args{response_parser}
33             || $class->config->{response_parser};
34 7 50 33     220 if ( !$response_parser
35 7         225 || !eval { $response_parser->isa('WebService::Simple::Parser') } )
36             {
37 7   33     26 my $config = $response_parser || $class->config->{response_parser};
38 7 100       26 if ( !ref $config ) {
39 2         6 $config = { module => $config };
40             }
41 7         16 my $module = $config->{module};
42 7 50       65 if ( $module !~ s/^\+// ) {
43 7         20 $module = __PACKAGE__ . "::Parser::$module";
44             }
45 7 50       59 if ( !Class::Inspector->loaded($module) ) {
46 7 100       678 $module->require or die;
47             }
48 2 50       28 $response_parser = $module->new( %{ $config->{args} || {} } );
  2         23  
49             }
50              
51 2         6 my $cache = delete $args{cache};
52 2 50 33     11 if ( !$cache || ref $cache eq 'HASH' ) {
53 2 50       31 my $config = ref $cache eq 'HASH' ? $cache : $class->config->{cache};
54 2 50       67 if ($config) {
55 0 0       0 if ( !ref $config ) {
56 0         0 $config = { module => $config };
57             }
58              
59 0         0 my $module = $config->{module};
60 0 0       0 if ( !Class::Inspector->loaded($module) ) {
61 0 0       0 $module->require or die;
62             }
63             $cache =
64 0         0 $module->new( $config->{hashref_args}
65             ? $config->{args}
66 0 0       0 : %{ $config->{args} } );
67             }
68             }
69              
70 2         18 my $self = $class->SUPER::new(%args);
71 2         5 $self->{base_url} = $base_url;
72 2         7 $self->{basic_params} = $basic_params;
73 2         4 $self->{response_parser} = $response_parser;
74 2         2 $self->{cache} = $cache;
75 2         5 $self->{debug} = $debug;
76 2         7 return $self;
77             }
78              
79 2     2   137 sub _agent { "libwww-perl/$LWP::VERSION+". __PACKAGE__ .'/'.$VERSION }
80              
81 0     0 1 0 sub base_url { $_[0]->{base_url} }
82 0     0 1 0 sub basic_params { $_[0]->{basic_params} }
83 2     2 1 20 sub response_parser { $_[0]->{response_parser} }
84 0     0 1   sub cache { $_[0]->{cache} }
85              
86             sub __cache_get {
87 0     0     my $self = shift;
88 0           my $cache = $self->cache;
89 0 0         return unless $cache;
90              
91 0           my $key = $self->__cache_key(shift);
92 0           return $cache->get( $key, @_ );
93             }
94              
95             sub __cache_set {
96 0     0     my $self = shift;
97 0           my $cache = $self->cache;
98 0 0         return unless $cache;
99              
100 0           my $key = $self->__cache_key(shift);
101 0           return $cache->set( $key, @_ );
102             }
103              
104             sub __cache_remove {
105 0     0     my $self = shift;
106 0           my $cache = $self->cache;
107 0 0         return unless $cache;
108              
109 0           my $key = $self->__cache_key(shift);
110 0           return $cache->remove( $key, @_ );
111             }
112              
113             sub __cache_key {
114 0     0     my $self = shift;
115 0           local $Data::Dumper::Indent = 1;
116 0           local $Data::Dumper::Terse = 1;
117 0           local $Data::Dumper::Sortkeys = 1;
118 0           return Digest::MD5::md5_hex( Data::Dumper::Dumper( $_[0] ) );
119             }
120              
121             sub request_url {
122 0     0 1   my $self = shift;
123 0           my %args = @_;
124            
125 0 0         my $uri = ref($args{url}) =~ m/^URI/ ? $args{url}->clone() : URI->new($args{url});
126 0 0         if ( my $extra_path = $args{extra_path} ) {
127 0           $extra_path =~ s!^/!!;
128 0           $uri->path( $uri->path . $extra_path );
129             }
130 0 0         if($args{params}) {
131 0 0         if(ref $args{params} eq 'Hash::MultiValue') {
132 0           for my $key ($args{params}->keys) {
133 0           $uri->query_param_append($key, $args{params}->get($key));
134             }
135             }else{
136 0           $uri->query_form(%{$args{params}});
  0            
137             }
138             }
139 0           return $uri;
140             }
141              
142             sub get {
143 0     0 1   my $self = shift;
144 0           my ($url, $extra) = ("", {});
145              
146 0 0         if ( ref $_[0] eq 'HASH' ) {
147 0           $extra = shift @_;
148             }
149             else {
150 0           $url = shift @_;
151 0 0         if ( ref $_[0] eq 'HASH' ) {
152 0           $extra = shift @_;
153             }
154             }
155              
156 0           my $uri = $self->request_url(
157             url => $self->base_url,
158             extra_path => $url,
159 0           params => Hash::MultiValue->new(%{$self->basic_params}, %$extra),
160             );
161              
162 0 0         warn "Request URL is $uri\n" if $self->{debug};
163              
164 0           my @headers = @_;
165 0           my $can_accept = HTTP::Message::decodable();
166 0           push @headers, ('Accept-Encoding' => $can_accept);
167              
168 0           my $response;
169 0           $response = $self->__cache_get( [ $uri, @headers ] );
170 0 0         if ($response) {
171 0 0         if ($response->isa('WebService::Simple::Response')) { # backward compatibility
172 0           return $response;
173             } else {
174 0           return WebService::Simple::Response->new_from_response(
175             response => $response,
176             parser => $self->response_parser
177             );
178             }
179             }
180              
181 0           $response = $self->SUPER::get( $uri, @headers );
182 0 0         if ( !$response->is_success ) {
183 0           Carp::croak("request to $uri failed");
184             }
185 0           $self->__cache_set( [ $uri, @headers ], $response );
186 0           $response = WebService::Simple::Response->new_from_response(
187             response => $response,
188             parser => $self->response_parser
189             );
190 0           return $response;
191             }
192              
193             sub post {
194 0     0 1   my $self = shift;
195 0           my ( $url, $extra ) = ( '', {} );
196              
197 0 0         if ( ref $_[0] eq 'HASH' ) { # post(\%arg [, @header ])
    0          
    0          
198 0           $extra = shift @_;
199             }
200             elsif ( ref $_[1] eq 'HASH' ) { # post($url, \%arg [, @header ])
201 0           $url = shift @_;
202 0           $extra = shift @_;
203             }
204             elsif ( @_ % 2 ) { # post($url [, @header ])
205 0           $url = shift @_;
206             }
207              
208 0           my $uri = $self->request_url(
209             url => $self->base_url,
210             extra_path => $url,
211 0           params => Hash::MultiValue->new(%{$self->basic_params}, %$extra),
212             );
213 0           my $content = $uri->query_form_hash();
214 0           $uri->query_form(undef);
215              
216 0           my @headers = @_;
217              
218 0           my $response = $self->SUPER::post( $uri, $content, @headers );
219              
220 0 0         if ( !$response->is_success ) {
221 0           Carp::croak( "request to $url failed: " . $response->status_line );
222             }
223 0           $response = WebService::Simple::Response->new_from_response(
224             response => $response,
225             parser => $self->response_parser
226             );
227 0           return $response;
228             }
229              
230             1;
231              
232             __END__