シュライン - 検証前にシュラインがファイルを自動アップロードしないようにする方法 - 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 インスタンスを直接使用できることに注意してください。)