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 )