ndd-url_checker 0.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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +50 -0
- data/Gemfile.lock +152 -0
- data/Guardfile +38 -0
- data/LICENSE.txt +20 -0
- data/README.md +19 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/lib/ndd/url_checker.rb +6 -0
- data/lib/ndd/url_checker/abstract_url_checker.rb +30 -0
- data/lib/ndd/url_checker/blocking_url_checker.rb +134 -0
- data/lib/ndd/url_checker/forked_url_checker.rb +100 -0
- data/lib/ndd/url_checker/parallel_url_checker.rb +45 -0
- data/lib/ndd/url_checker/status.rb +104 -0
- data/lib/ndd/url_checker/threaded_url_checker.rb +36 -0
- data/spec/ndd/url_checker/abstract_url_checker_spec.rb +17 -0
- data/spec/ndd/url_checker/blocking_url_checker_spec.rb +12 -0
- data/spec/ndd/url_checker/forked_url_checker_spec.rb +12 -0
- data/spec/ndd/url_checker/parallel_url_checker_spec.rb +62 -0
- data/spec/ndd/url_checker/status_spec.rb +510 -0
- data/spec/ndd/url_checker/threaded_url_checker_spec.rb +13 -0
- data/spec/spec_helper.rb +83 -0
- data/spec/support/multiple_url_checker_spec.rb +66 -0
- data/spec/support/single_url_checker_spec.rb +207 -0
- metadata +312 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6ffa576d85139cd2300b55ba9c340fdda8608850
|
4
|
+
data.tar.gz: 58835f36306bd29f9375f0f6c65afc7045b7e411
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 84a715175f934072d1b5ec7244302d4c8385d7db3d724d1ac7596e9e98ca00f58bccf12f68c4d88ef4cac4fb865f7ea192f435bcc939783e0dd8a4fcec77281b
|
7
|
+
data.tar.gz: 62ee300dbe403c80a42e8387dc79657549c9bbf0f0be3d3788ed692d2847517bc70ecd460a130be42517d6086b909885b7e47dc29c48c79f72e5ab0eebb80e37
|
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation --tag focused
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ndd-url_checker
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.5
|
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.0.0
|
4
|
+
- 2.1.5
|
5
|
+
before_install:
|
6
|
+
- gem update --system
|
7
|
+
- gem --version
|
8
|
+
branches:
|
9
|
+
only:
|
10
|
+
- master
|
11
|
+
- development
|
12
|
+
addons:
|
13
|
+
code_climate:
|
14
|
+
repo_token:
|
15
|
+
secure: "jwblN6fY+HN0u+JfNWKNRNRExOlDH0NbuPprLxqac3kjE3ER11pJieXJKOoeFMcYJ8Z/33qPn4KhOPeYV/0HcZW5YD3G9pjry+c2ha9S7YjIQi8O0BR/iUmqzhvYOT6OoR+khJl9pf5/li3OfXUbAVNdcEDAKARuzl/XnGpqsdE="
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
HOST_OS = RbConfig::CONFIG['host_os']
|
4
|
+
|
5
|
+
|
6
|
+
# ------------------------------------------------------------------------------
|
7
|
+
# Dependencies required to use the gem.
|
8
|
+
gem 'cod', '~> 0.6'
|
9
|
+
gem 'logging', '~> 1.8'
|
10
|
+
|
11
|
+
|
12
|
+
# ------------------------------------------------------------------------------
|
13
|
+
# Dependencies to develop the gem.
|
14
|
+
# Everything needed to run rake, tests, features, etc.
|
15
|
+
group :development do
|
16
|
+
|
17
|
+
gem 'bundler', '~> 1.7', require: false
|
18
|
+
gem 'guard', '~> 2.8', require: false
|
19
|
+
gem 'guard-bundler', '~> 2.0', require: false
|
20
|
+
gem 'guard-rspec', '~> 4.3', require: false
|
21
|
+
gem 'guard-spork', '~> 2.0', require: false
|
22
|
+
gem 'jeweler', '~> 2.0', require: false
|
23
|
+
gem 'rdoc', '~> 4.1', require: false
|
24
|
+
gem 'rspec', '~> 3.1', require: false
|
25
|
+
gem 'rspec-collection_matchers', '~> 1.1', require: false
|
26
|
+
gem 'simplecov', '~> 0.9', require: false
|
27
|
+
gem 'spork', '~> 0.9', require: false
|
28
|
+
gem 'webmock', '~> 1.20', require: false
|
29
|
+
gem 'yard', '~> 0.8', require: false
|
30
|
+
|
31
|
+
case HOST_OS
|
32
|
+
when /darwin/i
|
33
|
+
gem 'growl'
|
34
|
+
gem 'rb-fsevent'
|
35
|
+
when /linux/i
|
36
|
+
gem 'libnotify'
|
37
|
+
gem 'rb-inotify'
|
38
|
+
when /mswin|windows/i
|
39
|
+
gem 'rb-fchange'
|
40
|
+
gem 'rb-notifu'
|
41
|
+
gem 'win32console'
|
42
|
+
else
|
43
|
+
raise "Platform '#{HOST_OS}' is not supported"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
group :test do
|
49
|
+
gem 'codeclimate-test-reporter', '~> 0.4', require: false
|
50
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.6)
|
5
|
+
builder (3.2.2)
|
6
|
+
celluloid (0.16.0)
|
7
|
+
timers (~> 4.0.0)
|
8
|
+
childprocess (0.5.5)
|
9
|
+
ffi (~> 1.0, >= 1.0.11)
|
10
|
+
cod (0.6.0)
|
11
|
+
codeclimate-test-reporter (0.4.3)
|
12
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
13
|
+
coderay (1.1.0)
|
14
|
+
crack (0.4.2)
|
15
|
+
safe_yaml (~> 1.0.0)
|
16
|
+
descendants_tracker (0.0.4)
|
17
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
18
|
+
diff-lcs (1.2.5)
|
19
|
+
docile (1.1.5)
|
20
|
+
faraday (0.9.0)
|
21
|
+
multipart-post (>= 1.2, < 3)
|
22
|
+
ffi (1.9.6)
|
23
|
+
formatador (0.2.5)
|
24
|
+
git (1.2.8)
|
25
|
+
github_api (0.12.2)
|
26
|
+
addressable (~> 2.3)
|
27
|
+
descendants_tracker (~> 0.0.4)
|
28
|
+
faraday (~> 0.8, < 0.10)
|
29
|
+
hashie (>= 3.3)
|
30
|
+
multi_json (>= 1.7.5, < 2.0)
|
31
|
+
nokogiri (~> 1.6.3)
|
32
|
+
oauth2
|
33
|
+
guard (2.8.2)
|
34
|
+
formatador (>= 0.2.4)
|
35
|
+
listen (~> 2.7)
|
36
|
+
lumberjack (~> 1.0)
|
37
|
+
pry (>= 0.9.12)
|
38
|
+
thor (>= 0.18.1)
|
39
|
+
guard-bundler (2.0.0)
|
40
|
+
bundler (~> 1.0)
|
41
|
+
guard (~> 2.2)
|
42
|
+
guard-compat (0.3.0)
|
43
|
+
guard-rspec (4.4.2)
|
44
|
+
guard (~> 2.1)
|
45
|
+
guard-compat (~> 0.1)
|
46
|
+
rspec (>= 2.99.0, < 4.0)
|
47
|
+
guard-spork (2.0.1)
|
48
|
+
childprocess (>= 0.2.3)
|
49
|
+
guard (~> 2.8.2)
|
50
|
+
spork (>= 0.8.4)
|
51
|
+
hashie (3.3.2)
|
52
|
+
highline (1.6.21)
|
53
|
+
hitimes (1.2.2)
|
54
|
+
jeweler (2.0.1)
|
55
|
+
builder
|
56
|
+
bundler (>= 1.0)
|
57
|
+
git (>= 1.2.5)
|
58
|
+
github_api
|
59
|
+
highline (>= 1.6.15)
|
60
|
+
nokogiri (>= 1.5.10)
|
61
|
+
rake
|
62
|
+
rdoc
|
63
|
+
json (1.8.1)
|
64
|
+
jwt (1.2.0)
|
65
|
+
libnotify (0.8.4)
|
66
|
+
ffi (>= 1.0.11)
|
67
|
+
listen (2.8.3)
|
68
|
+
celluloid (>= 0.15.2)
|
69
|
+
rb-fsevent (>= 0.9.3)
|
70
|
+
rb-inotify (>= 0.9)
|
71
|
+
little-plugger (1.1.3)
|
72
|
+
logging (1.8.2)
|
73
|
+
little-plugger (>= 1.1.3)
|
74
|
+
multi_json (>= 1.8.4)
|
75
|
+
lumberjack (1.0.9)
|
76
|
+
method_source (0.8.2)
|
77
|
+
mini_portile (0.6.1)
|
78
|
+
multi_json (1.10.1)
|
79
|
+
multi_xml (0.5.5)
|
80
|
+
multipart-post (2.0.0)
|
81
|
+
nokogiri (1.6.5)
|
82
|
+
mini_portile (~> 0.6.0)
|
83
|
+
oauth2 (1.0.0)
|
84
|
+
faraday (>= 0.8, < 0.10)
|
85
|
+
jwt (~> 1.0)
|
86
|
+
multi_json (~> 1.3)
|
87
|
+
multi_xml (~> 0.5)
|
88
|
+
rack (~> 1.2)
|
89
|
+
pry (0.10.1)
|
90
|
+
coderay (~> 1.1.0)
|
91
|
+
method_source (~> 0.8.1)
|
92
|
+
slop (~> 3.4)
|
93
|
+
rack (1.5.2)
|
94
|
+
rake (10.4.2)
|
95
|
+
rb-fsevent (0.9.4)
|
96
|
+
rb-inotify (0.9.5)
|
97
|
+
ffi (>= 0.5.0)
|
98
|
+
rdoc (4.2.0)
|
99
|
+
json (~> 1.4)
|
100
|
+
rspec (3.1.0)
|
101
|
+
rspec-core (~> 3.1.0)
|
102
|
+
rspec-expectations (~> 3.1.0)
|
103
|
+
rspec-mocks (~> 3.1.0)
|
104
|
+
rspec-collection_matchers (1.1.2)
|
105
|
+
rspec-expectations (>= 2.99.0.beta1)
|
106
|
+
rspec-core (3.1.7)
|
107
|
+
rspec-support (~> 3.1.0)
|
108
|
+
rspec-expectations (3.1.2)
|
109
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
110
|
+
rspec-support (~> 3.1.0)
|
111
|
+
rspec-mocks (3.1.3)
|
112
|
+
rspec-support (~> 3.1.0)
|
113
|
+
rspec-support (3.1.2)
|
114
|
+
safe_yaml (1.0.4)
|
115
|
+
simplecov (0.9.1)
|
116
|
+
docile (~> 1.1.0)
|
117
|
+
multi_json (~> 1.0)
|
118
|
+
simplecov-html (~> 0.8.0)
|
119
|
+
simplecov-html (0.8.0)
|
120
|
+
slop (3.6.0)
|
121
|
+
spork (0.9.2)
|
122
|
+
thor (0.19.1)
|
123
|
+
thread_safe (0.3.4)
|
124
|
+
timers (4.0.1)
|
125
|
+
hitimes
|
126
|
+
webmock (1.20.4)
|
127
|
+
addressable (>= 2.3.6)
|
128
|
+
crack (>= 0.3.2)
|
129
|
+
yard (0.8.7.6)
|
130
|
+
|
131
|
+
PLATFORMS
|
132
|
+
ruby
|
133
|
+
|
134
|
+
DEPENDENCIES
|
135
|
+
bundler (~> 1.7)
|
136
|
+
cod (~> 0.6)
|
137
|
+
codeclimate-test-reporter (~> 0.4)
|
138
|
+
guard (~> 2.8)
|
139
|
+
guard-bundler (~> 2.0)
|
140
|
+
guard-rspec (~> 4.3)
|
141
|
+
guard-spork (~> 2.0)
|
142
|
+
jeweler (~> 2.0)
|
143
|
+
libnotify
|
144
|
+
logging (~> 1.8)
|
145
|
+
rb-inotify
|
146
|
+
rdoc (~> 4.1)
|
147
|
+
rspec (~> 3.1)
|
148
|
+
rspec-collection_matchers (~> 1.1)
|
149
|
+
simplecov (~> 0.9)
|
150
|
+
spork (~> 0.9)
|
151
|
+
webmock (~> 1.20)
|
152
|
+
yard (~> 0.8)
|
data/Guardfile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
3
|
+
# bundler
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
5
|
+
|
6
|
+
guard 'bundler' do
|
7
|
+
watch('Gemfile')
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
12
|
+
# spork (must be before rspec and cucumber)
|
13
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
14
|
+
|
15
|
+
guard 'spork',
|
16
|
+
wait: 60 do
|
17
|
+
|
18
|
+
watch('Gemfile')
|
19
|
+
watch('Gemfile.lock')
|
20
|
+
|
21
|
+
# ----- spec directory
|
22
|
+
watch('spec/spec_helper.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
27
|
+
# rspec
|
28
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
29
|
+
|
30
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
31
|
+
|
32
|
+
# ----- lib directory
|
33
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| %W(spec/#{m[1]}_spec.rb) }
|
34
|
+
|
35
|
+
# ----- spec directory
|
36
|
+
watch(%r{^spec/.+_spec\.rb$})
|
37
|
+
watch(%r{^spec/support/(.+)\.rb$}) { %W(spec) }
|
38
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 David DIDIER
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# NDD URL Checker
|
2
|
+
|
3
|
+
[](http://travis-ci.org/ddidier/ndd-url_checker)
|
4
|
+
[](https://gemnasium.com/ddidier/ndd-url_checker)
|
5
|
+
[](https://codeclimate.com/github/ddidier/ndd-url_checker)
|
6
|
+
[](https://codeclimate.com/github/ddidier/ndd-url_checker)
|
7
|
+
|
8
|
+
URL validator.
|
9
|
+
|
10
|
+
## Prerequisites
|
11
|
+
|
12
|
+
This gem is tested with Ruby 2.1.x.
|
13
|
+
|
14
|
+
## TODO
|
15
|
+
|
16
|
+
## Copyright
|
17
|
+
|
18
|
+
Copyright (c) 2014 David DIDIER.
|
19
|
+
See `LICENSE.txt` for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts 'Run `bundle install` to install missing gems'
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification
|
17
|
+
# see http://guides.rubygems.org/specification-reference/ for more options
|
18
|
+
gem.name = 'ndd-url_checker'
|
19
|
+
gem.summary = 'Validate URLs'
|
20
|
+
gem.description = 'Validate URLs'
|
21
|
+
gem.homepage = 'http://github.com/ddidier/ndd-url_checker'
|
22
|
+
gem.license = 'MIT'
|
23
|
+
gem.email = 'c_inconnu2@yahoo.fr'
|
24
|
+
gem.authors = ['David DIDIER']
|
25
|
+
# dependencies defined in Gemfile
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Code coverage detail'
|
36
|
+
task :simplecov do
|
37
|
+
ENV['COVERAGE'] = 'true'
|
38
|
+
Rake::Task['spec'].execute
|
39
|
+
end
|
40
|
+
|
41
|
+
task :default => :spec
|
42
|
+
|
43
|
+
require 'rdoc/task'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "NDD URL Checker #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require 'ndd/url_checker/abstract_url_checker'
|
2
|
+
require 'ndd/url_checker/blocking_url_checker'
|
3
|
+
require 'ndd/url_checker/forked_url_checker'
|
4
|
+
require 'ndd/url_checker/parallel_url_checker'
|
5
|
+
require 'ndd/url_checker/status'
|
6
|
+
require 'ndd/url_checker/threaded_url_checker'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'ndd/url_checker/status'
|
2
|
+
|
3
|
+
module NDD
|
4
|
+
module UrlChecker
|
5
|
+
|
6
|
+
# Abstract class, not very ruby-ish :)
|
7
|
+
# @author David DIDIER
|
8
|
+
class AbstractUrlChecker
|
9
|
+
|
10
|
+
# Checks that the given URL are valid.
|
11
|
+
# If there is only a single URL parameter, returns a NDD::UrlChecker::Status.
|
12
|
+
# If there is only multiple URL parameters, returns a Hash of NDD::UrlChecker::Status indexed by their URI.
|
13
|
+
# @param urls [String|Array<String>] the URLs to check.
|
14
|
+
# @return [NDD::UrlChecker::Status|Hash<String => NDD::UrlChecker::Status>]
|
15
|
+
def check(*urls)
|
16
|
+
raise 'NDD::UrlChecker::UrlChecker#check must be implemented'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Validates that the given URL are valid.
|
20
|
+
# If there is only a single URL parameter, returns a boolean.
|
21
|
+
# If there is only multiple URL parameters, returns a Hash of boolean indexed by their URI.
|
22
|
+
# @param urls [String|Array<String>] the URLs to validate.
|
23
|
+
# @return [NDD::UrlChecker::Status|Hash<String => Boolean>]
|
24
|
+
def validate(*urls)
|
25
|
+
raise 'NDD::UrlChecker::UrlChecker#validate must be implemented'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'logging'
|
2
|
+
require 'ndd/url_checker/abstract_url_checker'
|
3
|
+
require 'ndd/url_checker/status'
|
4
|
+
require 'net/http'
|
5
|
+
require 'net/https'
|
6
|
+
|
7
|
+
module NDD
|
8
|
+
module UrlChecker
|
9
|
+
|
10
|
+
# An URL checker using the blocking Net::HTTP class.
|
11
|
+
# @author David DIDIER
|
12
|
+
class BlockingUrlChecker < AbstractUrlChecker
|
13
|
+
|
14
|
+
# Create a new instance.
|
15
|
+
# @param [Fixnum] maximum_redirects the maximum number of redirects before failing.
|
16
|
+
# @param [Fixnum] timeout the number of seconds to wait before failing.
|
17
|
+
def initialize(maximum_redirects=5, timeout=5)
|
18
|
+
@logger = Logging.logger[self]
|
19
|
+
@maximum_redirects = maximum_redirects
|
20
|
+
@timeout = timeout
|
21
|
+
end
|
22
|
+
|
23
|
+
# Checks that the given URL are valid.
|
24
|
+
# If there is only a single URL parameter, returns a NDD::UrlChecker::Status.
|
25
|
+
# If there is only multiple URL parameters, returns a Hash of NDD::UrlChecker::Status indexed by their URI.
|
26
|
+
# @param [String|Array<String>] urls
|
27
|
+
# @return [NDD::UrlChecker::Status|Hash<String => NDD::UrlChecker::Status>]
|
28
|
+
def check(*urls)
|
29
|
+
@logger.info "Checking #{urls.size} URL(s)"
|
30
|
+
return check_single(urls.first) if urls.size == 1
|
31
|
+
Hash[urls.map { |url| [url, check_single(url)] }]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Validates that the given URL are valid.
|
35
|
+
# If there is only a single URL parameter, returns a boolean.
|
36
|
+
# If there is only multiple URL parameters, returns a Hash of boolean indexed by their URI.
|
37
|
+
# @param [String|Array<String>] urls
|
38
|
+
# @return [NDD::UrlChecker::Status|Hash<String => Boolean>]
|
39
|
+
def validate(*urls)
|
40
|
+
@logger.info "Validating #{urls.size} URL(s)"
|
41
|
+
return validate_single(urls.first) if urls.size == 1
|
42
|
+
Hash[urls.map { |url| [url, validate_single(url)] }]
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Checks that the given URL is valid.
|
49
|
+
# @param [String] url
|
50
|
+
# @return [NDD::UrlChecker::Status]
|
51
|
+
def check_single(url)
|
52
|
+
begin
|
53
|
+
@logger.debug "Checking: #{url}"
|
54
|
+
status = check_uri(URI.parse(url), Status.new(url))
|
55
|
+
rescue => error
|
56
|
+
status = if unknown_host?(error)
|
57
|
+
Status.new(url).unknown_host
|
58
|
+
else
|
59
|
+
Status.new(url).failed(error)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
@logger.debug "Checked: #{url} -> #{status.code.upcase}"
|
63
|
+
status
|
64
|
+
end
|
65
|
+
|
66
|
+
# Validates that the given URL are valid.
|
67
|
+
# @param [String] url
|
68
|
+
# @return [Boolean]
|
69
|
+
def validate_single(url)
|
70
|
+
@logger.debug "Validating: #{url}"
|
71
|
+
check_single(url).valid?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Checks that the given URL is valid.
|
75
|
+
# @param [URI::HTTP] uri the URI to check
|
76
|
+
# @param [NDD::UrlChecker::Status] status the current status of the stack
|
77
|
+
# @return [NDD::UrlChecker::Status]
|
78
|
+
def check_uri(uri, status)
|
79
|
+
if status.uris.size() > @maximum_redirects
|
80
|
+
return status.too_many_redirects
|
81
|
+
end
|
82
|
+
|
83
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
84
|
+
http.read_timeout = @timeout
|
85
|
+
http.use_ssl = true if uri.scheme == 'https'
|
86
|
+
http.start do
|
87
|
+
path = (uri.path.empty?) ? '/' : uri.path
|
88
|
+
http.request_get(path) do |response|
|
89
|
+
case response
|
90
|
+
when Net::HTTPSuccess then
|
91
|
+
return on_success(uri, response, status)
|
92
|
+
when Net::HTTPRedirection then
|
93
|
+
return on_redirection(uri, response, status)
|
94
|
+
else
|
95
|
+
return on_error(uri, response, status)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def on_success(uri, response, status)
|
102
|
+
return status if status.redirected?
|
103
|
+
status.direct
|
104
|
+
end
|
105
|
+
|
106
|
+
def on_redirection(uri, response, status)
|
107
|
+
redirected_uri = redirected_uri(uri, response)
|
108
|
+
redirected_status = status.redirected(redirected_uri)
|
109
|
+
check_uri(redirected_uri, redirected_status)
|
110
|
+
end
|
111
|
+
|
112
|
+
def on_error(uri, response, status)
|
113
|
+
status.failed(response)
|
114
|
+
end
|
115
|
+
|
116
|
+
def redirected_uri(uri, response)
|
117
|
+
if response['location'].match(/https?:\/\//)
|
118
|
+
URI(response['location'])
|
119
|
+
else
|
120
|
+
# If the redirect is relative we need to build a new URI using the current URI as a base.
|
121
|
+
URI.join("#{uri.scheme}://#{uri.host}:#{uri.port}", response['location'])
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# FIXME: platform dependent?
|
126
|
+
UNKNOWN_HOST_MESSAGE = 'getaddrinfo: Name or service not known'
|
127
|
+
|
128
|
+
def unknown_host?(error)
|
129
|
+
error.is_a?(SocketError) && error.message == UNKNOWN_HOST_MESSAGE
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|