Amazon-S3-Lite
view release on metacpan or search on metacpan
lib/Amazon/S3/Lite.pm view on Meta::CPAN
# 1. Caller-supplied credentials object (duck-typed)
if ( my $creds = $self->{credentials} ) {
croak "credential object is not blessed.\n"
if !blessed $creds;
foreach (qw(aws_access_key_id aws_secret_access_key token)) {
my $sub = $creds->can($_) // $creds->can("get_$_");
croak "credentials object must implement $_ or get_$_\n"
if !$sub;
}
$self->{credentials} = $creds;
return;
}
# 2. Explicit constructor args
if ( $self->{aws_access_key_id} && $self->{aws_secret_access_key} ) {
$self->{credentials} = Amazon::S3::Lite::Credentials->new(
aws_access_key_id => delete $self->{aws_access_key_id},
aws_secret_access_key => delete $self->{aws_secret_access_key},
token => delete $self->{token},
);
return;
}
# 3. Environment variables
if ( $ENV{AWS_ACCESS_KEY_ID} && $ENV{AWS_SECRET_ACCESS_KEY} ) {
$self->{credentials} = Amazon::S3::Lite::Credentials->new(
aws_access_key_id => $ENV{AWS_ACCESS_KEY_ID},
aws_secret_access_key => $ENV{AWS_SECRET_ACCESS_KEY},
token => $ENV{AWS_SESSION_TOKEN},
);
return;
}
# 4. Amazon::Credentials (covers IAM roles, ECS task roles,
# ~/.aws/credentials, etc.)
if ( eval { require Amazon::Credentials; 1 } ) {
$self->{credentials} = Amazon::Credentials->new;
return;
}
croak 'No AWS credentials found. Supply aws_access_key_id/'
. 'aws_secret_access_key, set AWS_ACCESS_KEY_ID/'
. 'AWS_SECRET_ACCESS_KEY environment variables, '
. 'or install Amazon::Credentials for IAM role support.';
}
########################################################################
# HTTP::Tiny instance - one per object, keep-alive enabled
########################################################################
sub _init_ua {
########################################################################
my ($self) = @_;
$self->{ua} = HTTP::Tiny->new(
timeout => $self->{timeout},
verify_SSL => $self->{secure},
);
return;
}
########################################################################
# Accessors
########################################################################
sub logger { return $_[0]->{logger} }
sub log_level { return $_[0]->{log_level}; }
sub ua { return $_[0]->{ua} }
sub region { return $_[0]->{region} }
sub host { return $_[0]->{host} }
sub credentials { return $_[0]->{credentials} }
########################################################################
# Build a fresh signer from current credentials.
# Called per-request so that rotating credentials (Lambda IAM roles)
# are always current.
########################################################################
sub _signer {
########################################################################
my ( $self, $region ) = @_;
my $creds = $self->credentials;
my $access_key
= $creds->can('get_aws_access_key_id')
? $creds->get_aws_access_key_id
: $creds->aws_access_key_id;
my $secret_key
= $creds->can('get_aws_secret_access_key')
? $creds->get_aws_secret_access_key
: $creds->aws_secret_access_key;
my $token_sub = $creds->can('get_token') // $creds->can('token');
my $token = $token_sub ? $token_sub->($creds) : undef;
return Amazon::Signature4::Lite->new(
access_key => $access_key,
secret_key => $secret_key,
session_token => $token,
region => $region // $self->region,
service => 's3',
);
}
########################################################################
# Build the endpoint URL for a bucket/key
########################################################################
sub _endpoint {
########################################################################
my ( $self, $bucket, $key ) = @_;
my $scheme = $self->{secure} ? 'https' : 'http';
my $host = $self->host;
# Path-style URL: https://s3.amazonaws.com/bucket/key
# (virtual-hosted style omitted for simplicity; path-style works
( run in 1.539 second using v1.01-cache-2.11-cpan-13bb782fe5a )