znamenica/dneslov

View on GitHub
app/validators/uri_validator.rb

Summary

Maintainability
A
2 hrs
Test Coverage
B
85%
class UriValidator < ActiveModel::EachValidator
   def validate_each(record, attribute, value)
      # if a local link just return true
      return true if value =~ %r{^/}

      response = Net::HTTP.get_response(URI(value && Addressable::URI.encode(value)))
      # validates :url, format: { with: /\.(?i-mx:jpg|png)\z/ } # TODO

      if [301, 303, 307].include?(response.code.to_i)
         new_url = response[:headers]&.[]("Location") || value
         if options[:allow_lost_slash] && value + "/" == new_url
            return true
         end

         if options[:allow_redirect]
            response = Net::HTTP.get_response(URI(Addressable::URI.encode(new_url)))
         end
      end

      unless [200, 302].include?(response.code.to_i)
         raise SocketError
      end
   rescue URI::InvalidURIError, Addressable::URI::InvalidURIError, ArgumentError
      record.errors.add(attribute, :invalid_uri, message: I18n.t('activerecord.errors.invalid_uri', uri: value))
   rescue Errno::ECONNREFUSED, OpenSSL::SSL::SSLError, Net::OpenTimeout
      record.errors.add(attribute, :inaccessible_uri, message: I18n.t('activerecord.errors.inaccessible_uri', uri: value))
   rescue SocketError
   end
end