File Coverage

blib/lib/WWW/BetterServers/API.pm
Criterion Covered Total %
statement 30 72 41.6
branch 0 14 0.0
condition 0 31 0.0
subroutine 10 14 71.4
pod 3 3 100.0
total 43 134 32.0


line stmt bran cond sub pod time code
1             package WWW::BetterServers::API;
2              
3 2     2   65472 use 5.010001;
  2         7  
  2         84  
4 2     2   13 use strict;
  2         3  
  2         74  
5 2     2   11 use warnings;
  2         7  
  2         69  
6 2     2   2708 use POSIX 'strftime';
  2         16765  
  2         15  
7 2     2   7003 use Digest::SHA 'hmac_sha256_hex';
  2         12284  
  2         245  
8 2     2   1950 use Mojo::JSON;
  2         157375  
  2         108  
9 2     2   2040 use Mojo::URL;
  2         19714  
  2         28  
10 2     2   2320 use Mojo::UserAgent;
  2         612006  
  2         67  
11 2     2   85 use Mojo::Util 'encode';
  2         4  
  2         140  
12 2     2   20 use Mojo::Base -base;
  2         5  
  2         18  
13              
14             our $VERSION = '0.09';
15              
16             has [qw(api_id api_secret auth_type api_host
17             api_port api_scheme agent)];
18              
19             sub new {
20 0     0 1   my $class = shift;
21 0           my $self = {};
22 0           bless $self, $class;
23              
24 0           my %args = @_;
25 0           for my $key (qw(api_id api_secret auth_type api_host api_port api_scheme agent)) {
26 0 0         $self->{$key} = $args{$key} if exists $args{$key};
27             }
28              
29 0   0       $self->{api_host} ||= 'api.betterservers.com';
30 0   0       $self->{agent} ||= "WWW-BetterServers-API/$VERSION";
31              
32 0           $self->{_ua} = Mojo::UserAgent->new;
33 0           $self->{_ua}->transactor->name($self->{agent});
34              
35 0           return $self;
36             }
37              
38             sub ua {
39 0     0 1   $_[0]->{_ua};
40             }
41              
42             sub request {
43 0     0 1   my $self = shift;
44 0           my %args = @_;
45              
46 0   0       $args{host} //= $self->{api_host};
47 0   0       $args{api_id} //= $self->{api_id};
48 0   0       $args{secret} //= $self->{api_secret};
49 0   0       $args{auth_type} //= $self->{auth_type};
50 0   0       $args{scheme} //= $self->{api_scheme} // 'https';
      0        
51 0   0       $args{port} //= $self->{api_port};
52 0   0       $args{date} //= strftime("%a, %d %b %Y %T GMT", gmtime);
53 0 0 0       $args{body} //= ($args{payload} ? Mojo::JSON->new->encode($args{payload}) : '');
54              
55 0           $args{url} = Mojo::URL->new($args{uri});
56 0           $args{url}->scheme($args{scheme});
57 0           $args{url}->host($args{host});
58 0 0         $args{url}->port($args{port}) if $args{port};
59              
60 0           my $req_str = join("\x0d\x0a",
61             encode('UTF-8', $args{method}),
62             encode('UTF-8', $args{host}),
63             encode('UTF-8', $args{date}),
64             encode('UTF-8', $args{url}->path),
65             $args{body});
66              
67 0 0         if ($ENV{BSAPI_AUTH_DEBUG}) {
68 0           print STDERR "url: " . $args{url}->path . "\n";
69 0           print STDERR "signed url: " . hmac_sha256_hex($args{url}->path, $args{secret}) . "\n";
70 0           print STDERR "body: " . $args{body} . "\n";
71 0           print STDERR "signed body: " . hmac_sha256_hex($args{body}, $args{secret}) . "\n";
72 0           print STDERR "url + body: " . hmac_sha256_hex($args{url}->path . $args{body}, $args{secret}) . "\n";
73 0           print STDERR "string: " . $req_str . "\n";
74 0           print STDERR "signature: " . hmac_sha256_hex($req_str, $args{secret}) . "\n";
75             }
76              
77 0     0     my $signature = sub { hmac_sha256_hex( $req_str,
78 0           $args{secret} ) }->();
79              
80 0           my $headers = { Date => $args{date},
81             "Content-Type" => "application/json",
82             Authorization => "$args{auth_type} $args{api_id}:$signature" };
83              
84 0           my $sub = lc($args{method});
85              
86 0 0         ref($args{pre_hook}) eq 'CODE' && $args{pre_hook}->($self, \%args, $headers);
87              
88 0 0         my $tx = $self->ua->$sub($args{url}->to_string,
89             $headers,
90             $args{body},
91             (ref($args{callback}) eq 'CODE' ? $args{callback} : ()));
92              
93 0 0         return (ref($args{callback}) eq 'CODE' ? undef : $tx->res);
94             }
95              
96             1;
97             __END__