2013-04-08 106 views
6

我想確定一個遠程URL是否是一個圖像。大多數網址都有.jpg,.png等等,但是一些圖片,比如谷歌圖片,沒有擴展名。載波圖像擴展

https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSbK2NSUILnFozlX-oCWQ0r2PS2gHPPF7c8XaxGuJFGe83KGJkhFtlLXU_u

我使用FastImage確定URL是否是一個圖像嘗試。它的工作原理是當任何URL被輸入到它時...

我怎樣才能確保遠程URL使用FastImage和上傳的文件使用白名單?這是我的上傳者所擁有的。 Avatar_remote_url無法識別...我在上傳程序中如何測試遠程URL而不是常規文件。

def extension_white_list 
    if defined? avatar_remote_url && !FastImage.type(CGI::unescape(avatar_remote_url)).nil? 
     # ok to process 
    else # regular uploaded file should detect the following extensions 
     %w(jpg jpeg gif png) 
    end 
    end 
+0

也許可以使用正則表達式來允許任何http://encrpyted-tbn0.gstatic上傳 – ahmet 2013-04-08 17:16:03

回答

3

如果你所有的一起工作就是這樣,你可以發送HEAD請求到服務器,以獲得理想的圖像內容類型的URL。從可以得到擴展

require 'net/http' 
require 'mime/types' 

def get_extension(url) 
    uri = URI.parse(url) 
    http = Net::HTTP.new(uri.host, uri.port) 
    http.use_ssl = true if uri.scheme == 'https' 
    request = Net::HTTP::Head.new(uri.request_uri) 
    response = http.request(request) 
    content_type = response['Content-Type'] 
    MIME::Types[content_type].first.extensions.first 
end 
2

我和你提供的代碼和一些在CarrierWave Wiki for validating remote URLs提供的代碼的工作。

您可以在lib/remote_image_validator.rb中創建一個新的驗證器。

require 'fastimage' 

class RemoteImageValidator < ActiveModel::EachValidator 
    def validate_each(object, attribute, value) 
    raise(ArgumentError, "A regular expression must be supplied as the :format option of the options hash") unless options[:format].nil? || options[:format].is_a?(Regexp) 
    configuration = { :message => "is invalid or not responding", :format => URI::regexp(%w(http https)) } 
    configuration.update(options) 

    if value =~ configuration[:format] 
     begin 
     if FastImage.type(CGI::unescape(avatar_remote_url)) 
      true 
     else 
      object.errors.add(attribute, configuration[:message]) and false 
     end 
     rescue 
     object.errors.add(attribute, configuration[:message]) and false 
     end 
    else 
     object.errors.add(attribute, configuration[:message]) and false 
    end 
    end 
end 
在模型

然後

class User < ActiveRecord::Base 
    validates :avatar_remote_url, 
    :remote_image => { 
     :format => /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)/ix, 
     :unless => remote_avatar_url.blank? 
    } 
end 
1

我在那裏創建從原來是失敗的不同版本的類似問題,因爲ImageMagick的無法找出正確的編碼器使用,由於缺少擴展。這裏是一個猴子補丁我在那個固定我的問題的Rails應用:

module CarrierWave 
    module Uploader 
    module Download 
     class RemoteFile 
     def original_filename 
      value = File.basename(file.base_uri.path) 
      mime_type = Mime::Type.lookup(file.content_type) 
      unless File.extname(value).present? || mime_type.blank? 
      value = "#{value}.#{mime_type.symbol}" 
      end 
      value 
     end 
     end 
    end 
    end 
end 

我相信,因爲它確保了文件擴展名的存在時,內容類型設置正確,這將解決您有還有問題。

UPDATE:

carrierwave的主支路具有不同的解決方案,以使用該Content-Disposition頭找出文件名這個問題。以下是github上的相關請求。

+0

這太棒了!爲什麼你沒有向Carrierwave做出pull請求,這顯然是現代圖像服務器和所有東西的更好方法... – 2013-10-16 09:43:30

+0

我實際上正在提交一個@NielsKristian :-D – Hamed 2013-10-16 21:00:21

+0

我認爲它會歡迎https://github.com/carrierwaveuploader/carrierwave/issues/1247 :-) – 2013-10-17 08:51:52