Amazon-S3
view release on metacpan or search on metacpan
lib/Amazon/S3.pm view on Meta::CPAN
my $region = $ENV{AWS_REGION} || $ENV{AWS_DEFAULT_REGION};
return $region
if $region;
my $url = $AWS_METADATA_BASE_URL . 'placement/availability-zone';
my $request = HTTP::Request->new( 'GET', $url );
my $ua = LWP::UserAgent->new;
$ua->timeout(0);
my $response = eval { return $ua->request($request); };
if ( $response && $response->is_success ) {
if ( $response->content =~ /\A([[:lower:]]+[-][[:lower:]]+[-]\d+)/xsm ) {
$region = $1;
}
}
return $region || $DEFAULT_REGION;
}
# Amazon::Credentials compatibility methods
########################################################################
sub get_aws_access_key_id {
########################################################################
my ($self) = @_;
return _decrypt( $self->aws_access_key_id );
}
########################################################################
sub get_aws_secret_access_key {
########################################################################
my ($self) = @_;
return _decrypt( $self->aws_secret_access_key );
}
########################################################################
sub get_token {
########################################################################
my ($self) = @_;
return _decrypt( $self->token );
}
########################################################################
sub turn_on_special_retry {
########################################################################
my ($self) = @_;
return
if !$self->retry;
# In the field we are seeing issue of Amazon returning with a 400
# code in the case of timeout. From AWS S3 logs: REST.PUT.PART
# Backups/2017-05-04/<account>.tar.gz "PUT
# /Backups<path>?partNumber=27&uploadId=<id> - HTTP/1.1" 400
# RequestTimeout 360 20971520 20478 - "-" "libwww-perl/6.15"
my $http_codes_hr = $self->ua->codes_to_determinate();
$http_codes_hr->{$HTTP_BAD_REQUEST} = $TRUE;
return;
}
########################################################################
sub turn_off_special_retry {
########################################################################
my ($self) = @_;
return
if !$self->retry;
# In the field we are seeing issue with Amazon returning a 400
# code in the case of timeout. From AWS S3 logs: REST.PUT.PART
# Backups/2017-05-04/<account>.tar.gz "PUT
# /Backups<path>?partNumber=27&uploadId=<id> - HTTP/1.1" 400
# RequestTimeout 360 20971520 20478 - "-" "libwww-perl/6.15"
my $http_codes_hr = $self->ua->codes_to_determinate();
delete $http_codes_hr->{$HTTP_BAD_REQUEST};
return;
}
########################################################################
sub region {
########################################################################
my ( $self, @args ) = @_;
if (@args) {
$self->_region( $args[0] );
}
$self->get_logger->debug(
sub { return 'region: ' . ( $self->_region // $EMPTY ) } );
if ( $self->_region ) {
my $host = $self->host;
$self->get_logger->debug( sub { return 'host: ' . $self->host } );
if ( $host =~ /\As3[.](.*)?amazonaws/xsm ) {
$self->host( sprintf 's3.%s.amazonaws.com', $self->_region );
}
}
return $self->_region;
}
########################################################################
sub buckets {
########################################################################
my ( $self, $verify_region ) = @_;
# The "default" region for Amazon is us-east-1
# This is the region to set it to for listing buckets
# You may need to reset the signer's endpoint to 'us-east-1'
# temporarily cache signer
my $region = $self->_region;
my $bucket_list;
$self->reset_signer_region($DEFAULT_REGION); # default region for buckets op
my $r = $self->_send_request(
{ method => 'GET',
path => $EMPTY,
headers => {},
region => $DEFAULT_REGION,
},
);
return $bucket_list
if !$r || $self->errstr;
my $owner_id = $r->{Owner}{ID};
my $owner_displayname = $r->{Owner}{DisplayName};
lib/Amazon/S3.pm view on Meta::CPAN
return $http_header;
}
# generate a canonical string for the given parameters. expires is optional and is
# only used by query string authentication.
########################################################################
sub _canonical_string {
########################################################################
my ( $self, $method, $path, $headers, $expires ) = @_;
# initial / meant to force host/bucket-name instead of DNS based name
$path =~ s/^\///xsm;
my %interesting_headers = ();
foreach my $p ( pairs %{$headers} ) {
my ( $key, $value ) = @{$p};
my $lk = lc $key;
if ( $lk eq 'content-md5'
or $lk eq 'content-type'
or $lk eq 'date'
or $lk =~ /^$AMAZON_HEADER_PREFIX/xsm ) {
$interesting_headers{$lk} = $self->_trim($value);
}
}
# these keys get empty strings if they don't exist
$interesting_headers{'content-type'} ||= $EMPTY;
$interesting_headers{'content-md5'} ||= $EMPTY;
# just in case someone used this. it's not necessary in this lib.
if ( $interesting_headers{'x-amz-date'} ) {
$interesting_headers{'date'} = $EMPTY;
}
# if you're using expires for query string auth, then it trumps date
# (and x-amz-date)
if ($expires) {
$interesting_headers{'date'} = $expires;
}
my $buf = "$method\n";
foreach my $key ( sort keys %interesting_headers ) {
if ( $key =~ /^$AMAZON_HEADER_PREFIX/xsm ) {
$buf .= "$key:$interesting_headers{$key}\n";
}
else {
$buf .= "$interesting_headers{$key}\n";
}
}
# don't include anything after the first ? in the resource...
# $path =~ /^([^?]*)/xsm;
# $buf .= "/$1";
$path =~ /\A([^?]*)/xsm;
$buf .= "/$1";
# ...unless there any parameters we're interested in...
if ( $path =~ /[&?](acl|torrent|location|uploads|delete)([=&]|$)/xsm ) {
# if ( $path =~ /[&?](acl|torrent|location|uploads|delete)([=&])?/xsm ) {
$buf .= "?$1";
}
elsif ( my %query_params = URI->new($path)->query_form ) {
# see if the remaining parsed query string provides us with any
# query string or upload id
if ( $query_params{partNumber} && $query_params{uploadId} ) {
# re-evaluate query string, the order of the params is important
# for request signing, so we can't depend on URI to do the right
# thing
$buf .= sprintf '?partNumber=%s&uploadId=%s',
$query_params{partNumber},
$query_params{uploadId};
}
elsif ( $query_params{uploadId} ) {
$buf .= sprintf '?uploadId=%s', $query_params{uploadId};
}
}
return $buf;
}
########################################################################
sub _trim {
########################################################################
my ( $self, $value ) = @_;
$value =~ s/^\s+//xsm;
$value =~ s/\s+$//xsm;
return $value;
}
# finds the hmac-sha1 hash of the canonical string and the aws secret access key and then
# base64 encodes the result (optionally urlencoding after that).
########################################################################
sub _encode {
########################################################################
my ( $self, $aws_secret_access_key, $str, $urlencode ) = @_;
my $hmac = Digest::HMAC_SHA1->new($aws_secret_access_key);
$hmac->add($str);
my $b64 = encode_base64( $hmac->digest, $EMPTY );
return $urlencode ? urlencode($b64) : return $b64;
}
########################################################################
sub bucketv2 {
########################################################################
my ( $self, @args ) = @_;
my $parameters = get_parameters(@args);
my ( $bucketname, $region, $verify_region )
= @{$parameters}{qw(bucket region verify_region)};
# only set to default region if a region wasn't passed or region
# verification not requested
if ( !$region && !$verify_region ) {
$region = $self->region;
}
return Amazon::S3::BucketV2->new(
{ bucket => $bucketname,
account => $self,
region => $region,
verify_region => $verify_region,
},
);
}
########################################################################
sub delete_public_access_block {
########################################################################
lib/Amazon/S3.pm view on Meta::CPAN
benefits from single-digit millisecond PUT and GET latencies.> -
L<https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-overview.html>
=over 10
=item list_directory_buckets
List the directory buckets. Note this only returns a list of you
directory buckets, not their contents. In order to list the contents
of a directory bucket you must first create a session that establishes
temporary credentials used to acces the Zonal endpoints. You then use
those credentials for signing requests using the ListObjectV2 API.
This process is currently B<not supported> by this class.
L<https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html>
<Lhttps://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html>
=item add_bucket
You can add a regin and availability zone to this call in order to
create a directory bucket.
$bucket->add_bucket({ bucket => $bucket_name, availability_zone => 'use1-az5' });
Note that your bucket name must conform to the naming conventions for
directory buckets. -
L<https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-overview.html#directory-buckets-name>
=back
=item Addition of version parameter for C<delete_key>
You can now delete a version of a key by including its verion ID.
$bucket->delete_key($key, $version_id);
=item Methods that accept a hash reference can now accept a
C<headers> object that may contain any additional headers you might want
to send with a request. Some of the methods that now allow you to pass
a header object include:
=over 10
=item add_bucket
=item add_key
=item get_key
Can now be called with a hashref which may include both a C<headers>
and C<uri_params> object.
=item delete_bucket
=item list_bucket
=item list_object_versions
=item upload_multipart_object
=back
=back
=head2 Comparison to Other Perl S3 Modules
Other implementations for accessing Amazon's S3 service include
C<Net::Amazon::S3> and the C<Paws> project. C<Amazon::S3> ostensibly
was intended to be a drop-in replacement for C<Net:Amazon::S3> that
"traded some performance in return for portability". That statement is
no longer accurate as C<Amazon::S3> may have changed the interface in
ways that might break your applications if you are relying on
compatibility with C<Net::Amazon::S3>.
However, C<Net::Amazon::S3> and C<Paws::S3> today, are dependent on
C<Moose> which may in fact level the playing field in terms of
performance penalties that may have been introduced by recent updates
to C<Amazon::S3>. Changes to C<Amazon::S3> include the use of more
Perl modules in lieu of raw Perl code to increase maintainability and
stability as well as some refactoring. C<Amazon::S3> also strives now
to adhere to best practices as much as possible.
C<Paws::S3> may be a much more robust implementation of a Perl S3
interface, however this module may still appeal to those that favor
simplicity of the interface and a lower number of dependencies. The
new L<Amazon::S3::BucketV2> module now provides access to nearly all
of the main S3 API metods.
Below is the original description of the module.
=over 10
Amazon S3 is storage for the Internet. It is designed to
make web-scale computing easier for developers. Amazon S3
provides a simple web services interface that can be used to
store and retrieve any amount of data, at any time, from
anywhere on the web. It gives any developer access to the
same highly scalable, reliable, fast, inexpensive data
storage infrastructure that Amazon uses to run its own
global network of web sites. The service aims to maximize
benefits of scale and to pass those benefits on to
developers.
To sign up for an Amazon Web Services account, required to
use this library and the S3 service, please visit the Amazon
Web Services web site at http://www.amazonaws.com/.
You will be billed accordingly by Amazon when you use this
module and must be responsible for these costs.
To learn more about Amazon's S3 service, please visit:
http://s3.amazonaws.com/.
The need for this module arose from some work that needed
to work with S3 and would be distributed, installed and used
on many various environments where compiled dependencies may
not be an option. L<Net::Amazon::S3> used L<XML::LibXML>
tying it to that specific and often difficult to install
option. In order to remove this potential barrier to entry,
lib/Amazon/S3.pm view on Meta::CPAN
version 5.10.0 C<perl> using some older CPAN modules to resolve
dependency issues.
To build this module on an earlier version of C<perl> you may need to
downgrade some modules. In particular I have found this recipe to
work for building and testing on 5.10.0.
In this order install:
HTML::HeadParser 2.14
LWP 6.13
Amazon::S3
...other versions I<may> work...YMMV. If you do decide to run on an
earlier version of C<perl>, you are encouraged to run the test
suite. See the L</TESTING> section for more details.
=item API Signing
Making calls to AWS APIs requires that the calls be signed. Amazon
has added a new signing method (Signature Version 4) to increase
security around their APIs. This module no longer utilizes Signature
Version V2.
B<New regions after January 30, 2014 will only support Signature Version 4.>
See L</Signature Version V4> below for important details.
=over 10
=item Signature Version 4
L<https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html>
I<IMPORTANT NOTE:>
Unlike Signature Version 2, Version 4 requires a regional
parameter. This implies that you need to supply the bucket's region
when signing requests for any API call that involves a specific
bucket. Starting with version 0.55 of this module,
C<Amazon::S3::Bucket> provides a new method (C<region()>) and accepts
in the constructor a C<region> parameter. If a region is not
supplied, the region for the bucket will be set to the region set in
the C<account> object (C<Amazon::S3>) that you passed to the bucket's
new constructor. Alternatively, you can request that the bucket's new
constructor determine the bucket's region for you by calling the
C<get_location_constraint()> method.
When signing API calls, the region for the specific bucket will be
used. For calls that are not regional (C<buckets()>, e.g.) the default
region ('us-east-1') will be used.
=item Signature Version 2
L<https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html>
=back
=item Multipart Upload Support
There are some recently added unit tests for multipart uploads that
seem to indicate this feature is working as expected. Please report
any deviation from expected results if you are using those methods.
For more information regarding multipart uploads visit the link below.
L<https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html>
=back
=head1 METHODS AND SUBROUTINES
Unless otherwise noted methods will return an C<undef> if an error
occurs. You can get more information about the error by calling
C<err()> and C<errstr()>.
=head2 new
Create a new S3 client object. Takes some arguments:
=over
=item credentials (optional)
Reference to a class (like C<Amazon::Credentials>) that can provide
credentials via the methods:
get_aws_access_key_id()
get_aws_secret_access_key()
get_token()
If you do not provide a credential class you must provide the keys
when you instantiate the object. See below.
I<You are strongly encourage to use a class that provides getters. If
you choose to provide your credentials to this class then they will be
stored in this object. If you dump the class you will likely expose
those credentials.>
=item aws_access_key_id
Use your Access Key ID as the value of the AWSAccessKeyId parameter
in requests you send to Amazon Web Services (when required). Your
Access Key ID identifies you as the party responsible for the
request.
=item aws_secret_access_key
Since your Access Key ID is not encrypted in requests to AWS, it
could be discovered and used by anyone. Services that are not free
require you to provide additional information, a request signature,
to verify that a request containing your unique Access Key ID could
only have come from you.
B<DO NOT INCLUDE THIS IN SCRIPTS OR APPLICATIONS YOU
DISTRIBUTE. YOU'LL BE SORRY.>
I<Consider using a credential class as described above to provide
credentials, otherwise this class will store your credentials for
signing the requests. If you dump this object to logs your credentials
could be discovered.>
=item token
An optional temporary token that will be inserted in the request along
( run in 0.594 second using v1.01-cache-2.11-cpan-b16cb0d3907 )