文件名中的特殊字符影响aws-sdk ruby​​ gem url_for方法

时间:2011-12-05 01:45:49

标签: ruby-on-rails ruby ruby-on-rails-3 amazon-s3

我正在使用官方AWS ruby​​ gem for S3,我在使用“url_for”方法时遇到问题,因为它们中包含特殊字符的文件(即逗号,撇号)。我正在使用最新的aws-sdk gem用于ruby,我的代码如下所示:

s3 = AWS::S3::new
bucket = s3.buckets[bucket]
object = bucket.objects[object_address]
object_url = object.url_for(:read, :expires => 60*60, :secure => true)

正确找到该对象,但是我从url_for获取的URL给出了一个HTTPError:404 Not Found错误。如果文件名中没有逗号或撇号,它可以正常工作。

有没有办法处理这个问题而不需要首先限制文件名?

2 个答案:

答案 0 :(得分:2)

您是否默认转义了URL字符串?例如:

object_url =  CGI.escape(object.url_for(:read, :expires => 60*60, :secure => true))

这会将字符串正确地转换为浏览器可读格式。我为所有安全的S3 URL执行此操作,因为签名中有时会出现/+字符,如果链接未正确转义,则会导致链接失败。这也将正确地逃避逗号和撇号。

答案 1 :(得分:2)

我最近遇到了同样的问题。我无法在提交之前修复文件名,因此我没有使用#url_for,而是编写了自己的编码器。这并不太难,虽然它在aws-sdk宝石中不起作用很烦人。

这是我的解决方案

def url_for_read(path, opts)
  expire_date = (Time.zone.now + opts[:expires]).to_i
  request_string = "GET\n\n\n#{expire_date}\n/#{config[:bucket]}/#{path}"
  hmac = OpenSSL::HMAC.digest(digest, config[:secret_access_key], request_string)
  signature = URI.escape(Base64.encode64(hmac).strip)
  s3_url_domain + "#{path}?AWSAccessKeyId=#{config[:access_key_id]}&Expires=#{expire_date}&Signature=#{CGI::escape(signature)}"
end

这假设您在config哈希中获得了aws信息,digest这里是'sha1',域名看起来像https://<my_bucket>.s3-<region>.amazonaws.com。对于完整的课程,您可以查看这个要点https://gist.github.com/bunnymatic/9274108