1

My setup:

1) I have added a CNAME on my domain to point to S3.

assets.foo.com  -> s3.amazonaws.com

2) I have a bucket called assets.foo.com on S3

3) Model code:

has_attached_file :report,
  :storage        => :s3,
  :s3_credentials => { 
    :access_key_id      => "xxxx",
    :secret_access_key  => "yyyy"},
  :s3_permissions => 'private',
  :s3_protocol    => 'http',
  :s3_host_alias  => "assets.foo.com",
  :url            => ":s3_alias_url",
  :bucket         => "assets.foo.com",
  :path           => ":class/:attachment/:id_partition_:style.:extension"

I get the expected URL when I call the url method.

s.report.url
#http://assets.foo.com/study/report/..../abc.pdf

I get an error when try to generate an expiring URL

s.report.expiring_url
AWS::S3::CurrentBucketNotSpecified: No bucket name can be inferred from your current connection's address (`s3.amazonaws.com')
    from C:/Ruby187/lib/ruby/gems/1.8/gems/aws-s3-0.6.2/lib/aws/s3/base.rb:107:in `current_bucket'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/aws-s3-0.6.2/lib/aws/s3/base.rb:179:in `bucket_name'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/aws-s3-0.6.2/lib/aws/s3/object.rb:300:in `path!'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/aws-s3-0.6.2/lib/aws/s3/object.rb:291:in `url_for'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/paperclip-2.3.11/lib/paperclip/storage/s3.rb:98:in `expiring_url'
    from (irb):4

According to the user manual the bucket name is inferred if the :s3_host_alias key is specified and :url key is set to ":s3_alias_url". I have configured my model as per the instruction. I still encountered the error.

I was able to work around the problem by adding the bucket configuration, i.e.

has_attached_file :report,
  :storage        => :s3,
  :s3_credentials => { 
    :access_key_id      => "xxxx",
    :secret_access_key  => "yyyy"},
  :s3_permissions => 'private',
  :s3_protocol    => 'http', 
  :s3_host_alias  => "assets.foo.com",
  :url            => ":s3_alias_url",
  :bucket         => "assets.foo.com",
  :path           => ":class/:attachment/:id_partition_:style.:extension"

When I add the bucket configuration, the expiring_url method ignores the custom CNAME alias.

s.report.expiring_url
#http://s3.amazon.com/assets.foo.com/study/report/..../abc.pdf

Interestingly, the url function generates the expected url even when the bucket configuration is present.

s.report.url
#http://assets.foo.com/study/report/..../abc.pdf

Note: I tried various combination of CNAME alias with the same result:

assets.foo.com  -> s3.amazonaws.com
assets.foo.com  -> assets.foo.com.s3.amazonaws.com
Harish Shetty
  • 64,083
  • 21
  • 152
  • 198

2 Answers2

0

The issue is that you are in a situation where it can not infer your current bucket. The documentation says that you can set the bucket name to avoid this error. However as you have realized this wont generate the correct URL.

Try setting the :url in your config to the correct value as well with the correct setting for the bucket and it should work.

Devin M
  • 9,636
  • 2
  • 33
  • 46
0

This behaviour is seen ONLY when expire_url function is called when s3_host_alias is set. I monkey patched the gem to get around the issue.

Added the patch in config\initializers\paperclip.rb

module Paperclip::Storage::S3
  def bucket_name_with_s3_host_alias
    s3_host_alias || bucket_name_without_s3_host_alias
  end
  alias_method_chain :bucket_name, :s3_host_alias

  def expiring_url_with_s3_host_alias
    result = expiring_url_without_s3_host_alias
    s3_host_alias.present? ? 
      result.gsub(/(\/s3.amazonaws.com)|(\.s3.amazonaws.com)/, '') : result
  end
  alias_method_chain :expiring_url, :s3_host_alias
end
Harish Shetty
  • 64,083
  • 21
  • 152
  • 198