我正在使用官方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错误。如果文件名中没有逗号或撇号,它可以正常工作。
有没有办法处理这个问题而不需要首先限制文件名?
答案 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。