Carrierwave Image Extensions

I am trying to determine if the remote url is an image. Most urls have .jpg, .png, etc., but some images, such as Google images, do not have the extension ... ie

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

I tried using FastImage to determine if the URL is an image. It works when any url is served in it ...

How can I guarantee that remote URLs use FastImage and downloaded files use whitelist? This is what is in my bootloader. Avatar_remote_url is not recognized ... what am I doing in the bootloader to just check for remote urls, not regular files.

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 
+6
source share
3 answers

If all you need to work with is a URL that you can send a HEAD request to the server to get the type of content for the image. From this you can get the extension

 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 
+3
source

I work with the code you provided and some of the code provided in the CarrierWave Wiki to check for remote URLs .

You can create a new validator 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 

Then in your model

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

I had a similar problem when creating different versions from the original failed because ImageMagick was unable to determine the correct encoder to use due to the lack of extension. Here is the patch patch that I applied in Rails that fixed my problem:

 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 

I believe this will address the issue you are facing, as it ensures the existence of a file extension when the content type is set appropriately.

UPDATE:

The main carrier wave branch has another solution to this problem that uses the Content-Disposition header to determine the file name. Here is the corresponding github stretch request.

+1
source

All Articles