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 +21 -0
- data/MIT-LICENSE +21 -0
- data/README +40 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/lib/http_url_validation_improved.rb +138 -0
- data/rails/init.rb +1 -0
- data/test/helper.rb +10 -0
- data/test/test_http_url_validation_improved.rb +7 -0
- metadata +101 -0
data/.gitignore
ADDED
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
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
|