From e274bb1757aa3c27645c181bae6164131a7a35dd Mon Sep 17 00:00:00 2001 From: Jeff Shumate Date: Wed, 25 Jan 2012 22:27:46 -0700 Subject: add source url for post --- config/initializers/url_validator.rb | 85 ++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 config/initializers/url_validator.rb (limited to 'config/initializers') diff --git a/config/initializers/url_validator.rb b/config/initializers/url_validator.rb new file mode 100644 index 0000000..15635e0 --- /dev/null +++ b/config/initializers/url_validator.rb @@ -0,0 +1,85 @@ +require 'net/http' + +class UrlValidator < ActiveModel::EachValidator + + def validate_each(record, attribute, value) + url = value + + # Regex code by 'Arsenic' from http://snippets.dzone.com/posts/show/3654 + if url =~ /^ +( (https?):\/\/ )? +( [a-z\d]+([\-\.][a-z\d]+)*\.[a-z]{2,6} ) +( +(: +( \d{1,5} ) +)? +( \/.* )? +)? +$/ix + url = "http#{'s' if $7 == '81'}://#{url}" unless $1 + else + record.errors[attribute] << 'Not a valid URL' + end + + if options[:verify] + begin + url_response = RedirectFollower.new(url).resolve + url = url_response.url if options[:verify] == [:resolve_redirects] + rescue RedirectFollower::TooManyRedirects + record.errors[attribute] << 'URL is redirecting too many times' + rescue + record.errors[attribute] << 'could not be resolved' + end + end + + if options[:update] + value.replace url + end + end +end + +# Code below written by John Nunemaker +# See blog post at http://railstips.org/blog/archives/2009/03/04/following-redirects-with-nethttp/ +class RedirectFollower + class TooManyRedirects < StandardError; end + + attr_accessor :url, :body, :redirect_limit, :response + + def initialize(url, limit=5) + @url, @redirect_limit = url, limit + logger.level = Logger::INFO + end + + def logger + @logger ||= Logger.new(STDOUT) + end + + def resolve + raise TooManyRedirects if redirect_limit < 0 + + self.response = Net::HTTP.get_response(URI.parse(url)) + + logger.info "redirect limit: #{redirect_limit}" + logger.info "response code: #{response.code}" + logger.debug "response body: #{response.body}" + + if response.kind_of?(Net::HTTPRedirection) + self.url = redirect_url + self.redirect_limit -= 1 + + logger.info "redirect found, headed to #{url}" + resolve + end + + self.body = response.body + self + end + + def redirect_url + if response['location'].nil? + response.body.match(/]+)\">/i)[1] + else + response['location'] + end + end +end \ No newline at end of file -- cgit v1.2.3