我希望允许用户上传.jpg
个文件,但前提是它们实际上是.jpg
(例如,cat.gif
重命名为cat.jpg
不} 工作。
目前在我的Carrierwave ImageUploader.rb
中我有:
include CarrierWave::RMagick
include CarrierWave::MimeTypes
process :set_content_type
def extension_white_list
%w(jpg jpeg png)
end
在我的Rspec测试文件中,我测试了三种方式:
# Works
describe "with invalid mime type and invalid extension" do
before do
image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'executable.jpg')) # this is a .exe renamed to .jpg
end
it { image.should_not be_valid }
end
# Works
describe "with invalid mime type and invalid extension" do
before do
image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'test_gif.gif')) # this is a .gif
end
it { should_not be_valid }
end
# Doesn't work
describe "with invalid mime type and valid extension" do
before do
image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'test_gif.jpg')) # this is a .gif renamed to .jpg
end
it { image.should_not be_valid }
end
前两个测试通过,但第二个测试失败。我不知道为什么,因为我在白名单上没有gif
而且我正在检查mime类型。
有什么建议吗?
(将gif转换为jpgs是我的备份,但我宁愿拒绝它们。)
答案 0 :(得分:0)
我遇到了同样的问题,不得不覆盖我的上传者的默认set_content_type方法。这假设您的Gemfile中有 Rmagick gem,这样您就可以通过阅读图像获得正确的mime类型,而不是做出最佳猜测。
注意:如果Prawn正在使用仅支持JPG和PNG图像的图像,这将非常有用。
上传者类:
process :set_content_type
def set_content_type #Note we are overriding the default set_content_type_method for this uploader
real_content_type = Magick::Image::read(file.path).first.mime_type
if file.respond_to?(:content_type=)
file.content_type = real_content_type
else
file.instance_variable_set(:@content_type, real_content_type)
end
end
图片模型:
class Image < ActiveRecord::Base
mount_uploader :image, ImageUploader
validates_presence_of :image
validate :validate_content_type_correctly
before_validation :update_image_attributes
private
def update_image_attributes
if image.present? && image_changed?
self.content_type = image.file.content_type
end
end
def validate_content_type_correctly
if not ['image/png', 'image/jpg'].include?(content_type)
errors.add_to_base "Image format is not a valid JPEG or PNG."
return false
else
return true
end
end
end