AWS-S3

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

  - Adds new session_token and region attributes to the constructor (see perldoc)

0.19 2024-01-08
  - Fix "bad hostname" test may fail in presence of wildcard DNS records (GH #19)

0.18 2019-03-01
  - Fix leading slashes defaults to off, see honor_leading_slashes arg

0.17 2019-03-01
  - Fix leading slashes in key names (GH #12)
  - Fix lack of location shouldn't set it to undef (GH #11)

0.16 2019-01-03
  - Remove dependency on Iterator::Paged

0.15 2018-04-20
  - More fixes for ->add_bucket. Fix an error when no location is provided or
    us-east-1 is explicitly asked for. Patch by Dave Rolsky. (GH #9)

0.14 2018-04-13
  - Fix sending of undefined location param in ->add_bucket (GH #9)

Changes  view on Meta::CPAN

  - Fix DNS bucket name checking for non-valid DNS bucket nams (GH #4)
  - Fix URI escaping for filenames to avoid infinite loop on spaces (GH #5)

0.11 2015-08-31
  - Fix signed_url to URI escape the Signature param value (GH #3)

0.10 2015-06-23
  - dist changes related to kwalitee (no functional changes)

0.051 2015-05-23
  - default size to 0 when not set in content-length (GH #1)

0.050 2014-10-23
  New maintainer leejo
  - Add lib/AWS/S3/Request/GetPreSignedUrl.pm to MANIFEST
  - Various changes in dist related to issue tracking, testing, etc

0.040 2014-10-23
  Work done by leejo
  - Add signed_url method to AWS::S3::File and tests
  - Fix load / hash order bugs in AWS::S3::Signer

Changes  view on Meta::CPAN

  - File's S3 was a weak ref, which caused problems.  No longer...

0.020 2011-12-21
  - Updated to be compatible with VSO 0.21

0.019 2011-12-14
  - Bucket's S3 was a weak ref, which caused problems sometimes.  Not anymore...
    we'll see if that fixes it.

0.018 2011-12-13
  - Thanks to ukautz++ (Ulrich Kautz) for adding the ability to set the content-type
    of files stored in S3.
  - He even updated the POD to show how to set the content-type (via 'contenttype').

0.017 2011-12-11
  - Fixed broken META.yml (again)

0.016 2011-12-10
  - Fixed broken META.yml

0.015 2011-12-10
  - Migrated to github.
  - Added repository url to meta.

Changes  view on Meta::CPAN

    on CPAN.

0.010 2011-11-23
  - Added missing files to MANIFEST.

0.009 2011-11-23
  - Added missing prereq Iterator::Paged

0.008 2011-11-23
  - Fixed some POD to clearly show that a scalar reference is always needed
    to set the contents of a file.
  - Removed bad reference to a *::Lite module that doesn't exist on CPAN.

0.007 2011-11-22
  - Fixed AWS::S3::FileIterator to work properly.
  - New tests confirm it.
  - Now require LWP::UserAgent::Determined instead of just LWP::UserAgent.
  - More POD updates.

0.006 2011-11-22
  - Updated some of the POD.

README.markdown  view on Meta::CPAN

</div>

# SYNOPSIS

    use AWS::S3;

    my $s3 = AWS::S3->new(
      access_key_id     => 'E654SAKIASDD64ERAF0O',
      secret_access_key => 'LgTZ25nCD+9LiCV6ujofudY1D6e2vfK0R4GLsI4H',
      session_token     => 'IQob3JpJZ2luXJ2VjJEL7//////////wE...',
      region            => 'eu-west-1', # set to relevant AWS region
      honor_leading_slashes => 0, # set to allow leading slashes in bucket names, defaults to 0
    );

    # Add a bucket:
    my $bucket = $s3->add_bucket(
      name    => 'foo-bucket',
    );

    # Set the acl:
    $bucket->acl( 'private' );

    # Add a file:
    my $new_file = $bucket->add_file(
      key       => 'foo/bar.txt',
      contents  => \'This is the contents of the file',
    );

    # You can also set the contents with a coderef:
    # Coderef should eturn a reference, not the actual string of content:
    $new_file = $bucket->add_file(
      key       => 'foo/bar.txt',
      contents  => sub { return \"This is the contents" }
    );

    # Get the file:
    my $same_file = $bucket->file( 'foo/bar.txt' );

    # Get the contents:

README.markdown  view on Meta::CPAN

Default is `s3.amazonaws.com`

## ua

Optional.  Should be an instance of [LWP::UserAgent](https://metacpan.org/pod/LWP%3A%3AUserAgent) or a subclass of it.

Defaults to creating a new instance of [LWP::UserAgent::Determined](https://metacpan.org/pod/LWP%3A%3AUserAgent%3A%3ADetermined)

## honor\_leading\_slashes

Optional. Boolean to set if bucket names should include any leading slashes
when sent to S3 - defaults to zero

# PUBLIC PROPERTIES

## access\_key\_id

String.  Read-only

## secret\_access\_key

lib/AWS/S3.pm  view on Meta::CPAN

<a href='https://coveralls.io/r/leejo/AWS-S3?branch=master'><img src='https://coveralls.io/repos/leejo/AWS-S3/badge.png?branch=master' alt='Coverage Status' /></a>

=head1 SYNOPSIS

  use AWS::S3;

  my $s3 = AWS::S3->new(
    access_key_id     => 'E654SAKIASDD64ERAF0O',
    secret_access_key => 'LgTZ25nCD+9LiCV6ujofudY1D6e2vfK0R4GLsI4H',
    session_token     => 'IQob3JpJZ2luXJ2VjJEL7//////////wE...',
    region            => 'eu-west-1', # set to relevant AWS region
    honor_leading_slashes => 0, # set to allow leading slashes in bucket names, defaults to 0
  );

  # Add a bucket:
  my $bucket = $s3->add_bucket(
    name    => 'foo-bucket',
  );

  # Set the acl:
  $bucket->acl( 'private' );

  # Add a file:
  my $new_file = $bucket->add_file(
    key       => 'foo/bar.txt',
    contents  => \'This is the contents of the file',
  );

  # You can also set the contents with a coderef:
  # Coderef should eturn a reference, not the actual string of content:
  $new_file = $bucket->add_file(
    key       => 'foo/bar.txt',
    contents  => sub { return \"This is the contents" }
  );

  # Get the file:
  my $same_file = $bucket->file( 'foo/bar.txt' );

  # Get the contents:

lib/AWS/S3.pm  view on Meta::CPAN

Default is C<s3.amazonaws.com>

=head2 ua

Optional.  Should be an instance of L<LWP::UserAgent> or a subclass of it.

Defaults to creating a new instance of L<LWP::UserAgent::Determined>

=head2 honor_leading_slashes

Optional. Boolean to set if bucket names should include any leading slashes
when sent to S3 - defaults to zero

=head1 PUBLIC PROPERTIES

=head2 access_key_id

String.  Read-only

=head2 secret_access_key

lib/AWS/S3/Bucket.pm  view on Meta::CPAN

        );

        my %acl = ();
        if ( $new_val =~ m{<} ) {
            $acl{acl_xml} = $new_val;
        }
        elsif ( exists $shorts{$new_val} ) {
            $acl{acl_short} = $new_val;
        }
        else {
            die "Attempt to set an invalid value for acl: '$new_val'";
        }

        my $type     = 'SetBucketAccessControl';
        my $req      = $self->s3->request( $type, %acl, bucket => $self->name, );
        my $response = $req->request();

        return if $response->response->code == 404;

        if ( my $msg = $response->friendly_error() ) {
            die $msg;

lib/AWS/S3/Bucket.pm  view on Meta::CPAN

Given an ArrayRef of the keys you want to delete, C<delete_multi> can only delete
up to 1000 keys at once.  Empty your buckets for deletion quickly like this:

  my $deleted = 0;
  my $bucket = $s->bucket( 'foobar' );
  my $iter = $bucket->files( page_size => 1000, page_number => 1 );
  while( my @files = $iter->next_page )
  {
    $bucket->delete_multi( map { $_->key } @files );
    $deleted += @files;
    # Reset to page 1:
    $iter->page_number( 1 );
    warn "Deleted $deleted files so far\n";
  }# end while()
  
  # NOW you can delete your bucket (if you want) because it's empty:
  $bucket->delete;

=head1 SEE ALSO

L<The Amazon S3 API Documentation|http://docs.amazonwebservices.com/AmazonS3/latest/API/>

lib/AWS/S3/File.pm  view on Meta::CPAN

    },
);

has 'contents' => (
    is       => 'rw',
    isa      => fileContents,
    required => 0,
    lazy     => 1,
    coerce   => 1,
    default  => \&_get_contents,
    trigger  => \&_set_contents
);

sub BUILD {
    my $s = shift;

    return unless $s->etag;
    ( my $etag = $s->etag ) =~ s{^"}{};
    $etag =~ s{"$}{};
    $s->{etag} = $etag;
}    # end BUILD()

sub update {
    my $s       = shift;
    my %args    = @_;
    my @args_ok = grep { /^content(?:s|type)$/ } keys %args;
    if ( @args_ok ) {
        $s->{$_} = $args{$_} for @args_ok;
        $s->_set_contents();
        return 1;
    }
    return;
}    # end update()

sub _get_contents {
    my $s = shift;

    my $type = 'GetFileContents';
    my $req  = $s->bucket->s3->request(
        $type,
        bucket => $s->bucket->name,
        key    => $s->key,
    );

    return \$req->request->response->decoded_content;
}    # end contents()

sub _set_contents {
    my ( $s, $ref ) = @_;

    my $type     = 'SetFileContents';
    my %args     = ();
    my $response = $s->bucket->s3->request(
        $type,
        bucket                 => $s->bucket->name,
        file                   => $s,
        contents               => $ref,
        content_type           => $s->contenttype,
        server_side_encryption => $s->is_encrypted ? 'AES256' : undef,
    )->request();

    ( my $etag = $response->response->header( 'etag' ) ) =~ s{^"}{};
    $etag =~ s{"$}{};
    $s->{etag} = $etag;

    if ( my $msg = $response->friendly_error() ) {
        die $msg;
    }    # end if()
}    # end _set_contents()

sub signed_url {
    my $s       = shift;
    my $expires = shift || 3600;

    # expiry for v4 signature is in seconds, not epoch time
    if ( $expires > time ) {
        $expires -= time;
    }

lib/AWS/S3/FileIterator.pm  view on Meta::CPAN

}    # end has_prev()

sub has_next { shift->{has_next} }

sub next {
  my $s = shift;

  if( exists( $s->{data}->[ $s->{idx} ] ) ) {
    return $s->{data}->[ $s->{idx}++ ];
  } else {
    # End of the current resultset, see if we can get another page of records:
    if( my $page = $s->next_page ) {
      $s->{data} = $page;
      $s->{idx} = 0;
      return $s->{data}->[ $s->{idx}++ ];
    } else {
      # No more pages, no more data:
      return;
    }
  }
}

sub reset {
  my $s = shift;
  $s->{idx} = 0;
}


sub page_number {
    my $s = shift;
    @_ ? $s->{page_number} = $_[0] - 1 : $s->{page_number};
}    # end page_number()

lib/AWS/S3/ResponseParser.pm  view on Meta::CPAN

    my $src = $self->response->content;

    # Do not try to parse non-xml:
    unless ( $src =~ m/^[[:space:]]*</s ) {
        ( my $code = $src ) =~ s/^[[:space:]]*\([0-9]*\).*$/$1/s;
        $self->error_code( $code );
        $self->error_message( $src );
        return 1;
    }    # end unless()

    ## Originally at this point the re-setting of xpc would happen
    ## Does not seem to be needed but it may be a problem area
    ## Feel free to delete - Evan Carroll 2012/06/14
    #### $s->_clear_xpc;

    if ( $self->xpc->findnodes( "//Error" ) ) {
        $self->error_code( $self->xpc->findvalue( "//Error/Code" ) );
        $self->error_message( $self->xpc->findvalue( "//Error/Message" ) );
        return 1;
    }

lib/AWS/S3/Roles/Request.pm  view on Meta::CPAN


    my $req = HTTP::Request->new( $method => $uri );
    $req->content( $content ) if $content;

    delete($headers->{Authorization}); # we will use a v4 signature
    map { $req->header( $_ => $headers->{$_} ) } keys %$headers;

    $s->_sign($req);
    my $res = $s->s3->ua->request( $req );

    # After creating a bucket and setting its location constraint, we get this
    # strange 'TemporaryRedirect' response.  Deal with it.
    if ( $res->header( 'location' ) && $res->content =~ m{>TemporaryRedirect<}s ) {
        $req->uri( $res->header( 'location' ) );
        $res = $s->s3->ua->request( $req );
    }
    return $s->parse_response( $res );
}

sub _sign {
  my ($s, $request) = @_;

lib/AWS/S3/Signer/V4.pm  view on Meta::CPAN


 -service            An AWS service

 -region             An AWS region


If a security token is provided, it overrides any values given for
-access_key or -secret_key.

If the environment variables EC2_ACCESS_KEY and/or EC2_SECRET_KEY are
set, their contents are used as defaults for -access_key and
-secret_key.

If -service and/or -region is not provided, they are automtically determined
according to endpoint.

=cut

sub new {
    my $self = shift;
    my %args = @_;

t/010_basic.t  view on Meta::CPAN

    my $dist = $cf->add_distribution(
      Origin  => AWS::CloudFront::S3Origin->new(
        DNSName => $bucket->name . '.s3.amazonaws.com',
      )
    );
    $bucket->enable_cloudfront_distribution( $dist );
  }# end unless()
}

#  my $acl = $bucket->acl;
#  ok $bucket->acl( 'private' ), 'set bucket.acl to private';
#  is $acl, $bucket->acl, 'get bucket.acl returns private';

#  ok $bucket->location_constraint( 'us-east-1' ), 'set bucket.location_constraint to us-east-1';
#  is $bucket->location_constraint, 'us-east-1', 'get bucket.location returns us-east-1';
#  is $s3->bucket($bucket->name)->location_constraint, 'us-east-1', 'get bucket.location returns us-east-1 second time';

#  is $bucket->policy, '', 'get bucket.policy returns empty string';

  my $test_str = "This is the original value right here!"x20;
  my $filename = 'foo/bar.txt';
  ADD_FILE: {
    my $file = $bucket->add_file(
      key       => $filename,

t/010_basic.t  view on Meta::CPAN

    $file->delete;
  };
  
  # Set contents:
  SET_CONTENTS: {
    my $new_contents = "This is the updated value"x10;
    ok my $file = $bucket->file($filename), 'bucket.file(filename) works';
    $file->contents( \$new_contents );
    
    # Now check it:
    is ${$bucket->file($filename)->contents}, $new_contents, "set file.contents works";
    
    # use alternative update method
    $new_contents = 'More new content';
    $file->update( contents => \$new_contents );
    is ${$bucket->file($filename)->contents}, $new_contents, "set file.update works";
  };
  
  DELETE_FILE: {
    eval { $bucket->delete };
    ok $@, 'bucket.delete fails when bucket is not empty.';
    like $@, qr/BucketNotEmpty/, 'error looks like BucketNotEmpty';
    ok $bucket->file($filename)->delete, 'file.delete';
    ok ! $bucket->file($filename), 'file no longer exists in bucket';
  };
  

t/aws/s3/file_iterator.t  view on Meta::CPAN

        'AWS::S3::FileIterator'
    );

    is( $iterator->marker,'','marker' );
    is( $iterator->pattern,qr/.*/,'pattern' );
    isa_ok( $iterator->bucket,'AWS::S3::Bucket' );
    is( $iterator->page_size,1,'page_size' );
    is( $iterator->has_prev,'','has_prev' );
    is( $iterator->has_next,undef,'has_next' );
    is( $iterator->page_number,1,'get page_number' );
    is( $iterator->page_number(1),0,'set page_number' );
    is( $iterator->prefix,'img','prefix' );

    {
        my $iterator2 = AWS::S3::FileIterator->new(
            page_number => 1,
            page_size   => 1,
            bucket      => $bucket,
            marker      => 'foo',
            pattern     => qr/\d/,
        );

t/aws/s3/http_request.t  view on Meta::CPAN

        s3      => $s3,
        method  => 'POST',
        path    => '/bar/baz',
        content => 'Hello World!'
    ),
    'AWS::S3::HTTPRequest'
);

isa_ok( my $http_request_with_content = $request_with_content->http_request, 'HTTP::Request' );
my $header = $http_request_with_content->headers;
is( $header->header( 'content-type' ), 'text/plain', '... and content-type got set' );
is( $header->header( 'content-length' ), 12, '... and content-length got set' );
is( $header->header( 'host' ), 's3.baz.com', '... and host got set' );

done_testing();



( run in 0.619 second using v1.01-cache-2.11-cpan-49f99fa48dc )