28 lines
1 KiB
Ruby
28 lines
1 KiB
Ruby
|
|
require 'timeout'
|
||
|
|
require 'uri'
|
||
|
|
|
||
|
|
class UrlActiveValidator < ActiveModel::EachValidator
|
||
|
|
|
||
|
|
# Checks the status of the webpage at the given url
|
||
|
|
# To speed things up we ONLY request the head and not the entire page.
|
||
|
|
# Bypass check for fanfiction.net and ficbook.net because of ip block
|
||
|
|
def validate_each(record,attribute,value)
|
||
|
|
return true if value.match("fanfiction.net") || value.match("ficbook.net")
|
||
|
|
|
||
|
|
inactive_url_msg = "could not be reached. If the URL is correct and the site is currently down, please try again later."
|
||
|
|
inactive_url_timeout = 10 # seconds
|
||
|
|
begin
|
||
|
|
status = Timeout::timeout(options[:timeout] || inactive_url_timeout) {
|
||
|
|
url = Addressable::URI.parse(value)
|
||
|
|
response_code = Net::HTTP.start(url.host, url.port) {|http| http.head(url.path.blank? ? '/' : url.path).code}
|
||
|
|
active_status = %w[200 301 302 307 308]
|
||
|
|
active_status.include? response_code
|
||
|
|
}
|
||
|
|
rescue
|
||
|
|
status = false
|
||
|
|
end
|
||
|
|
record.errors.add(attribute, options[:message] || inactive_url_msg) unless status
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|