Amazon-CloudFront-Thin

 view release on metacpan or  search on metacpan

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


sub _create_canonical_request {
    my ($url, $headers, $content) = @_;

    # http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
    my @sorted_header_names = sort $headers->header_field_names();
    return
        "POST\n"
      . ($url->path || '/') . "\n\n"
      . join( "\n", map {
            lc($_) . ':' . $headers->header($_)
          } @sorted_header_names
      ) . "\n\n"
      . _signed_headers($headers) . "\n"
      . Digest::SHA::sha256_hex($content)
    ;
}

sub _signed_headers {
    my ($headers) = @_;
    return join(';' => map lc, sort $headers->header_field_names());
}

sub _create_string_to_sign {
    my ($headers, $canonical_request) = @_;

    my ($formatted_date, $formatted_time) = _format_date(
        HTTP::Date::str2time($headers->header('X-Amz-Date'))
    );

    return
        "AWS4-HMAC-SHA256\n"
      . $formatted_date . 'T' . $formatted_time . "Z\n"
      . _cloudfront_scope($formatted_date) . "\n"
      . Digest::SHA::sha256_hex($canonical_request)
    ;
}

sub _create_signature {
    my ($aws_secret_access_key, $string_to_sign, $date) = @_;

    return Digest::SHA::hmac_sha256_hex(
        $string_to_sign, Digest::SHA::hmac_sha256(
            'aws4_request', Digest::SHA::hmac_sha256(
                'cloudfront', Digest::SHA::hmac_sha256(
                    'us-east-1', Digest::SHA::hmac_sha256($date, 'AWS4' . $aws_secret_access_key)
                )
            )
        )
    );
}

sub _create_xml_payload {
    my ($paths, $identifier) = @_;
    my $total_paths = scalar @$paths;
    my $path_content;
    foreach my $path (@$paths) {
        # leading '/' is required:
        # http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/InvalidationBatchDatatype.html
        $path = '/' . $path unless index($path, '/') == 0;
        # we wrap paths on CDATA so we don't have to escape them
        if (index($path, ']]>') >= 0) {
            $path =~ s/\]\]>/\]\]\]\]><![CDATA[>/gs; # split CDATA end token.
        }
        $path_content .= '<Path><![CDATA[' . $path . ']]></Path>'
    }
    return qq{<?xml version="1.0" encoding="UTF-8"?><InvalidationBatch xmlns="http://cloudfront.amazonaws.com/doc/2018-11-05/"><Paths><Quantity>$total_paths</Quantity><Items>$path_content</Items></Paths><CallerReference>$identifier</CallerReference><...
}

42;
__END__
=encoding utf8

=head1 NAME

Amazon::CloudFront::Thin - A thin, lightweight, low-level Amazon CloudFront client

=head1 SYNOPSIS

    use Amazon::CloudFront::Thin;

    my $cloudfront = Amazon::CloudFront::Thin->new({
        aws_access_key_id     => $key_id,
        aws_secret_access_key => $access_key,
        distribution_id       => 'my-cloudfront-distribution',
    });

    my $res = $cloudfront->create_invalidation(
       '/path/to/some/object.jpg',
       '/path/to/another/object.bin',
    );

=head1 DESCRIPTION

Amazon::CloudFront::Thin is a thin, lightweight, low level client for Amazon CloudFront.

It is designed for only ONE purpose: send a request and get a response.

It offers the following features:

=over 4

=item Low Level

Every request returns an L<HTTP::Response> object so you can easily inspect
what's happening inside, and can handle errors as you like.

=item Low Dependency

It has very few dependencies, so installation is easy and bloat-free
for your application. Aside from core modules like Digest::SHA, we
only rely on basic web modules like URI and HTTP::Message, which
you're probably already loaded from within your preferred web framework
or application.

=item Low Learning Cost

The interface is designed to follow Amazon CloudFront's official REST APIs.
So it is easy to learn and use by following the official documentation.

=back



( run in 1.109 second using v1.01-cache-2.11-cpan-140bd7fdf52 )