http_url_validation_improved 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2006 Cloves Carneiro Jr (and others, such as
2
+ Katipo Communications, Ltd. and Erik Gregg)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,40 @@
1
+ HTTP URL Validation Plugin Improved
2
+ by Erik Gregg, Walter McGinnis, Kieran Pilkington
3
+
4
+ This work is based on Erik's work, but mainly refined for the Kete application (http://kete.net.nz).
5
+
6
+ Inspired by HTTP URL Validation Plugin by C. Carneiro Jr.
7
+ ========================
8
+
9
+ HTTP URL Validation Improved is a Rails gem that allows you to validate a URL
10
+ entered in a form. It validates if the URL exists by hitting it with a HEAD
11
+ request.
12
+
13
+ The improved version includes retries for common patterns when the head request is refused before giving a failure notice.
14
+
15
+ It also looks up a SITE_URL constant to the user agent in the headers.
16
+
17
+ There's also the option to also check that the URL returns content of
18
+ a specified type. Here’s how you can use it your model:
19
+
20
+ Check for content type:
21
+ validates_http_url :url, :content_type => "text/html"
22
+
23
+ Do not check for content type, just make sure the site is accessible:
24
+ validates_http_url :website
25
+
26
+ Make sure there is a DNS entry for a domain
27
+ validates_http_domain :domain
28
+ # Domain must be in 'www.site.com' for or 'site.com' form. No http://, no path.
29
+
30
+ This example will make sure the value entered for the URL field points to a
31
+ publicly accessible HTML page, and the photo field points to an image:
32
+ validates_http_url :image_url, :content_type => "image"
33
+ # :content_type checks for a matching substring, so any image will validate
34
+
35
+ ========================
36
+
37
+ Bug reports and feedback are always welcome.
38
+
39
+ Please report them via http://github.com/kete/http_url_validation_improved
40
+
data/Rakefile ADDED
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "http_url_validation_improved"
8
+ gem.summary = %Q{a Rails gem that allows you to validate a URL
9
+ entered in a form}
10
+ gem.description = %Q{a Rails gem that allows you to validate a URL
11
+ entered in a form. It validates if the URL exists by hitting it with a HEAD
12
+ request.
13
+
14
+ The improved version includes retries for common patterns when the head request is refused before giving a failure notice.
15
+
16
+ It also looks up a SITE_URL constant to the user agent in the headers.
17
+
18
+ Also has the option to also check that the URL returns content of
19
+ a specified type.}
20
+ gem.email = "walter@katipo.co.nz"
21
+ gem.homepage = "http://github.com/kete/http_url_validation_improved"
22
+ gem.authors = ["Erik Gregg", "Walter McGinnis", "Kieran Pilkington"]
23
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
24
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
25
+ end
26
+ Jeweler::GemcutterTasks.new
27
+ rescue LoadError
28
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
29
+ end
30
+
31
+ require 'rake/testtask'
32
+ Rake::TestTask.new(:test) do |test|
33
+ test.libs << 'lib' << 'test'
34
+ test.pattern = 'test/**/test_*.rb'
35
+ test.verbose = true
36
+ end
37
+
38
+ begin
39
+ require 'rcov/rcovtask'
40
+ Rcov::RcovTask.new do |test|
41
+ test.libs << 'test'
42
+ test.pattern = 'test/**/test_*.rb'
43
+ test.verbose = true
44
+ end
45
+ rescue LoadError
46
+ task :rcov do
47
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
48
+ end
49
+ end
50
+
51
+ task :test => :check_dependencies
52
+
53
+ task :default => :test
54
+
55
+ require 'rake/rdoctask'
56
+ Rake::RDocTask.new do |rdoc|
57
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
58
+
59
+ rdoc.rdoc_dir = 'rdoc'
60
+ rdoc.title = "http_url_validation_improved #{version}"
61
+ rdoc.rdoc_files.include('README*')
62
+ rdoc.rdoc_files.include('lib/**/*.rb')
63
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.1
@@ -0,0 +1,138 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'socket'
4
+
5
+ module ActiveRecord
6
+ module Validations
7
+ module ClassMethods
8
+
9
+ # Validates a URL.
10
+ def validates_http_url(*attr_names)
11
+ configuration = {
12
+ :message_not_accessible => "is not accessible when we tried the link",
13
+ :message_wrong_content => "is not of the appropriate content type",
14
+ :message_moved_permanently => "has moved permanently",
15
+ :message_url_format => "is not formatted correctly. (Missing 'http://'?)"
16
+ }
17
+ configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
18
+ validates_each(attr_names, configuration) do |record, attr_name, value|
19
+
20
+ # Ignore blank URLs, these can be validated with validates_presence_of
21
+ if value.nil? or value.empty?
22
+ next
23
+ end
24
+
25
+ begin
26
+ moved_retry ||= false
27
+ not_allowed_retry ||= false
28
+ retry_without_headers ||= false
29
+ # Check Formatting
30
+ raise if not value =~ /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix
31
+ response = nil
32
+ url = URI.parse(value)
33
+ url.path = "/" if url.path.length < 1
34
+ http = Net::HTTP.new(url.host, (url.scheme == 'https') ? 443 : 80)
35
+ if url.scheme == 'https'
36
+ http.use_ssl = true
37
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
38
+ end
39
+ headers = Object.const_defined?('SITE_URL') ? { "User-Agent" => "#{SITE_URL} link checking mechanism via Ruby Net/HTTP" } : { "User-Agent" => "Ruby Net/HTTp used for link checking mechanism" }
40
+ response = if not_allowed_retry
41
+ if retry_without_headers
42
+ http.request_get(url.path) {|r|}
43
+ else
44
+ http.request_get(url.path, headers) {|r|}
45
+ end
46
+ else
47
+ http.request_head(url.path, headers)
48
+ end
49
+ # response = not_allowed_retry ? http.request_get(url.path) {|r|} : http.request_head(url.path)
50
+ # Comment out as you need to
51
+ allowed_codes = [
52
+ Net::HTTPMovedPermanently,
53
+ Net::HTTPOK,
54
+ Net::HTTPCreated,
55
+ Net::HTTPAccepted,
56
+ Net::HTTPNonAuthoritativeInformation,
57
+ Net::HTTPPartialContent,
58
+ Net::HTTPFound,
59
+ Net::HTTPTemporaryRedirect,
60
+ Net::HTTPSeeOther
61
+ ]
62
+ # If response is not allowed, raise an error
63
+ raise unless allowed_codes.include?(response.class)
64
+ # Check if the model requires a specific content type
65
+ unless configuration[:content_type].nil?
66
+ record.errors.add(attr_name, configuration[:message_wrong_content]) if response['content-type'].index(configuration[:content_type]).nil?
67
+ end
68
+ rescue
69
+ # Has the page moved?
70
+ if response.is_a?(Net::HTTPMovedPermanently)
71
+ unless moved_retry
72
+ moved_retry = true
73
+ value += "/" # In case webserver is just adding a /
74
+ retry
75
+ else
76
+ record.errors.add(attr_name, configuration[:message_moved_permanently])
77
+ end
78
+ elsif response.is_a?(Net::HTTPMethodNotAllowed) || response.is_a?(Net::HTTPInternalServerError)
79
+ unless not_allowed_retry
80
+ # Retry with a GET
81
+ not_allowed_retry = true
82
+ retry
83
+ else
84
+ if response.is_a?(Net::HTTPInternalServerError)
85
+ record.errors.add(attr_name, configuration[:message_not_accessible]+". The site link in question has had a problem. Please raise the issue with them and let them know that requests to the link break when coming from the automatic link checking mechanism on this site.")
86
+ else
87
+ record.errors.add(attr_name, configuration[:message_not_accessible]+" (GET method not allowed)")
88
+ end
89
+ end
90
+ elsif response.is_a?(Net::HTTPForbidden)
91
+ # handle requests where particular variants are forbidden
92
+ unless (not_allowed_retry && retry_without_headers)
93
+ unless not_allowed_retry
94
+ # try a full request GET first (rather than just head)
95
+ not_allowed_retry = true
96
+ retry
97
+ else
98
+ # try again but without headers (sometimes site refuse custom headers)
99
+ # for now, at least, this does a full GET request (rather than just head)
100
+ retry_without_headers = true
101
+ retry
102
+ end
103
+ else
104
+ record.errors.add(attr_name, configuration[:message_not_accessible] + ". The website says the URL is Forbidden.")
105
+ end
106
+ else
107
+ # if response is nil, then it's a format issue
108
+ if response.nil?
109
+ record.errors.add(attr_name, configuration[:message_url_format])
110
+ else
111
+ # Just Plain non-accessible
112
+ record.errors.add(attr_name, configuration[:message_not_accessible]+". This is what the website in question returned to us: "+response.class.to_s)
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def validates_http_domain(*attr_names)
120
+ validates_each(attr_names) do |record, attr_name, value|
121
+ # Set valid true on successful connect (all we need is one, one is all we need)
122
+ failed = true
123
+ possibilities = [value, "www."+value]
124
+ possibilities.each do |url|
125
+ begin
126
+ temp = Socket.gethostbyname(url)
127
+ rescue SocketError
128
+ next
129
+ end
130
+ failed = false
131
+ break
132
+ end
133
+ record.errors.add(attr_name, "cannot be resolved.") if failed
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'http_url_validation_improved'
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'http_url_validation_improved'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestHttpUrlValidationImproved < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_url_validation_improved
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 1
10
+ version: 1.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Erik Gregg
14
+ - Walter McGinnis
15
+ - Kieran Pilkington
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2010-06-04 00:00:00 +12:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: thoughtbot-shoulda
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ hash: 3
32
+ segments:
33
+ - 0
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id001
37
+ description: |-
38
+ a Rails gem that allows you to validate a URL
39
+ entered in a form. It validates if the URL exists by hitting it with a HEAD
40
+ request.
41
+
42
+ The improved version includes retries for common patterns when the head request is refused before giving a failure notice.
43
+
44
+ It also looks up a SITE_URL constant to the user agent in the headers.
45
+
46
+ Also has the option to also check that the URL returns content of
47
+ a specified type.
48
+ email: walter@katipo.co.nz
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files:
54
+ - README
55
+ files:
56
+ - .gitignore
57
+ - MIT-LICENSE
58
+ - README
59
+ - Rakefile
60
+ - VERSION
61
+ - lib/http_url_validation_improved.rb
62
+ - rails/init.rb
63
+ - test/helper.rb
64
+ - test/test_http_url_validation_improved.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/kete/http_url_validation_improved
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options:
71
+ - --charset=UTF-8
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: a Rails gem that allows you to validate a URL entered in a form
99
+ test_files:
100
+ - test/helper.rb
101
+ - test/test_http_url_validation_improved.rb