File Coverage

blib/lib/JSON/RPC/Simple/Client.pm
Criterion Covered Total %
statement 59 66 89.3
branch 17 26 65.3
condition 6 9 66.6
subroutine 10 11 90.9
pod 1 1 100.0
total 93 113 82.3


line stmt bran cond sub pod time code
1             package JSON::RPC::Simple::Client;
2              
3 1     1   744 use strict;
  1         2  
  1         33  
4 1     1   5 use warnings;
  1         2  
  1         29  
5              
6 1     1   5 use Carp qw(croak);
  1         2  
  1         46  
7 1     1   1567 use LWP::UserAgent;
  1         312733  
  1         42  
8 1     1   1201 use JSON qw();
  1         15279  
  1         32  
9 1     1   11 use URI::Escape qw();
  1         2  
  1         32  
10              
11             require JSON::RPC::Simple;
12              
13 1     1   7 use constant DEFAULT_TIMEOUT => 180;
  1         2  
  1         65  
14 1         879 use constant JSON_RPC_HTTP_HEADERS => (
15             Content_Type => "application/json; charset=UTF-8",
16             Accept => 'application/json',
17 1     1   6 );
  1         2  
18              
19             sub new {
20 2     2 1 7 my ($pkg, $uri, $attrs) = @_;
21            
22 2 100       11 $attrs = {} unless ref $attrs eq "HASH";
23            
24 2   33     74 my $agent = delete $attrs->{agent} || "JSON::RPC::Simple " .
25             JSON::RPC::Simple->VERSION;
26            
27 2 50       33 my $ua = LWP::UserAgent->new(
28             agent => $agent,
29             timeout => (
30             exists $attrs->{timeout} ?
31             delete $attrs->{timeout} :
32             DEFAULT_TIMEOUT
33             ),
34             );
35            
36 2         86038 my $get = $attrs->{GET};
37              
38             # Since the last component in GET call is the method name make sure we have a separator
39 2 100 66     23 $uri .= "/" if $get && substr($uri, -1, 1) ne '/';
40            
41 2         50 my $self = bless {
42             json => JSON->new->utf8,
43             %$attrs,
44             ua => $ua,
45             uri => $uri,
46             GET => $get,
47             }, $pkg;
48              
49 2         11 return $self;
50             }
51              
52 0     0   0 sub DESTROY {
53             # or AUTOLOAD will pick this up
54             }
55              
56             my $next_request_id = 0;
57              
58             our $AUTOLOAD;
59             sub AUTOLOAD {
60 4     4   2371 my ($self, $params) = @_;
61              
62 4         28 my $method = $AUTOLOAD;
63 4         34 $method =~ s/.*:://;
64            
65 4         8 my $id = ++$next_request_id;
66            
67 4         8 my $r;
68              
69 4         8 my $sent = '';
70 4 100       18 unless ($self->{GET}) {
71 1         31 my $content = $self->{json}->encode({
72             version => "1.1",
73             method => $method,
74             params => $params,
75             id => $id,
76             });
77 1         4 $sent = $content;
78              
79 1         8 $r = $self->{ua}->post(
80             $self->{uri},
81             JSON_RPC_HTTP_HEADERS,
82             Content => $content,
83             );
84             }
85             else {
86 3 100 100     44 croak "GET only supports named parameters" if $params && ref $params ne 'HASH';
87 2 100       10 $params = {} unless $params;
88            
89 2         8 my $params = join "&", map { "$_=" . URI::Escape::uri_escape_utf8($params->{$_}) } keys %$params;
  2         56  
90              
91 2         24 my $request_uri = $self->{uri} . $method . '?' . ${params};
92            
93 2         15 $r = $self->{ua}->get(
94             $request_uri,
95             JSON_RPC_HTTP_HEADERS,
96             );
97             }
98            
99 3 50       1241408 if ($r->is_success) {
100 3 50       50 if ($r->content_type !~ /application\/json/) {
101 0         0 croak("Bad response. Response was not type 'application/json'\n\nResponse:\n" . $r->decoded_content);
102             }
103             }
104             else {
105 0 0       0 croak $r->decoded_content unless $r->content_type =~ m{^application/json};
106             }
107            
108 3         102 my $result;
109 3         6 eval {
110 3         22 my $content = $r->decoded_content;
111              
112 3 50       439 if ($self->{debug}) {
113 0         0 print STDERR "RPC-Server: " . $self->{uri} . "\n\n";
114 0         0 print STDERR "Sent: $sent\n";
115 0         0 print STDERR "Recv: " . $r->decoded_content . "\n";
116 0         0 print STDERR "\n";
117             }
118              
119 3         26 $result = $self->{json}->decode($r->decoded_content);
120             };
121 3 50       500 croak $@ if $@;
122 3 50       18 croak "Didn't get a JSON object back" unless ref $result eq "HASH";
123 3 50       14 croak $result->{error}->{message} if $result->{error};
124              
125 3         60 return $result->{result};
126             }
127              
128             1;
129             __END__