Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

patch att_fu to allow cloudfront distributions

  • Loading branch information...
commit 3ff5420b90562961f47ec9482b73938ca041219e 1 parent a967a66
@bborn bborn authored
View
3  plugins/attachment_fu/README
@@ -47,6 +47,8 @@ has_attachment(options = {})
:partition # Whether to partiton files in directories like /0000/0001/image.jpg. Default is true. Only applicable to the :file_system backend.
:storage # Specifies the storage system to use..
# Defaults to :db_file. Options are :file_system, :db_file, and :s3.
+ :cloudfront # If using S3 for storage, this option allows for serving the files via Amazon CloudFront.
+ # Defaults to false.
:processor # Sets the image processor to use for resizing of the attached image.
# Options include ImageScience, Rmagick, and MiniMagick. Default is whatever is installed.
:uuid_primary_key # If your model's primary key is a 128-bit UUID in hexadecimal format, then set this to true.
@@ -67,6 +69,7 @@ has_attachment(options = {})
has_attachment :storage => :file_system, :path_prefix => 'public/files',
:thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
has_attachment :storage => :s3
+ has_attachment :store => :s3, :cloudfront => true
validates_as_attachment
This method prevents files outside of the valid range (:min_size to :max_size, or the :size range) from being saved. It does not however, halt the upload of such files. They will be uploaded into memory regardless of size before validation.
View
3  plugins/attachment_fu/amazon_s3.yml.tpl
@@ -2,13 +2,16 @@ development:
bucket_name: appname_development
access_key_id:
secret_access_key:
+ distribution_domain: XXXX.cloudfront.net
test:
bucket_name: appname_test
access_key_id:
secret_access_key:
+ distribution_domain: XXXX.cloudfront.net
production:
bucket_name: appname
access_key_id:
secret_access_key:
+ distribution_domain: XXXX.cloudfront.net
View
3  plugins/attachment_fu/lib/technoweenie/attachment_fu.rb
@@ -52,6 +52,8 @@ module ActMethods
# for the S3 backend. Setting this sets the :storage to :file_system.
# * <tt>:storage</tt> - Use :file_system to specify the attachment data is stored with the file system. Defaults to :db_system.
+ # * <tt>:cloundfront</tt> - Set to true if you are using S3 storage and want to serve the files through CloudFront. You will need to
+ # set a distribution domain in the amazon_s3.yml config file. Defaults to false
# * <tt>:bucket_key</tt> - Use this to specify a different bucket key other than :bucket_name in the amazon_s3.yml file. This allows you to use
# different buckets for different models. An example setting would be :image_bucket and the you would need to define the name of the corresponding
# bucket in the amazon_s3.yml file.
@@ -80,6 +82,7 @@ def has_attachment(options = {})
options[:thumbnails] ||= {}
options[:thumbnail_class] ||= self
options[:s3_access] ||= :public_read
+ options[:cloudfront] ||= false
options[:content_type] = [options[:content_type]].flatten.collect! { |t| t == :image ? Technoweenie::AttachmentFu.content_types : t }.flatten unless options[:content_type].nil?
unless options[:thumbnails].is_a?(Hash)
View
52 plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/s3_backend.rb
@@ -17,22 +17,28 @@ module Backends
# If you don't already have your access keys, all you need to sign up for the S3 service is an account at Amazon.
# You can sign up for S3 and get access keys by visiting http://aws.amazon.com/s3.
#
+ # If you wish to use Amazon CloudFront to serve the files, you can also specify a distibution domain for the bucket.
+ # To read more about CloudFront, visit http://aws.amazon.com/cloudfront
+ #
# Example configuration (RAILS_ROOT/config/amazon_s3.yml)
#
# development:
# bucket_name: appname_development
# access_key_id: <your key>
# secret_access_key: <your key>
+ # distribution_domain: XXXX.cloudfront.net
#
# test:
# bucket_name: appname_test
# access_key_id: <your key>
# secret_access_key: <your key>
+ # distribution_domain: XXXX.cloudfront.net
#
# production:
# bucket_name: appname
# access_key_id: <your key>
# secret_access_key: <your key>
+ # distribution_domain: XXXX.cloudfront.net
#
# You can change the location of the config path by passing a full path to the :s3_config_path option.
#
@@ -59,6 +65,8 @@ module Backends
# * <tt>:server</tt> - The server to make requests to. Defaults to <tt>s3.amazonaws.com</tt>.
# * <tt>:port</tt> - The port to the requests should be made on. Defaults to 80 or 443 if <tt>:use_ssl</tt> is set.
# * <tt>:use_ssl</tt> - If set to true, <tt>:port</tt> will be implicitly set to 443, unless specified otherwise. Defaults to false.
+ # * <tt>:distribution_domain</tt> - The CloudFront distribution domain for the bucket. This can either be the assigned
+ # distribution domain (ie. XXX.cloudfront.net) or a chosen domain using a CNAME. See CloudFront for more details.
#
# == Usage
#
@@ -150,6 +158,16 @@ module Backends
#
# Niether <tt>base_path</tt> or <tt>full_filename</tt> include the bucket name as part of the path.
# You can retrieve the bucket name using the <tt>bucket_name</tt> method.
+ #
+ # === Accessing CloudFront URLs
+ #
+ # You can get an object's CloudFront URL using the cloudfront_url accessor. Using the example from above:
+ # @postcard.cloudfront_url # => http://XXXX.cloudfront.net/photos/1/mexico.jpg
+ #
+ # The resulting url is in the form: http://:distribution_domain/:table_name/:id/:file
+ #
+ # If you set :cloudfront to true in your model, the public_filename will be the CloudFront
+ # URL, not the S3 URL.
module S3Backend
class RequiredLibraryNotFoundError < StandardError; end
class ConfigFileNotFoundError < StandardError; end
@@ -197,6 +215,10 @@ def self.hostname
def self.port_string
@port_string ||= (s3_config[:port].nil? || s3_config[:port] == (s3_config[:use_ssl] ? 443 : 80)) ? '' : ":#{s3_config[:port]}"
end
+
+ def self.distribution_domain
+ @distribution_domain = s3_config[:distribution_domain]
+ end
module ClassMethods
def s3_protocol
@@ -210,6 +232,10 @@ def s3_hostname
def s3_port_string
Technoweenie::AttachmentFu::Backends::S3Backend.port_string
end
+
+ def cloudfront_distribution_domain
+ Technoweenie::AttachmentFu::Backends::S3Backend.distribution_domain
+ end
end
# Overwrites the base filename writer in order to store the old filename
@@ -248,7 +274,27 @@ def full_filename(thumbnail = nil)
def s3_url(thumbnail = nil)
File.join(s3_protocol + s3_hostname + s3_port_string, bucket_name, full_filename(thumbnail))
end
- alias :public_filename :s3_url
+
+ # All public objects are accessible via a GET request to CloudFront. You can generate a
+ # url for an object using the cloudfront_url method.
+ #
+ # @photo.cloudfront_url
+ #
+ # The resulting url is in the form: <tt>http://:distribution_domain/:table_name/:id/:file</tt> using
+ # the <tt>:distribution_domain</tt> variable set in the configuration parameters in <tt>RAILS_ROOT/config/amazon_s3.yml</tt>.
+ #
+ # The optional thumbnail argument will output the thumbnail's filename (if any).
+ def cloudfront_url(thumbnail = nil)
+ "http://" + cloudfront_distribution_domain + "/" + full_filename(thumbnail)
+ end
+
+ def public_filename(*args)
+ if attachment_options[:cloudfront]
+ cloudfront_url(args)
+ else
+ s3_url(args)
+ end
+ end
# All private objects are accessible via an authenticated GET request to the S3 servers. You can generate an
# authenticated url for an object like this:
@@ -300,6 +346,10 @@ def s3_hostname
def s3_port_string
Technoweenie::AttachmentFu::Backends::S3Backend.port_string
end
+
+ def cloudfront_distribution_domain
+ Technoweenie::AttachmentFu::Backends::S3Backend.distribution_domain
+ end
protected
# Called in the after_destroy callback

0 comments on commit 3ff5420

Please sign in to comment.
Something went wrong with that request. Please try again.