2013-01-24 19 views
1

我想允許用戶上傳.jpg文件,但只有當他們實際上是.jpg(例如,cat.gif更名爲cat.jpg工作carrierwave:拒絕.gif注意改名到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圖片JPG格式是我的備份,但我寧願只是拒絕他們。)

+0

我認爲extension_white_list只檢查擴展。我認爲你需要實際檢查content_type屬性:https://github.com/jnicklas/carrierwave/wiki/How-to%3A-Store-the-uploaded-file-size-and-content-type – micapam

+0

第二個「描述「是」它不應該be_valid}「和其他人是」它{image.should_not ...「 你確定第二個」它「是主題? – kukrt

+0

@micapam通過包括MimeTypes我在印象中,我正在檢查content_type:https://github.com/jnicklas/carrierwave#setting-the-content-type – pseudosudo

回答

0

我碰到了同樣的問題,不得不重寫我上傳的默認set_content_type方法。這假設你在你的Gemfile中有Rmagick寶石,這樣你就可以從閱讀圖像中獲得正確的mime類型,而不是做出最好的猜測。

注意:如果圖像被僅支持JPG和PNG圖像的Prawn使用,此功能特別有用。

上傳類別:

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