Amazon-Signature4-Lite

 view release on metacpan or  search on metacpan

t/01-signature4-lite.t  view on Meta::CPAN

    method  => 'PUT',
    url     => 'https://s3.amazonaws.com/bucket/key',
    payload => 'hello world',
    time    => $TEST_TIME,
  );
  is $signed->{'x-amz-content-sha256'},
    'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9',
    'payload hash for "hello world"';

  # scalar ref payload
  my $data    = 'hello world';
  my $signed2 = $signer->sign(
    method  => 'PUT',
    url     => 'https://s3.amazonaws.com/bucket/key',
    payload => \$data,
    time    => $TEST_TIME,
  );
  is $signed2->{'x-amz-content-sha256'}, $signed->{'x-amz-content-sha256'}, 'scalar ref produces same hash as scalar';
};

########################################################################
# _encode_path
########################################################################

subtest '_encode_path' => sub {
  is Amazon::Signature4::Lite::_encode_path('/'), '/', 'root path unchanged';

  is Amazon::Signature4::Lite::_encode_path('/bucket/key'), '/bucket/key', 'simple path unchanged';

  is Amazon::Signature4::Lite::_encode_path('/bucket/my key.txt'), '/bucket/my%20key.txt', 'space encoded';

  is Amazon::Signature4::Lite::_encode_path('/bucket/my+key.txt'), '/bucket/my%2Bkey.txt', 'plus encoded';

  is Amazon::Signature4::Lite::_encode_path('/bucket/path/to/key/'), '/bucket/path/to/key/', 'trailing slash preserved';

  is Amazon::Signature4::Lite::_encode_path('/bucket/k[1].txt'), '/bucket/k%5B1%5D.txt', 'brackets encoded';

  # S3 uses single path encoding — % signs in existing encoded sequences
  # are encoded to %25, resulting in apparent double-encoding of the sequence
  is Amazon::Signature4::Lite::_encode_path('/bucket/key%2Fwith%2Fslashes'),
    '/bucket/key%252Fwith%252Fslashes', 'existing encoding double-encoded';

};

########################################################################
# canonical query string
########################################################################

subtest 'canonical query string' => sub {
  my $signer = new_signer();

  # query params must be sorted
  my $signed = $signer->sign(
    method => 'GET',
    url    => 'https://s3.amazonaws.com/bucket?prefix=foo&list-type=2&max-keys=10',
    time   => $TEST_TIME,
  );

  ok defined $signed->{Authorization}, 'signs URL with query string';

  # verify sorted order appears in signed headers
  # (we check that the signing didn't die and produced a signature)
  like $signed->{Authorization}, qr/Signature=[0-9a-f]{64}/, 'signature produced with query params';
};

########################################################################
# parse_service_url
########################################################################

subtest 'parse_service_url' => sub {
  # class method call
  my @r = Amazon::Signature4::Lite->parse_service_url(
    host           => 's3.amazonaws.com',
    default_region => 'us-east-1',
  );
  is $r[1], 's3',        's3 global endpoint — service';
  is $r[2], 'us-east-1', 's3 global endpoint — falls back to default region';

  # regional S3
  @r = Amazon::Signature4::Lite->parse_service_url(
    host           => 's3.us-east-2.amazonaws.com',
    default_region => 'us-east-1',
  );
  is $r[1], 's3',        'regional S3 — service';
  is $r[2], 'us-east-2', 'regional S3 — region extracted';

  # non-S3 service
  @r = Amazon::Signature4::Lite->parse_service_url(
    host           => 'ec2.us-west-2.amazonaws.com',
    default_region => 'us-east-1',
  );
  is $r[1], 'ec2',       'EC2 endpoint — service';
  is $r[2], 'us-west-2', 'EC2 endpoint — region extracted';

  # explicit service/region override
  @r = Amazon::Signature4::Lite->parse_service_url(
    host    => 's3.amazonaws.com',
    service => 'execute-api',
    region  => 'ap-southeast-1',
  );
  is $r[1], 'execute-api',    'explicit service not overridden';
  is $r[2], 'ap-southeast-1', 'explicit region not overridden';

  # LocalStack — no match, falls back to defaults
  @r = Amazon::Signature4::Lite->parse_service_url(
    host           => 'localhost:4566',
    default_region => 'us-east-1',
  );
  is $r[2], 'us-east-1', 'LocalStack falls back to default region';

  # instance method call also works
  my $signer = new_signer();
  @r = $signer->parse_service_url(
    host           => 's3.eu-west-1.amazonaws.com',
    default_region => 'us-east-1',
  );
  is $r[1], 's3',        'instance method call — service';
  is $r[2], 'eu-west-1', 'instance method call — region';
};

########################################################################



( run in 1.616 second using v1.01-cache-2.11-cpan-364913b4093 )