Skip to content

Instantly share code, notes, and snippets.

@joshuap
Created April 29, 2011 19:37
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save joshuap/948880 to your computer and use it in GitHub Desktop.
Save joshuap/948880 to your computer and use it in GitHub Desktop.
Net:HTTP enabled URI Validator for Rails 3
...
require 'uri_validator'
validates :url, :presence => true, :uri => { :format => /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)/ix }
require 'net/http'
# Thanks Ilya! http://www.igvita.com/2006/09/07/validating-url-in-ruby-on-rails/
# Original credits: http://blog.inquirylabs.com/2006/04/13/simple-uri-validation/
# HTTP Codes: http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html
class UriValidator < 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? or 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 # check header response
case Net::HTTP.get_response(URI.parse(value))
when Net::HTTPSuccess then true
else object.errors.add(attribute, configuration[:message]) and false
end
rescue # Recover on DNS failures..
object.errors.add(attribute, configuration[:message]) and false
end
else
object.errors.add(attribute, configuration[:message]) and false
end
end
end
@valk
Copy link

valk commented Jul 4, 2012

This doesn't seem to work. Tried with http://google.com, http://www.google.com, http://google.com/. Also tried to apply the other 2 guys comments. No luck?

@joshuap
Copy link
Author

joshuap commented Jul 13, 2012

@valk works for me:

irb(main):006:0> r = /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?([\/].*)?$)/ix
=> /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?([\/].*)?$)/ix
irb(main):007:0> r =~ 'http://google.com'                                   => 0
irb(main):008:0> r =~ 'http://www.google.com'
=> 0
irb(main):009:0> r =~ 'http://google.com/'
=> 0
irb(main):010:0> 

@Server4001
Copy link

No support for ftp://.... ?

@joshuap
Copy link
Author

joshuap commented Jul 17, 2013

@Server4001 you could easily add support to the regex for ftp://. Something like:

validates :url, :presence => true, :uri => { :format => URI::regexp(%w(http https ftp)) }

However, I think the Net::HTTP request would fail for FTP uris. You would need to modify the validator to check the validity of the FTP server.

@BeenaShetty
Copy link

Enter only url i.e http://www.flipkart.com then it doesnot validate it. It should also check if it is not a proper image url

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment