AWS-Signature-V4

 view release on metacpan or  search on metacpan

t/errors.t  view on Meta::CPAN

      local $SIG{__DIE__} = sub { die Carp::longmess($_[0]) } if $how eq 'die handler';
      AWS::Signature::V4->new(%x509, x509 => {
         key_type => 'RSA', certificate => $der, serial => 1,
         private_key => 'garbage', private_key_password => $secret,
      });
   };
   like $e->message, qr{\Acannot load the private key: [^\n]+\z},
      "$how: the message is one line";
   unlike "$e", qr{\Q$secret\E}, "$how: the message does not include the password";
}
like dies { $s->sign(url => 'http://h/') }, qr{ at \S*errors\.t line \d+},
   'same for the errors of sign';

# options: undefined is like missing, derived values cannot be set
my $t = AWS::Signature::V4->new(
   service => 's3', region => 'r', %cred,
   payload_header => undef, double_encode => undef, normalize_path => undef,
);
ok $t->payload_header, 'undefined payload_header: default for s3';
ok !$t->double_encode, 'undefined double_encode: default for s3';
ok !$t->normalize_path, 'undefined normalize_path: default for s3';
like $t->sign(method => 'GET', url => 'http://h/')->{headers},
   {'x-amz-content-sha256' => qr/\A[0-9a-f]{64}\z/}, 'the header is there';

my $u = AWS::Signature::V4->new(
   service => 's', region => 'r', %cred,
   algorithm => 'RSA', _signer => undef, _x509_serial => 'X',
);
is $u->algorithm, 'AWS4-HMAC-SHA256', 'algorithm cannot be set';

my %mine = (access_key_id => 'a', secret_access_key => 'b');
my $v = AWS::Signature::V4->new(service => 's', region => 'r', credentials => \%mine);
$mine{access_key_id} = 'EVIL';
is $v->credentials->{access_key_id}, 'a', 'credentials are copied';

# a subclass can assign $_ in its builders
{
   package Sub::Signer;
   use Moo;
   extends 'AWS::Signature::V4';
   has '+region' => (lazy => 1, builder => 1);
   sub _build_region { $_ = 'eu-west-1'; return $_ }
}
is(Sub::Signer->new(service => 's', %cred)->region, 'eu-west-1', 'builders can use $_');

# no warnings for what used to be accepted silently
is warns { $s->sign(method => 'GET', url => 'http://h/', headers => {'X-Opt' => undef}) },
   0, 'undefined header value: no warnings';

# the chunker is not confused by its own errors
my $ck = streaming($s, decoded_content_length => 9, checksum => 'sha256',
   trailers => ['x-foo'], signed_headers => ['host'])->{chunker};
$ck->chunk('123456789');
ouch_like sub { $ck->finish }, 400, 'missing trailer value';
like $ck->finish('x-foo' => 1),
   qr{x-amz-checksum-sha256:\Q@{[ encode_base64(sha256('123456789'), '') ]}\E\r\n},
   'the checksum survives a failed finish';

$ck = streaming($s, decoded_content_length => 4)->{chunker};
$ck->chunk('abc');
ouch_like sub { $ck->chunk('xy') }, 400, 'too much data';
ok lives { $ck->chunk('x') }, 'a chunk that fits is still accepted';
ok lives { $ck->finish }, 'and the stream can be completed';

done_testing;



( run in 2.456 seconds using v1.01-cache-2.11-cpan-16aabcbfbcb )