簡體   English   中英

從Rails的S3服務大文件

[英]Serving large files from S3 on Rails

我需要能夠從S3存儲桶中的Rails應用中下載一個大文件。 通常,我只給用戶3S存儲桶的URL,但是我需要保留該URL以使其被屏蔽,以便我可以隨意終止或刪除該URL。 我正在做以下事情:

def download
  purchase = Purchase.find(params[:id])

  data = open(purchase[:download_url])
  send_data data.read, filename: purchase[:file_name]
end

它適用於較小的文件,但由於Heroku的超時限制,在一個1GB的文件上,用戶會收到一個嚴重的520錯誤。

我了解這里發生的事情:整個文件在發送給用戶之前先在我的應用程序中打開,這就是較大文件超時的原因。 我想知道的是,是否有辦法避免提供用戶S3 URL? 是否可以僅屏蔽URL(而不重定向)而不是下載文件?

任何幫助表示贊賞!

編輯

基於SO的其他答案,我嘗試實現一個即將過期的URL:

def download
  purchase = Purchase.find(params[:id])
  path = purchase[:download_url].sub! 'entire URL until bucket path', ''
  s3URL = AWS::S3::S3Object.new(S3_BUCKET, path)

  redirect_to s3URL.url_for(:read).to_s
end

那只是重定向到AWS上的AccessDenied ,但是也許我在錯誤地構建URL。 再次感謝您的幫助!

我認為您的S3對象網址無法訪問,因為存儲桶/對象沒有public-read

要允許人們直接從您的S3存儲桶下載,您可以:

  • 使您的存儲桶公開訪問,或
  • 創建一個預簽名的URL,以授權匿名S3用戶下載該文件。

使S3存儲桶公開可用

如果您采用這種方法,則只需在更新的問題中提供S3對象的url。 您只需要在AWS中配置存儲桶。

  1. 轉到S3控制台。
  2. 打開存儲桶屬性(右鍵單擊存儲桶,然后單擊“ 屬性” )。
  3. 點擊權限部分,然后點擊添加存儲桶策略
  4. 復制並粘貼以下存儲桶策略:

     { "Version":"2012-10-17", "Statement":[ { "Sid":"AddPerm", "Effect":"Allow", "Principal": "*", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::examplebucket/*"] } ] } 

    資料來源: http : //docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-2

  5. 點擊保存 現在,只要具有URL,任何用戶都可以下載此存儲桶中的任何對象。 提示,要避免猜測URL,可以使用合理長度的隨機字符串重命名對象鍵。

創建一個預簽名的URL

在這種方法中,只有具有預簽名URL的用戶才能在特定時間段內(默認情況下是一周)下載您的S3對象。 之后,他/她需要換一個新的。 要創建預簽名的S3對象:

def download
  purchase = Purchase.find(params[:id])
  path = purchase[:download_url].sub! 'entire URL until bucket path', ''

  s3 = Aws::S3::Resource.new(region:'us-west-2')
  object = s3.bucket(S3_BUCKET).object(path)
  redirect_to object.presigned_url(:get)
end

您還可以在object.presigned_url方法中設置一些選項,例如:

object.presigned_url(:get, expires_in: 3600, response_content_disposition: 'attachment; filename=original_file_name.zip')

http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method中閱讀更多內容。

您需要選擇一種適合您的情況。 對於不敏感的公共S3對象,我更喜歡使S3存儲桶成為公共可訪問的。 但是,我認為,對於您的情況(購買一些東西然后下載),最好實現預簽名的URL。

您不需要發送數據,只需設置一個代理URL,重定向到S3 URL或進行編程所需的其他任何操作。

還請記住,S3 URL已到期。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM