Amazon-S3-Lite

 view release on metacpan or  search on metacpan

lib/Amazon/S3/Lite.pm  view on Meta::CPAN


  # Collect x-amz-meta-* headers, stripping the prefix from the key
  my %metadata;
  for my $name ( keys %{$headers} ) {
    if ( $name =~ /^x-amz-meta-(.+)$/xsm ) {
      $metadata{$1} = $headers->{$name};
    }
  }

  return {
    content_type   => $headers->{'content-type'},
    content_length => $headers->{'content-length'} + 0,
    etag           => $etag,
    last_modified  => $headers->{'last-modified'},
    metadata       => \%metadata,
  };
}

########################################################################
# get_object( $bucket, $key, %options )
#

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


  no warnings 'redefine';

  # 404 returns undef
  local *Amazon::S3::Lite::_request = mock_request( status => 404 );
  ok !defined $s3->head_object( 'b', 'k' ), '404 returns undef';

  # success
  local *Amazon::S3::Lite::_request = mock_request(
    headers => {
      'content-type'      => 'text/plain',
      'content-length'    => '42',
      'etag'              => '"abc123"',
      'last-modified'     => 'Wed, 01 Jan 2025 00:00:00 GMT',
      'x-amz-meta-source' => 'lambda',
    },
  );
  my $r = $s3->head_object( 'test-bucket', 'hello.txt' );
  is $r->{content_type},   'text/plain', 'content_type';
  is $r->{content_length}, 42,           'content_length is integer';
  is $r->{etag},           'abc123',     'etag stripped of quotes';

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

  no warnings 'redefine';

  # 404 returns undef
  local *Amazon::S3::Lite::_request = mock_request( status => 404 );
  ok !defined $s3->get_object( 'b', 'k' ), '404 returns undef';

  # in-memory success
  local *Amazon::S3::Lite::_request = mock_request(
    content => 'hello world',
    headers => {
      'content-type'   => 'text/plain',
      'content-length' => '11',
      'etag'           => '"abc123"',
      'last-modified'  => 'Wed, 01 Jan 2025 00:00:00 GMT',
    },
  );
  my $r = $s3->get_object( 'test-bucket', 'hello.txt' );
  is $r->{content},      'hello world', 'content returned';
  is $r->{content_type}, 'text/plain',  'content_type';
  is $r->{etag},         'abc123',      'etag clean';

  # range header passed through
  my $captured = {};
  local *Amazon::S3::Lite::_request = mock_request(
    status  => 206,
    content => 'hello',
    headers => { 'content-type' => 'text/plain', 'content-length' => '5', 'etag' => '"abc"' },
    capture => \$captured,
  );
  $s3->get_object( 'test-bucket', 'hello.txt', range => 'bytes=0-4' );
  is $captured->{headers}{Range}, 'bytes=0-4', 'Range header set';

  # filename — streaming to disk
  {
    my ( $fh, $fname ) = tempfile( UNLINK => 1 );
    close $fh;

    local *Amazon::S3::Lite::_request = sub {
      my ( $self, $method, $url, $headers, $content, $extra ) = @_;
      $extra->{data_callback}->('hello ') if $extra->{data_callback};
      $extra->{data_callback}->('world')  if $extra->{data_callback};
      return {
        status  => 200,
        reason  => 'OK',
        headers => { 'content-type' => 'text/plain', 'content-length' => '11', 'etag' => '"abc"' },
        content => '',
      };
    };

    my $meta = $s3->get_object( 'test-bucket', 'hello.txt', filename => $fname );
    ok !exists $meta->{content}, 'no content key when filename used';
    ok -f $fname,                'file created';
    open my $in, '<', $fname or die $!;
    is do { local $/; <$in> }, 'hello world', 'file content correct';
  }



( run in 2.297 seconds using v1.01-cache-2.11-cpan-524268b4103 )