Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dir[File.join(Rails.root, 'lib', 'patches', '**', '*.rb')].sort.each { |patch| require(patch) }
module AWS
module S3
class Authentication
class CanonicalString
def initialize(request, options = {})
super()
@request = request
@headers = {}
@options = options
# "For non-authenticated or anonymous requests. A NotImplemented error result code will be returned if
# an authenticated (signed) request specifies a Host: header other than 's3.amazonaws.com'"
# (from http://docs.amazonwebservices.com/AmazonS3/2006-03-01/VirtualHosting.html)
request['Host'] = AWS::S3::Base.connection.subdomain || DEFAULT_HOST
build
end
private
def build
self << "#{request.method}\n"
ensure_date_is_valid
initialize_headers
set_expiry!
headers.sort_by {|k, _| k}.each do |key, value|
value = value.to_s.strip
self << (key =~ self.class.amazon_header_prefix ? "#{key}:#{value}" : value)
self << "\n"
end
self << (AWS::S3::Base.connection.subdomain ? "/#{AWS::S3::Base.connection.subdomain}#{path}" : path)
end
end
end
class Bucket
class << self
private
def path(name, options = {})
if name.is_a?(Hash)
options = name
name = nil
end
bucket_name(name) == connection.subdomain ? "/#{RequestOptions.process(options).to_query_string}" : "/#{bucket_name(name)}#{RequestOptions.process(options).to_query_string}"
end
end
end
class Connection
def subdomain
http.address[/^(.+)\.#{DEFAULT_HOST}$/, 1]
end
end
class S3Object
class << self
def path!(bucket, name, options = {}) #:nodoc:
# We're using the second argument for options
if bucket.is_a?(Hash)
options.replace(bucket)
bucket = nil
end
bucket_name(bucket) == connection.subdomain ? "/#{name}" : "/#{bucket_name(bucket)}/#{name}"
end
end
end
end
end
module Paperclip
module Storage
module S3
# Patch s3 storage initialisation to pass server name to aws/s3
def self.extended(base)
require 'aws/s3'
base.instance_eval do
@s3_credentials = parse_credentials(@options[:s3_credentials])
@bucket = @options[:bucket] || @s3_credentials[:bucket]
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
@s3_options = @options[:s3_options] || {}
@s3_permissions = @options[:s3_permissions] || :public_read
@s3_protocol = @options[:s3_protocol] || (@s3_permissions == :public_read ? 'http' : 'https')
@s3_headers = @options[:s3_headers] || {}
@s3_host_alias = @options[:s3_host_alias]
@url = ":s3_path_url" unless @url.to_s.match(/^:s3.*url$/)
AWS::S3::Base.establish_connection!( @s3_options.merge(
:access_key_id => @s3_credentials[:access_key_id],
:secret_access_key => @s3_credentials[:secret_access_key],
:server => "#{@bucket}.s3.amazonaws.com"
))
end
Paperclip.interpolates(:s3_alias_url) do |attachment, style|
"#{attachment.s3_protocol}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}"
end
Paperclip.interpolates(:s3_path_url) do |attachment, style|
"#{attachment.s3_protocol}://s3.amazonaws.com/#{attachment.bucket_name}/#{attachment.path(style).gsub(%r{^/}, "")}"
end
Paperclip.interpolates(:s3_domain_url) do |attachment, style|
"#{attachment.s3_protocol}://#{attachment.bucket_name}.s3.amazonaws.com/#{attachment.path(style).gsub(%r{^/}, "")}"
end
end
# Patch to use binmode on Windows
def to_file(style = default_style)
return @queued_for_write[style] if @queued_for_write[style]
begin
file = Tempfile.new(path(style))
file.binmode if file.respond_to?(:binmode)
file.write(AWS::S3::S3Object.value(path(style), bucket_name))
file.rewind
rescue AWS::S3::NoSuchKey
file.close if file.respond_to?(:close)
file = nil
end
file
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.