| line | stmt | bran | cond | sub | pod | time | code | 
| 1 | 7 |  |  | 7 |  | 35 | use strict; | 
|  | 7 |  |  |  |  | 13 |  | 
|  | 7 |  |  |  |  | 188 |  | 
| 2 | 7 |  |  | 7 |  | 33 | use warnings; | 
|  | 7 |  |  |  |  | 17 |  | 
|  | 7 |  |  |  |  | 245 |  | 
| 3 |  |  |  |  |  |  |  | 
| 4 |  |  |  |  |  |  | package WebService::Shippo::Request; | 
| 5 | 7 |  |  | 7 |  | 36 | use Carp                 ( 'confess' ); | 
|  | 7 |  |  |  |  | 13 |  | 
|  | 7 |  |  |  |  | 319 |  | 
| 6 | 7 |  |  | 7 |  | 33 | use JSON::XS             (); | 
|  | 7 |  |  |  |  | 13 |  | 
|  | 7 |  |  |  |  | 108 |  | 
| 7 | 7 |  |  | 7 |  | 824337 | use LWP                  (); | 
|  | 7 |  |  |  |  | 477737 |  | 
|  | 7 |  |  |  |  | 183 |  | 
| 8 | 7 |  |  | 7 |  | 5436 | use LWP::Protocol::https (); | 
|  | 7 |  |  |  |  | 724335 |  | 
|  | 7 |  |  |  |  | 325 |  | 
| 9 | 7 |  |  | 7 |  | 63 | use Clone                ( 'clone' ); | 
|  | 7 |  |  |  |  | 16 |  | 
|  | 7 |  |  |  |  | 453 |  | 
| 10 | 7 |  |  | 7 |  | 42 | use URI::Encode          ( 'uri_encode' ); | 
|  | 7 |  |  |  |  | 16 |  | 
|  | 7 |  |  |  |  | 5335 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | { | 
| 13 |  |  |  |  |  |  | my $value = { | 
| 14 |  |  |  |  |  |  | 'Content-Type'  => 'application/json', | 
| 15 |  |  |  |  |  |  | 'Accept'        => 'application/json', | 
| 16 |  |  |  |  |  |  | 'Pragma'        => 'no-cache', | 
| 17 |  |  |  |  |  |  | 'Cache-Control' => 'max-age=0, no-cache, no-store', | 
| 18 |  |  |  |  |  |  | 'Expires'       => 'Fri, 26 Oct 2001 00:00:00 GMT', | 
| 19 |  |  |  |  |  |  | }; | 
| 20 |  |  |  |  |  |  |  | 
| 21 | 14 | 100 |  | 14 | 0 | 398 | sub headers { wantarray ? %$value : $value } | 
| 22 |  |  |  |  |  |  | } | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | { | 
| 25 |  |  |  |  |  |  | my $value = undef; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | sub user_agent | 
| 28 |  |  |  |  |  |  | { | 
| 29 | 14 |  |  | 14 | 0 | 32273 | my ( $class, $new_value ) = @_; | 
| 30 | 14 | 100 |  |  |  | 94 | return $value unless @_ > 1; | 
| 31 | 7 |  |  |  |  | 18 | $value = $new_value; | 
| 32 | 7 | 50 |  |  |  | 89 | if ( $value->can( 'agent' ) ) { | 
| 33 | 7 |  |  |  |  | 18 | my $prod = 'Shippo/'; | 
| 34 | 7 |  |  |  |  | 102 | $prod .= WebService::Shippo::Resource->DEFAULT_API_VERSION; | 
| 35 | 7 |  |  |  |  | 29 | $prod .= " WebService\::Shippo/$WebService::Shippo::VERSION"; | 
| 36 | 7 | 50 |  |  |  | 70 | $prod .= ' ' . $value->_agent | 
| 37 |  |  |  |  |  |  | if $value->can( '_agent' ); | 
| 38 | 7 |  |  |  |  | 61 | $value->agent( $prod ); | 
| 39 | 7 |  |  |  |  | 511 | headers->{'X-Shippo-Client-User-Agent'} = $value->agent; | 
| 40 |  |  |  |  |  |  | } | 
| 41 | 7 |  |  |  |  | 18 | return $class; | 
| 42 |  |  |  |  |  |  | } | 
| 43 |  |  |  |  |  |  | } | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | sub query_string | 
| 46 |  |  |  |  |  |  | { | 
| 47 | 7 |  |  | 7 | 0 | 18 | my ( $invocant, $params ) = @_; | 
| 48 | 7 | 50 |  |  |  | 31 | return '' | 
| 49 |  |  |  |  |  |  | unless ref( $params ); | 
| 50 | 7 |  |  |  |  | 18 | my @pairs; | 
| 51 | 7 |  |  |  |  | 39 | while ( my ( $k, $v ) = each %$params ) { | 
| 52 | 0 |  |  |  |  | 0 | $k = uri_encode( $k ); | 
| 53 | 0 |  |  |  |  | 0 | $v = uri_encode( $v ); | 
| 54 | 0 |  |  |  |  | 0 | push @pairs, join( '=', $k, $v ); | 
| 55 |  |  |  |  |  |  | } | 
| 56 | 7 | 50 |  |  |  | 37 | return '' | 
| 57 |  |  |  |  |  |  | unless @pairs; | 
| 58 | 0 |  |  |  |  | 0 | return '?' . join( ';', @pairs ); | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | { | 
| 62 |  |  |  |  |  |  | my $json          = JSON::XS->new->utf8->convert_blessed->allow_blessed; | 
| 63 |  |  |  |  |  |  | my $last_response = undef; | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | sub response | 
| 66 |  |  |  |  |  |  | { | 
| 67 | 0 |  |  | 0 | 0 | 0 | return $last_response; | 
| 68 |  |  |  |  |  |  | } | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | sub confess_failure | 
| 71 |  |  |  |  |  |  | { | 
| 72 | 0 |  |  | 0 | 0 | 0 | confess sprintf "%s\n%s\n\tFailed request", $last_response->status_line, | 
| 73 |  |  |  |  |  |  | $last_response->content; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | sub get | 
| 77 |  |  |  |  |  |  | { | 
| 78 | 7 |  |  | 7 | 0 | 20 | my ( $invocant, $url, @params ) = @_; | 
| 79 | 7 | 50 |  |  |  | 43 | @params = ( {} ) | 
| 80 |  |  |  |  |  |  | unless @params; | 
| 81 | 7 | 50 |  |  |  | 36 | my $params = ref( $params[0] ) ? $params[0] : {@params}; | 
| 82 | 7 |  |  |  |  | 33 | $url .= $invocant->query_string( $params ); | 
| 83 | 7 |  |  |  |  | 30 | my $response = user_agent->get( $url, headers ); | 
| 84 | 7 |  |  |  |  | 1073707 | $last_response = clone( $response ); | 
| 85 | 7 | 50 |  |  |  | 86 | $invocant->confess_failure( $response ) | 
| 86 |  |  |  |  |  |  | unless $response->is_success; | 
| 87 | 7 |  |  |  |  | 236 | return $response; | 
| 88 |  |  |  |  |  |  | } | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | sub put | 
| 91 |  |  |  |  |  |  | { | 
| 92 | 0 |  |  | 0 | 0 |  | my ( $invocant, $url, @params ) = @_; | 
| 93 | 0 | 0 |  |  |  |  | @params = ( {} ) | 
| 94 |  |  |  |  |  |  | unless @params; | 
| 95 | 0 | 0 |  |  |  |  | my $params   = ref( $params[0] ) ? $params[0] : {@params}; | 
| 96 | 0 |  |  |  |  |  | my $payload  = $json->encode( $params ); | 
| 97 | 0 |  |  |  |  |  | my $response = user_agent->put( $url, headers, Content => $payload ); | 
| 98 | 0 |  |  |  |  |  | $last_response = clone( $response ); | 
| 99 | 0 | 0 |  |  |  |  | $invocant->confess_failure( $response ) | 
| 100 |  |  |  |  |  |  | unless $response->is_success; | 
| 101 | 0 |  |  |  |  |  | return $response; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | sub post | 
| 105 |  |  |  |  |  |  | { | 
| 106 | 0 |  |  | 0 | 0 |  | my ( $invocant, $url, @params ) = @_; | 
| 107 | 0 | 0 |  |  |  |  | @params = ( {} ) | 
| 108 |  |  |  |  |  |  | unless @params; | 
| 109 | 0 | 0 |  |  |  |  | my $params   = ref( $params[0] ) ? $params[0] : {@params}; | 
| 110 | 0 |  |  |  |  |  | my $payload  = $json->encode( $params ); | 
| 111 | 0 |  |  |  |  |  | my $response = user_agent->post( $url, headers, Content => $payload ); | 
| 112 | 0 |  |  |  |  |  | $last_response = clone( $response ); | 
| 113 | 0 | 0 |  |  |  |  | $invocant->confess_failure( $response ) | 
| 114 |  |  |  |  |  |  | unless $response->is_success; | 
| 115 | 0 |  |  |  |  |  | return $response; | 
| 116 |  |  |  |  |  |  | } | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | BEGIN { | 
| 120 | 7 |  |  | 7 |  | 57 | no warnings 'once'; | 
|  | 7 |  |  |  |  | 18 |  | 
|  | 7 |  |  |  |  | 360 |  | 
| 121 |  |  |  |  |  |  | # Forcing the dev to always use CPAN's perferred "WebService::Shippo" | 
| 122 |  |  |  |  |  |  | # namespace is just cruel; allow the use of "Shippo", too. | 
| 123 | 7 |  |  | 7 |  | 310 | *Shippo::Request:: = *WebService::Shippo::Request::; | 
| 124 |  |  |  |  |  |  | } | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | # Init the user_agent attribute, and all that entails... | 
| 127 |  |  |  |  |  |  | __PACKAGE__->user_agent( LWP::UserAgent->new() ); | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | 1; |