2013-04-08 3 views
6

Я пытаюсь определить, является ли удаленный url образ. Большинство url имеют .jpg, .png и т. Д., Но некоторые изображения, такие как изображения Google, не имеют расширения ... т. Е.Расширения изображений Carrierwave

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

ответ

3

, если все, что вы должны работать с является URL, как, что вы можете отправить запрос HEAD, сервер, чтобы получить тип содержимого для изображения. Из того, что вы можете получить удлиняющую

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? Это, очевидно, лучший подход в наше время с серверами изображений и всего ... –

+0

Я действительно был в процессе отправки одного @NielsKristian :-D – Hamed

+0

Я думаю, это будет приветствуется https://github.com/carrierwaveuploader/carrierwave/issues/1247 :-) –

Смежные вопросы