NAME

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

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',
);

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:

Low Level

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

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.

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.

Comparison to alternative modules

There are several useful modules for CloudFront on CPAN, like 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.

Amazon CloudFront setup in a Nutshell

Amazon CloudFront is the content-delivery (CDN) service of Amazon Web Services (AWS). You use it by creating distributions (each with its own "distribution id" which we use below). To manage your distributions with this module, you need to provide credentials allowed to access/change your CloudFront distributions. You do this by going to AWS's Identity and Access Management (IAM) console and creating a new user. When you do that, the user's Access Key ID and Secret Access Key credentials will be shown to you. You'll also need to pass those to Amazon::CloudFront::Thin's constructor as shown in the SYNOPSIS and below, as aws_access_key_id and aws_secret_access_key, respectively. Finally, please note that the provided IAM credentials must have the rights to change your CloudFront. You can do that by clicking on the user (in the Amazon IAM console where you created it) and attaching a policy to it, such as the CloudFrontFullAccess standard policy. Otherwise you'll get errors when trying to invalidate your CloudFront distributions.

CONSTRUCTOR

new( \%params )

Receives: hashref with options.

Returns: Amazon::CloudFront::Thin object.

use Amazon::CloudFront::Thin;
use IO::Socket::SSL;
use Furl;


my $cloudfront = Amazon::CloudFront::Thin->new(
    aws_access_key_id     => 'my_key_id',
    aws_secret_access_key => 'my_key_secret',
    distribution_id       => 'my-cloudfront-distribution-id',

    # optional
    ua => Furl->new(
        ssl_opts => { SSL_verify_mode => SSL_VERIFY_PEER()
    },
);

Available arguments are:

  • aws_access_key_id (required) Your CloudFront credential key id.

  • aws_secret_access_key (required) Your CloudFront credential secret.

  • distribution_id (required) The id of the CloudFront distribution you want to manage.

  • ua (Optional) An LWP::UserAgent compatible object (otherwise, LWP::UserAgent will be used). The object must provide a request() method that receives an HTTP::Request and returns a response. The responses, whatever they are, will be forwarded to your call. Also, the object must be able to handle HTTPS. If you don't want to use LWP::UserAgent, there is a (highly incomplete) list of alternatives below:

    Compatible: Furl, LWP::UserAgent, HTTP::Thin, WWW::Curl::Simple.

    Incompatible: HTTP::Lite, Hijk, HTTP::Lite, HTTP::Tiny.

ACCESSORS

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 Furl instead of LWP::UserAgent).

METHODS

create_invalidation( $path )

create_invalidation( @paths )

create_invalidation( \@paths )

Receives: list of strings (or arrayref of strings), each specifying a different path to invalidate.

Returns: an HTTP::Response object for the request. Use the 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 paths are case sensitive and that the leading '/' is optional, meaning "foo/BAR" and "FOO/bar" are completely different, but "foo/bar" and "/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 Amazon's API documentation for CreateInvalidation. For information on invalidations in general, including limitations, please refer to Amazon's CloudFront Developer Guide. Finally, please refer to Amazon's CloudFront error messages for more information on how to interpret errors returned as responses.

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 "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 );

AUTHOR

Breno G. de Oliveira garu at cpan.org

LICENSE AND COPYRIGHT

Copyright 2015-2019 Breno G. de Oliveira <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 perlartistic.

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.