File Coverage

blib/lib/MessagePack/RPC/HTTP/Client.pm
Criterion Covered Total %
statement 18 42 42.8
branch 0 8 0.0
condition 0 2 0.0
subroutine 6 11 54.5
pod 0 5 0.0
total 24 68 35.2


line stmt bran cond sub pod time code
1             package MessagePack::RPC::HTTP::Client;
2 1     1   832 use 5.008005;
  1         3  
  1         32  
3 1     1   5 use strict;
  1         2  
  1         32  
4 1     1   13 use warnings;
  1         2  
  1         29  
5              
6 1     1   4 use Carp;
  1         1  
  1         85  
7              
8 1     1   839 use Data::MessagePack;
  1         1184  
  1         28  
9 1     1   746 use Furl;
  1         36558  
  1         428  
10              
11             our $VERSION = "0.02";
12              
13             my $HEADER = ["Content-Type" => "application/x-msgpack"];
14              
15             # copy & paste from msgpack-rpc-over-http/lib/msgpack-rpc-over-http.rb
16             my $REQUEST = 0; # [0, msgid, method, param]
17             my $RESPONSE = 1; # [1, msgid, error, result]
18             my $NOTIFY = 2; # [2, method, param]
19              
20             my $NO_METHOD_ERROR = 0x01;
21             my $ARGUMENT_ERROR = 0x02;
22              
23             sub new {
24 0     0 0   my ($this, $url, %options) = @_;
25 0   0       my $self = bless +{
26             url => $url,
27             http_client => Furl->new(
28             agent => "msgpack-rpc-over-http client (perl $VERSION)",
29             timeout => $options{timeout} || 5,
30             ),
31             seqid => 0,
32             }, $this;
33 0           $self;
34             }
35              
36             sub call {
37 0     0 0   my ($self, $method, @args) = @_;
38 0           $self->send_request($method, \@args);
39             }
40              
41             sub send_request { # param: ArrayRef
42 0     0 0   my ($self, $method, $param) = @_;
43 0           my $data = $self->create_request_body($method, $param);
44             # $furl->post($url :Str, $headers :ArrayRef[Str], $content :Any)
45 0           my $res = $self->{http_client}->post($self->{url}, $HEADER, $data);
46 0 0         unless ($res->is_success) {
47 0           croak "ServerError: check server log or status";
48             }
49 0           my $body = $res->body;
50 0           $self->get_result($body);
51             }
52              
53             my $SEQID_MAX = ( 1 << 31 );
54              
55             sub create_request_body {
56 0     0 0   my ($self, $method, $param) = @_;
57 0           my $msgid = ($self->{seqid})++;
58 0 0         $self->{seqid} = 0 if $self->{seqid} >= $SEQID_MAX;
59 0           Data::MessagePack->pack([$REQUEST, $msgid, $method, $param]);
60             }
61              
62             sub get_result {
63 0     0 0   my ($self, $body) = @_;
64             # type, msgid, err, res
65 0           my ($type, $msgid, $err, $res) = @{ Data::MessagePack->unpack($body) };
  0            
66 0 0         if ($type != $RESPONSE) {
67 0           croak "Unknown message type $type";
68             }
69 0 0         if (not defined($err)) {
70 0           return $res;
71             } else {
72 0           croak "RemoteError $err: $res";
73             }
74             }
75              
76             1;
77             __END__