Можно ли переименовать имя файла перед нажатием правой кнопки мыши + сохранить как с Carrierwave + S3 + Heroku + Content-Disposition? - PullRequest
1 голос
/ 08 октября 2011

Можно ли переименовать имя файла до того, как пользователь щелкнет правой кнопкой мыши + сохранить, как с Carrierwave + S3 + Heroku + Content-Disposition? Я думаю о дезинфекции имен файлов (например, 193712391231.flv) перед сохранением файла на сервере S3 и сохранении исходного имени файла в столбце в БД.

Когда пользователь решает загрузить файл (щелкните правой кнопкой мыши и сохраните как). Я не могу служить / отправить его как 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, потому что он сначала кэширует файл в локальной файловой системе, а затем отправляет его в браузер. Который занимает целый веб-процесс (Dyno in Heroku).

Если у кого-то есть идеи, предложите.

Ответы [ 2 ]

3 голосов
/ 28 февраля 2013

Акшуллы, вы можете:

# 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
...

После этого браузер принудительно загрузит (вместо открытия в браузере) и будет использовать заданное вами имя файла, независимо от имени файла, используемого для хранения содержимого в корзине. Единственный недостаток этого заключается в том, что заголовок Content-Disposition устанавливается, когда Carrierwave создает файл, поэтому вы не можете, например, использовать разные имена файлов в одном файле для разных пользователей.

В этом случае вы можете использовать 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
0 голосов
/ 12 октября 2011

Если вы отправляете файл пользователю напрямую из S3, у вас нет выбора.Если вы направите файл через dyno, вы можете назвать его как хотите, но вы используете dyno на протяжении всей загрузки.

Я бы сохранял файлы удобным для пользователя способом, где это возможно, ииспользуйте папки для их организации.

...