Paperclip 2.3.11为`expiring_url`抛出CurrentBucketNotSpecified错误

时间:2011-06-18 21:27:28

标签: ruby-on-rails paperclip

我的设置:

1)我在我的域名中添加了一个CNAME,指向S3。

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

2)我在S3上有一个名为assets.foo.com的存储桶

3)型号代码:

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"

当我调用url方法时,我得到了预期的网址。

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

尝试生成过期网址时出错

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

根据用户手册,如果指定了:s3_host_alias密钥并且:url密钥设置为":s3_alias_url",则会推断出存储桶名称。我按照说明配置了我的模型。我仍然遇到了错误。

我能够通过添加存储桶配置解决问题,即

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"

当我添加存储桶配置时,expiring_url方法会忽略自定义CNAME别名。

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

有趣的是,即使url配置存在,bucket函数也会生成预期的URL。

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

注意:我尝试了各种CNAME别名组合,结果相同:

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

2 个答案:

答案 0 :(得分:0)

问题是您处于无法推断当前存储桶的情况。 documentation表示您可以设置存储桶名称以避免此错误。但是,您已经意识到这不会生成正确的URL。

尝试将配置中的:url设置为正确的值,并使用正确的存储区设置,它应该可以正常工作。

答案 1 :(得分:0)

仅在设置expire_url时调用s3_host_alias函数时才会出现此行为。我猴子打了宝石来解决这个问题。

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