Amazon-CloudFront-Thin

 view release on metacpan or  search on metacpan

lib/Amazon/CloudFront/Thin.pm  view on Meta::CPAN

package Amazon::CloudFront::Thin;
use strict;
use warnings;
use URI            ();
use URI::Escape    ();
use Carp           ();
use HTTP::Headers  ();
use HTTP::Date     ();
use HTTP::Request  ();
use Digest::SHA    ();

our $VERSION = '0.05';

sub new {
    my ($class, @extra) = @_;
    my $args;
    my $self = {};

    if (@extra == 1) {
        Carp::croak 'please provide a hash or hash reference to new()'
            unless ref $extra[0] eq 'HASH';
        $args = $extra[0];
    }
    else {
        Carp::croak 'please provide a hash or hash reference to new()'
            unless @extra % 2 == 0;
        $args = {@extra};
    }

    foreach my $key (qw(aws_access_key_id aws_secret_access_key distribution_id)) {
        if (exists $args->{$key}) {
            $self->{$key} = $args->{$key};
        }
        else {
            Carp::croak "argument '$key' missing on call to new()";
        }
    }
    bless $self, $class;
    my $ua = $args->{ua} || _default_ua();
    $self->ua($ua);

    return $self;
}

sub _default_ua {
    require LWP::UserAgent;
    my $ua = LWP::UserAgent->new(
        keep_alive => 10,
#        requests_redirectable => [qw(GET HEAD DELETE PUT)]
    );
    $ua->timeout(10);
    $ua->env_proxy;
    return $ua;
}

sub ua {
    my ($self, $ua) = @_;
    $self->{_ua} = $ua if ($ua);
    return $self->{_ua};
}

sub create_invalidation {
    my ($self, @paths) = @_;
    if (@paths == 1 && ref $paths[0] && ref $paths[0] eq 'ARRAY') {
        @paths = @{$paths[0]};
    }

    my $time = time;

    my $url = URI->new(
        'https://cloudfront.amazonaws.com/2018-11-05/distribution/'
        . $self->{distribution_id} . '/invalidation'
    );

    my $content = _create_xml_payload(\@paths, $time);

    # Amazon unfortunately does not comply with RFC 1123 for the
    # 'date' header, requiring instead that it gets written in
    # ISO-8601 format. Since HTTP::Headers does the right thing
    # for date(), we set the ISO-8601 date in "X-Amz-Date" instead.
    my ($formatted_date, $formatted_time) = _format_date($time);
    my $http_headers = HTTP::Headers->new(
        'Content-Length' => length $content,
        'Content-Type'   => 'text/xml',
        'Host'           => $url->host,
        'X-Amz-Date'     => $formatted_date . 'T' . $formatted_time . 'Z',
    );

    $http_headers->header(
        Authorization => 'AWS4-HMAC-SHA256 Credential='
            . $self->{aws_access_key_id} . '/' . _cloudfront_scope($formatted_date)
            . ', SignedHeaders=' . _signed_headers($http_headers)
            . ', Signature='
            . _calculate_signature(
                    $self->{aws_secret_access_key},
                    $url,
                    $http_headers,
                    $content



( run in 1.539 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )