1

我正在构建一个 Rails 4 应用程序,管理员将大文件上传到 Amazon S3。为了验证大文件的传输,我想根据亚马逊文档在请求标头中包含 Content-MD5 字段:

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html

我从 Paperclip + S3 开始,并且 MD5 验证有效:

has_attached_file :file,
                :storage => :s3,
                :bucket => AppSetting.s3_bucket,
                :s3_credentials => Proc.new{|a| a.instance.s3_credentials },
                :s3_permissions => :private,
                :s3_headers => Proc.new{|a| a.s3_headers },
                :path => "uploads/:id/:basename.:extension"

def s3_credentials
  {:access_key_id => AppSetting.aws_access_key_id, :secret_access_key => AppSetting.aws_secret_access_key}
end

# md5sum is a value entered by the user as a string (hex notation)
# ex: "7d592a3129ab6a867cf6e2eb60f9ef83"
#
def encoded_md5sum
  [[md5sum].pack("H*")].pack("m0")
end

def s3_headers
  {:content_md5 => encoded_md5sum}
end

使用 Paperclip,大文件首先上传到我的服务器,然后传输到 Amazon S3。这会阻塞 Rails 进程并消耗冗余带宽,因此我尝试使用 S3UploadDirect gem 将文件直接上传到 S3 存储桶:

https://github.com/waynehoover/s3_direct_upload

这个 gem 是 Railscasts 第 383 集代码的包装器,并使用 jquery-fileupload-rails 进行实际上传:

<%= s3_uploader_form callback_url: "#{AppSetting.host_base_url}/admin/uploads",
                 callback_method: "POST",
                 callback_param: "upload[file_url]",
                 key: "uploads/{timestamp}-{unique_id}-#{SecureRandom.hex}/${filename}",
                 key_starts_with: "uploads/",
                 acl: "private",
                 bucket: AppSetting.s3_bucket,
                 aws_access_key_id: AppSetting.aws_access_key_id,
                 aws_secret_access_key: AppSetting.aws_secret_access_key,
                 max_file_size: 5.gigabytes,
                 id: "s3-uploader",
                 class: "upload-form",
                 data: {:key => :val} do %>
  <%= file_field_tag :file, multiple: true %>
<% end %>

<script id="template-upload" type="text/x-tmpl">
  <div id="file-{%=o.unique_id%}" class="upload">
   {%=o.name%}
   <div class="progress"><div class="bar" style="width: 0%"></div></div>
 </div>
</script> 

我可以上传文件,但我不知道如何将 Content-MD5 信息传递到上传请求标头中。

4

0 回答 0