1

ユーザーが右クリックして、Carrierwave + S3 + Heroku + Content-Dispositionのように保存する前に、ファイル名の名前を変更することはできますか?ファイルをS3サーバーに保存する前に、ファイル名(193712391231.flvなど)をサニタイズし、元のファイル名をデータベースの列に保存することを考えています。

ユーザーがファイルをダウンロードすることを決定したとき(右クリックして名前を付けて保存)。193712391231.flvとして提供/送信できません。代わりに、元のファイル名でファイルを送信したいと思います。

これはどのように実装できますか?

Carrierwaveを使用します。私はこれに出くわしました:

uploaded = Video.first.attachment
uploader.retrieve_from_store!(File.basename(Video.first.attachment.url))
uploader.cache_stored_file!

send_file uploader.file.path

S3は最初にファイルをローカルファイルシステムにキャッシュし、次にそれをブラウザに送信するため、これはS3によって提供されません。これはWebプロセス全体を占めます(HerokuのDyno)。

誰かアイデアがあれば、提案してください。

4

2 に答える 2

3

Akshully、次のことができます。

# minimal example, 
# here using mongoid, but it doesn't really matter

class Media 

  field :filename, type: String   # i.e. "cute-puppy"
  field :extension, type: String  # i.e. "mp4"

  mount_uploader :media, MediaUploader

end

class MediaUploader < CarrierWave::Uploader::Base

  # Files on S3 are only accessible via signed URLS:
  @fog_public = false 

  # Signed URLS expire after ...:
  @fog_authenticated_url_expiration = 2.hours # in seconds from now, (default is 10.minutes)

  # MIME-Type and filename that the user will see:
  def fog_attributes
    {
      "Content-Disposition" => "attachment; filename*=UTF-8''#{model.filename}",
      "Content-Type" => MIME::Types.type_for(model.extension).first.content_type
    }
  end

  # ...
end

生成されるURLはmodel.media.url、次のヘッダーを返します。

Accept-Ranges:bytes
Content-Disposition:attachment; filename*=UTF-8''yourfilename.mp4
Content-Length:3926746
Content-Type:video/mpeg
Date:Thu, 28 Feb 2013 10:09:14 GMT
Last-Modified:Thu, 28 Feb 2013 09:53:50 GMT
Server:AmazonS3
...

次に、ブラウザは(ブラウザで開くのではなく)ダウンロードを強制し、バケットにデータを保存するために使用されるファイル名に関係なく、設定したファイル名を使用します。これの唯一の欠点は、Carrierwaveがファイルを作成するときにContent-Dispositionヘッダーが設定されるため、たとえば、異なるユーザーに対して同じファイルで異なるファイル名を使用できないことです。

その場合、RightAWSを使用して署名付きURLを生成できます。

class Media

  def to_url 
    s3_key = "" # the 'path' to the file in the S3 bucket

    request_header = {}
    response_header = {
      "response-content-disposition" => "attachment; filename*=UTF-8''#{filename_with_extension}",
      "response-content-type" => MIME::Types.type_for(extension).first.content_type
    }

    RightAws::S3Generator.new(
        Settings.aws.key,
        Settings.aws.secret,
        :port => 80,
        :protocol => 'http').
      bucket(Settings.aws.bucket).
      get(s3_key, 2.hours, request_header, response_header)
  end
end

編集:RightAWSを使用する必要はなく、uploader#url応答ヘッダーのオーバーライドをサポートします。構文は少し混乱します(CarrierWave、imhoのすべてと同様ですが、それでも素晴らしいです):

Media.last.media.url(query: {"response-content-disposition" => "attachment; filename*=UTF-8''huhuhuhuhu"}) 

# results in: 
# => https://yourbucket.s3.amazonaws.com/media/512f292be75ab5a46f000001/yourfile.mp4?response-content-disposition=attachment%3B%20filename%2A%3DUTF-8%27%27huhuhuhuhu&AWSAccessKeyId=key&Signature=signature%3D&Expires=1362055338
于 2013-02-28T10:24:15.517 に答える
0

S3から直接ユーザーにファイルを送信する場合、オプションはありません。ファイルをdyno経由でルーティングする場合は、ファイルを好きなように呼び出すことができますが、ダウンロードの全期間にわたってdynoを使用しています。

可能な場合はユーザーフレンドリーな方法でファイルを保存し、フォルダーを使用してファイルを整理します。

于 2011-10-12T15:39:13.577 に答える