2013-04-08 13 views
6

Sto provando a determinare se un URL remoto è un'immagine. La maggior parte dell'URL ha .jpg, .png ecc ... ma alcune immagini, come le immagini di google, non hanno estensione ... i.Estensioni immagine Carrierwave

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

Ho provato con FastImage per determinare se un URL è un'immagine. Funziona quando viene alimentato da qualsiasi URL ...

Come posso garantire che gli URL remoti utilizzino FastImage e che i file caricati utilizzino la whitelist? Ecco cosa hanno nel mio uploader. Avatar_remote_url non è riconosciuto ... cosa faccio nell'uploader per testare solo URL remoti e file non regolari.

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

Potrebbe essere possibile utilizzare regex per consentire qualsiasi cosa da http: //encrpyted-tbn0.gstatic da caricare – ahmet

risposta

3

se tutto quello che dovete lavorare con è un URL del genere è possibile inviare una richiesta HEAD al server per ottenere il tipo di contenuto per l'immagine. Da che si può ottenere la proroga

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

sto lavorando con il codice che hai fornito e parte del codice fornito nel CarrierWave Wiki for validating remote URLs.

È possibile creare un nuovo validatore in 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 

Poi nel modello

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

stavo avendo un problema simile in cui la creazione di diverse versioni dall'originale stava fallendo perché ImageMagick non riusciva a capire l'encoder corretto da utilizzare a causa dell'estensione mancante . Ecco una scimmia-patch ho applicato in Rails che fissavano il mio problema:

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 

Credo che questa affronterà il problema si stanno avendo così in quanto garantisce l'esistenza di un estensione del file quando il tipo di contenuto è impostato in modo appropriato .

UPDATE:

ramo principale di carrierwave ha una diversa soluzione a questo problema che utilizza l'intestazione Content-Disposition di capire il nome del file. Ecco la richiesta di pull rilevante su github.

+0

Questo è fantastico! Perché non hai fatto una richiesta di pull a Carrierwave, Questo è ovviamente un approccio migliore ora nei tempi moderni con i server di immagini e tutto ... –

+0

Ero in procinto di inviare uno @NielsKristian MrGreen – Hamed

+0

Penso che sarà essere accolto https://github.com/carrierwaveuploader/carrierwave/issues/1247 :-) –

Problemi correlati