Techioz Blog

シュライン - 検証前にシュラインがファイルを自動アップロードしないようにする方法 - Ruby Upload Gem

概要

この質問は、ファイル アップロード用の Ruby Gem Shrine を使用した経験がある人に向けてのものです。

ClamAV を使用して、アップロードされたファイルのウイルスをスキャンしようとしています。スキャンは正常に機能しますが、ファイルは検証前に、Shrine によってすでにクラウド ストレージに自動アップロードされています。

現時点でのコードは次のとおりです。

Attacher.validate do
    if file
      tmp_file = file.download
      # raise Services::Clamav::Client::FileContainVirus
      errors << "virus file" if Services::Clamav::Client.virus?(tmp_file.path)
    end
 end

あらゆる考え/回答が役に立ちます。ありがとう。

解決策

まず、Shrine 経由でファイルをアップロードする場合の注意点です。すべてのファイルは最初にキャッシュ/一時ストレージ (通常はローカル ファイルシステム上) にアップロードされ、検証に合格した後にのみ最終ストレージに保存されます。したがって、実行する検証はキャッシュされたファイルに対して実行され、ウイルス (またはその他の検証の失敗) が検出された場合、そのファイルは永続ストレージに昇格されません。これがどのように機能するかについて詳しくは、Shrine の入門ガイドをご覧ください。

ただし、ドキュメントでは次のようなカスタム検証が示されています。

require "streamio-ffmpeg"

class VideoUploader < Shrine
  plugin :add_metadata

  add_metadata :duration do |io|
    movie = Shrine.with_file(io) { |file| FFMPEG::Movie.new(file.path) }
    movie.duration
  end

  Attacher.validate do
    if file.duration > 5*60*60
      errors << "duration must not be longer than 5 hours"
    end
  end
end

add_metadata ブロックには、ファイル ストリームの読み取りに使用できる io インスタンスが渡されるか、Shrine.with_file(io) を使用してファイル オブジェクトに昇格できます。メタデータ :is_virus? を追加することで目的を達成できます。そして検証時にそれをチェックします。 (ClamAV は実際には clamdscan –stream - を介したストリーミングをサポートしているため、ファイルにプロモートする代わりに io インスタンスを直接使用できることに注意してください。)