Amazon-CloudFront-Thin
view release on metacpan or search on metacpan
lib/Amazon/CloudFront/Thin.pm view on Meta::CPAN
} @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
=head2 Comparison to alternative modules
There are several useful modules for CloudFront on CPAN, like
L<Paws::CloudFront>, who provide a nice interface. You are welcome
to check them out to see if they suit your needs best. The reason
I wrote Amazon::CloudFront::Thin is because I needed to invalidate
CloudFront paths quickly and easily, and the alternatives felt either
like an "all or nothing" approach or lacked the documentation or
features I needed.
lib/Amazon/CloudFront/Thin.pm view on Meta::CPAN
Compatible: L<Furl>, L<LWP::UserAgent>, L<HTTP::Thin>, L<WWW::Curl::Simple>.
Incompatible: L<HTTP::Lite>, L<Hijk>, L<HTTP::Lite>, L<HTTP::Tiny>.
=back
=head1 ACCESSORS
=head2 ua
Gets/Sets the current user agent object doing the requests to Amazon
CloudFront. Defaults to LWP::UserAgent. You can replace it either
using this accessor or during object construction (see above for an
example that loads C<Furl> instead of C<LWP::UserAgent>).
=head1 METHODS
=head2 create_invalidation( $path )
=head2 create_invalidation( @paths )
=head2 create_invalidation( \@paths )
B<Receives>: list of strings (or arrayref of strings), each specifying
a different path to invalidate.
B<Returns>: an L<HTTP::Response> object for the request. Use the C<content()>
method on the returned object to read the contents:
my $res = $cloudfront->create_invalidation( '/path/to/some/object.png' );
if ($res->is_success) {
my $content = $res->content;
}
This method creates a new invalidation batch request on Amazon CloudFront.
Please note that B<paths are case sensitive> and that
B<the leading '/' is optional>, meaning C<"foo/BAR"> and C<"FOO/bar">
are completely different, but C<"foo/bar"> and C<"/foo/bar"> (note the '/')
point to the same object.
Each path is wrapped under CDATA on the resulting XML, so it should be
safe for non-ASCII and unsafe characters in your paths.
For more information, please refer to
L<< Amazon's API documentation for CreateInvalidation|https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateInvalidation.html >>.
For information on invalidations in general, including limitations,
please refer to L<< Amazon's CloudFront Developer Guide|https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html >>.
Finally, please refer to L<< Amazon's CloudFront error messages|https://docs.aws.amazon.com/cloudfront/latest/APIReference/CommonErrors.html >>
for more information on how to interpret errors returned as responses.
=head1 HANDLING UNICODE FILENAMES & PATHS
Amazon appears to reference filenames containing non ASCII characters
by URL Encoding the filenames. The following code takes a path such as
C<"events/Ø§ÙØ§Ø¨ØØ§Ø«"> which contains both a slash to indicate a directory
boundary and a non-ascii filename and creates an invalidation:
use Amazon::CloudFront::Thin;
use URL::Encode qw( url_encode_utf8 );
my $cloudfront = Amazon::CloudFront::Thin::->new( ... );
my $encoded_filename = url_encode_utf8($path);
# "/" will be encoded as %2F, but we want it as "/"
$encoded_filename =~ s!%2F!/!g;
$cloudfront->create_invalidation( '/' . $encoded_filename );
=head1 AUTHOR
Breno G. de Oliveira C<< garu at cpan.org >>
=head1 LICENSE AND COPYRIGHT
Copyright 2015-2019 Breno G. de Oliveira C<< <garu at cpan.org> >>. All rights reserved.
This module is free software; you can redistribute it and/or modify it
under the same terms as Perl itself. See L<perlartistic>.
=head1 DISCLAIMER OF WARRANTY
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR, OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
( run in 1.903 second using v1.01-cache-2.11-cpan-5837b0d9d2c )