mlightner-universal_ruby_whois 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008 Matt Lightner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
data/README ADDED
File without changes
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'activesupport'
3
+
4
+ require 'net/http'
5
+ require 'uri'
6
+ require 'time'
7
+ require 'timeout'
8
+
9
+ require File.dirname(__FILE__) + '/universal_ruby_whois/inverted_regexp'
10
+ Regexp.class_eval do
11
+ include MattLightner::InvertedRegexp
12
+ end
13
+
14
+ require File.dirname(__FILE__) + '/universal_ruby_whois/domain'
15
+ require File.dirname(__FILE__) + '/universal_ruby_whois/server'
16
+ require File.dirname(__FILE__) + '/universal_ruby_whois/server_list'
17
+
@@ -0,0 +1,53 @@
1
+ require 'time'
2
+
3
+ module Whois
4
+
5
+ class Domain
6
+
7
+ attr_accessor :domain, :server_tld_key, :whois_output
8
+
9
+ def initialize(domain, server_tld_key = nil)
10
+ @domain, @server_tld_key = domain.to_s.strip.downcase, server_tld_key
11
+ end
12
+
13
+ def server
14
+ Whois::Server.list[@server_tld_key]
15
+ end
16
+
17
+ def regexes
18
+ server.regexes
19
+ end
20
+
21
+ def whois_output
22
+ return @whois_output if !@whois_output.blank?
23
+ @whois_output = server.raw_response(domain) || ""
24
+ end
25
+
26
+ def status
27
+ return @status unless @status.blank?
28
+ [ :registered, :free, :error ].each do |status|
29
+ #return status if Regexp.new(regexes[status].source, 5).match(res)
30
+ return(@status = status) if regexes[status].match_with_inversion(whois_output)
31
+ end
32
+ return @status = :unknown
33
+ end
34
+
35
+ def available?
36
+ status == :free
37
+ end
38
+
39
+ def registered?
40
+ status == :registered
41
+ end
42
+
43
+ def created_date
44
+ return @created_date unless @created_date.blank?
45
+ if regexes[:created_date] && (regexes[:created_date] =~ whois_output)
46
+ @created_date = (Time.local(*ParseDate.parsedate($2)) rescue nil)
47
+ end
48
+ @created_date
49
+ end
50
+ end
51
+
52
+ end
53
+
@@ -0,0 +1,150 @@
1
+ module Whois
2
+
3
+ class Server
4
+ @@whois_bin = `which whois`.gsub(/\s/, '')
5
+
6
+ attr_accessor :tld, :nic_server, :regexes, :port
7
+
8
+ def initialize(tld, nic_server = nil, options = {})
9
+ @tld = tld
10
+ @response_cache = Hash.new("")
11
+ @nic_server = nic_server
12
+ @port = options.delete(:port)
13
+ @regexes = options.reverse_merge(
14
+ :free => /(avail|free|no match|no entr|not taken|not registered|not found)/im,
15
+ :registered => /(registered|Domain ID|domain name\s*\:|is active|is not available|exists|\bregistrant\b|Created on)/im,
16
+ :created_date => /(Creation date|created on|created at|Commencement Date|Registration Date)\s*[\:\.]*\s*([\w\-\:\ ]+)[^\n\r]*[\n\r]/im,
17
+ :error => /(error)/im
18
+ )
19
+ end
20
+
21
+ # Class variable accessors
22
+ def self.list
23
+ @@list ||= Hash.new
24
+ end
25
+
26
+ def self.list=(value)
27
+ @@list = value
28
+ end
29
+
30
+ def self.domain_object_cache
31
+ @@domain_object_cache ||= Hash.new
32
+ end
33
+
34
+ def self.domain_object_cache=(value)
35
+ @@domain_object_cache = value
36
+ end
37
+
38
+ def self.defined_tlds
39
+ self.list.collect {|tld,server| tld.gsub(/^\./, '') }
40
+ end
41
+
42
+ # Find a TLD from a full domain name. There is special care to check for
43
+ # two part TLD's (such as .co.uk, .kids.us, etc) first and then to look for
44
+ # the last part alone.
45
+ def self.find_server_from_domain(domain)
46
+ # valid domain?
47
+ return nil unless domain =~ /^((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/
48
+
49
+ # start the searching.
50
+ tld = nil
51
+ parts = domain.split('.')
52
+
53
+ # if the passed domain is more than two parts (. separated strings)
54
+ # try to find the TLD from the last two parts (ie, .co.uk)
55
+ if parts.size > 2
56
+ tld_string = parts[-2,2].join('.')
57
+ tld = self.list[tld_string]
58
+ end
59
+
60
+ # if nothing was found, check for a match on the last part only.
61
+ if tld.blank?
62
+ tld_string = parts.last
63
+ tld = self.list[tld_string]
64
+ end
65
+
66
+ return nil if !tld.kind_of?(Whois::Server)
67
+ return tld
68
+ end
69
+
70
+ def self.find(domain)
71
+ domain = domain.to_s.strip.downcase
72
+ return domain_object_cache[domain] unless domain_object_cache[domain].blank?
73
+ return nil unless server = server_for_domain(domain)
74
+ domain_object_cache[domain] = Whois::Domain.new(domain, server.tld)
75
+ end
76
+
77
+ def self.server_for_domain(domain)
78
+ server = self.find_server_from_domain(domain)
79
+ # This will only work on single extension domains
80
+ if server.blank? # && domain.scan(/(\.)/).length == 1
81
+ domain =~ /\.([\w\-]+)$/
82
+ tld = $1
83
+ self.define_from_iana(tld)
84
+ return false unless server = self.find_server_from_domain(domain)
85
+ end
86
+ server
87
+ end
88
+
89
+ def raw_response(domain)
90
+ return @response_cache[domain] if !@response_cache[domain].blank?
91
+ @response_cache[domain] = ""
92
+ if nic_server =~ /^http/
93
+ url = nic_server.gsub(/\%DOMAIN\%/, domain)
94
+ @response_cache[domain] = Net::HTTP.get_response(URI.parse(url)).body
95
+ else
96
+ command = "#{@@whois_bin} #{('-h ' + @nic_server) unless @nic_server.blank?} #{self.class.shell_escape(domain)} 2>&1"
97
+ @response_cache[domain] = Whois::Server.run_command_with_timeout(command, 10, true)
98
+ end
99
+ @response_cache[domain]
100
+ end
101
+
102
+ def self.define_from_iana(tld)
103
+ iana_out = run_command_with_timeout("#{@@whois_bin} -h whois.iana.org #{shell_escape(tld.to_s)} 2>&1", 10, false)
104
+ return false if iana_out.blank?
105
+ return false unless iana_out =~ /Whois\s+Server\s+\(port ([\d]+)\)\: ([\w\-\.\_]+)/im
106
+ port = $1
107
+ server = $2
108
+ define_single(tld.to_s, server, :port => port)
109
+ end
110
+
111
+ def self.define_single(*args, &block)
112
+ new_server = allocate
113
+ new_server.send(:initialize, *args, &block)
114
+ list[args.first.to_s] = new_server
115
+ new_server
116
+ end
117
+
118
+ def self.define(*args, &block)
119
+ tld_list = args.shift
120
+ tld_list = tld_list.kind_of?(Array) ? tld_list : [tld_list]
121
+ tld_list.each do |tld|
122
+ define_single(*args.clone.unshift(tld.to_s), &block)
123
+ end
124
+ tld_list
125
+ end
126
+
127
+ def self.run_command_with_timeout(command, timeout = 10, do_raise = false)
128
+ @output = ""
129
+ begin
130
+ status = Timeout::timeout(10) do
131
+ IO.popen(command, "r") do |io|
132
+ @output << "#{io.read.to_s}"
133
+ end
134
+ end
135
+ rescue Exception => e
136
+ if do_raise
137
+ raise "Running command \"#{command}\" timed out."
138
+ end
139
+ end
140
+ @output
141
+ end
142
+
143
+ def self.shell_escape(word)
144
+ word.to_s.gsub(/[^\w\-\_\.]+/, '')
145
+ end
146
+
147
+ end # class Server
148
+
149
+ end
150
+
@@ -0,0 +1,240 @@
1
+ # Define whois servers and their corresponding output format in this file.
2
+ # If no regular expressions are given to match states, some reasonable
3
+ # defaults will be used, but more specific is always better :)
4
+
5
+ # More generic definitions should appear first, as the more specific definitions
6
+ # will overwrite them in the extension dictionary if they appear later in the file.
7
+
8
+ Whois::Server.define('ae', 'whois.uaenic.ae')
9
+ Whois::Server.define('ai', 'whois.ainic.ai')
10
+ Whois::Server.define('as', 'whois.nic.as')
11
+ Whois::Server.define('at', 'whois.nic.at')
12
+ Whois::Server.define('bg', 'whois.digsys.bg')
13
+ Whois::Server.define('bi', 'whois.nic.bi')
14
+ Whois::Server.define('bj', 'www.nic.bj')
15
+ Whois::Server.define('bz', 'whois.belizenic.bz')
16
+ Whois::Server.define('cc', 'whois.nic.cc')
17
+ Whois::Server.define('cd', 'whois.nic.cd')
18
+ Whois::Server.define('ck', 'whois.nic.ckcn')
19
+ Whois::Server.define('de', 'whois.denic.de')
20
+ Whois::Server.define('fo', 'whois.ripe.net')
21
+ Whois::Server.define('gg', 'whois.isles.net')
22
+ Whois::Server.define('gl', 'whois.ripe.net')
23
+ Whois::Server.define('gm', 'whois.ripe.net')
24
+ Whois::Server.define('gr', 'whois.grnet.gr')
25
+ Whois::Server.define('gs', 'whois.gs')
26
+ Whois::Server.define('hm', 'webhst1.capital.hm')
27
+ Whois::Server.define('hu', 'whois.nic.hu')
28
+ Whois::Server.define('id', 'whois.idnic.net.id')
29
+ Whois::Server.define('in', 'whois.inregistry.net')
30
+ Whois::Server.define('ir', 'whois.nic.ir')
31
+ Whois::Server.define('kz', 'whois.nic.kz')
32
+ Whois::Server.define('la', 'whois2.afilias-grs.net')
33
+ Whois::Server.define('ly', 'whois.lydomains.com')
34
+ Whois::Server.define('mc', 'whois.ripe.net')
35
+ Whois::Server.define('ms', 'whois.ms')
36
+ Whois::Server.define('mx', 'whois.nic.mx')
37
+ Whois::Server.define('my', 'whois.mynic.net.my')
38
+ Whois::Server.define('nu', 'whois.nic.nu')
39
+ Whois::Server.define('pl', 'whois.dns.pl')
40
+ Whois::Server.define('pm', 'whois.nic.pm')
41
+ Whois::Server.define('pro', 'whois.registrypro.pro')
42
+ Whois::Server.define('pt', 'whois.nic.pt')
43
+ Whois::Server.define('sa', 'saudinic.net.sa')
44
+ Whois::Server.define('sb', 'whois.nic.net.sb')
45
+ Whois::Server.define('se', 'whois.nic-se.se')
46
+ Whois::Server.define('si', 'whois.arnes.si')
47
+ Whois::Server.define('sk', 'whois.sk-nic.sk')
48
+ Whois::Server.define('sm', 'whois.ripe.net')
49
+ Whois::Server.define('st', 'whois.nic.st')
50
+ Whois::Server.define('su', 'whois.ripn.net')
51
+ Whois::Server.define('tc', 'whois.tc')
52
+ Whois::Server.define('th', 'whois.thnic.net')
53
+ Whois::Server.define('to', 'whois.tonic.to')
54
+ Whois::Server.define('tv', 'tvwhois.verisign-grs.com')
55
+ Whois::Server.define('uy', 'www.nic.org.uy')
56
+ Whois::Server.define('uz', 'whois.cctld.uz')
57
+ Whois::Server.define('va', 'whois.ripe.net')
58
+ Whois::Server.define('ve', 'whois.nic.ve')
59
+ Whois::Server.define('vg', 'whois.vg')
60
+ Whois::Server.define('wf', 'whois.nic.wf')
61
+ Whois::Server.define('ws', 'whois.tld.ws')
62
+ Whois::Server.define('yt', 'whois.nic.yt')
63
+ Whois::Server.define('us', 'whois.nic.us')
64
+ Whois::Server.define('at',"whois.nic.at")
65
+ Whois::Server.define('ca',"whois.cira.ca")
66
+ Whois::Server.define('cc',"whois.nic.cc")
67
+ Whois::Server.define('ch',"whois.nic.ch")
68
+ Whois::Server.define('cn',"whois.cnnic.net.cn")
69
+ Whois::Server.define('cz',"whois.nic.cz")
70
+ Whois::Server.define('ee',"whois.eenet.ee")
71
+ Whois::Server.define('es',"https://www.nic.es/esnic/servlet/BuscarDomSolAlta?dominio=%DOMAIN%")
72
+ Whois::Server.define('com.es',"https://www.nic.es/esnic/servlet/BuscarDomSolAlta?dominio=%DOMAIN%")
73
+ Whois::Server.define('gr',"https://grweb.ics.forth.gr/")
74
+ Whois::Server.define('it',"whois.nic.it")
75
+ Whois::Server.define('li',"whois.nic.li")
76
+ Whois::Server.define('lt',"whois.domreg.lt")
77
+ Whois::Server.define('lu',"whois.dns.lu")
78
+ Whois::Server.define('lv',"whois.ripe.net")
79
+ Whois::Server.define('ms',"whois.adamsnames.tc")
80
+ Whois::Server.define('co.nz',"whois.domainz.net.nz")
81
+ Whois::Server.define('nu',"whois.nic.nu")
82
+ Whois::Server.define('pl',"whois.dns.pl")
83
+ Whois::Server.define('ro',"whois.rotld.ro")
84
+ Whois::Server.define('ru',"whois.ripn.net")
85
+ Whois::Server.define('se',"whois.nic-se.se")
86
+ Whois::Server.define('sk',"whois.ripe.net")
87
+ Whois::Server.define('tc',"whois.adamsnames.tc")
88
+ Whois::Server.define('vg',"whois.adamsnames.tc")
89
+ Whois::Server.define('ws',"whois.worldsite.ws")
90
+
91
+
92
+ # By leaving out the whois server, we force it to follow the internic redirection.
93
+ Whois::Server.define(
94
+ [ 'com', 'net', 'edu' ], nil,
95
+ :registered => /No match for/im.invert!,
96
+ :free => /No match for/im
97
+ )
98
+
99
+ Whois::Server.define(
100
+ 'gov', 'whois.nic.gov',
101
+ :registered => /Status:\s*Active/im,
102
+ :free => /Status:\s*Active/im.invert!
103
+ )
104
+
105
+ Whois::Server.define(%w(asn.au com.au id.au net.au org.au), 'whois.aunic.net',
106
+ :free => /No Data Found/im,
107
+ :registered => /No Data Found/im.invert! )
108
+
109
+ Whois::Server.define(
110
+ %w(hk com.hk net.hk edu.hk org.hk gov.hk idv.hk),
111
+ 'whois.hkdnr.net.hk',
112
+ :free => /Domain Not Found/,
113
+ :registered => /Domain Name\:/im
114
+ )
115
+ Whois::Server.define(
116
+ %w(co.nz net.nz org.nz geek.nz school.nz gen.nz govt.nz maori.nz ac.nz iwi.nz cri.nz mil.nz parliament.nz),
117
+ 'whois.srs.net.nz',
118
+ :free => /220 available/im,
119
+ :registered => /220 available/im.invert!
120
+ )
121
+ Whois::Server.define(
122
+ %w(eu.com uk.com uk.net us.com la cn.com de.com jpn.com kr.com no.com za.com br.com ar.com ru.com sa.com se.com
123
+ se.net hu.com gb.com gb.net qc.com uy.com ae.org no.com se.com),
124
+ 'whois.centralnic.net',
125
+ :free => /available for registration/im,
126
+ :registered => /Domain Name\:/im
127
+ )
128
+ Whois::Server.define(
129
+ 'be',
130
+ 'whois.dns.be',
131
+ :free => /Status:\s+FREE/im,
132
+ :registered => /Status:\s+REGISTERED/im
133
+ )
134
+ Whois::Server.define(
135
+ 'biz',
136
+ 'whois.neulevel.biz',
137
+ :free => /Not found:/im,
138
+ :registered => /Domain Name:/im
139
+ )
140
+ Whois::Server.define(
141
+ %w(co.uk org.uk me.uk ltd.uk plc.uk net.uk sch.uk),
142
+ 'whois.nic.uk',
143
+ :registered => /Domain name:/im,
144
+ :free => /No match for/im,
145
+ :error => /Error for/im
146
+ )
147
+ Whois::Server.define(
148
+ 'de',
149
+ 'whois.denic.de',
150
+ :error => /Status:\s+invalid/im,
151
+ :registered => /Status:\s+connect/im,
152
+ :free => /Status:\s+free/im
153
+ )
154
+ Whois::Server.define(
155
+ 'dk',
156
+ 'whois.dk-hostmaster.dk',
157
+ :registered => /Registered:/im,
158
+ :error => /Your request is not valid./im,
159
+ :free => /No entries found for the selected source./im
160
+ )
161
+ Whois::Server.define(
162
+ 'eu',
163
+ 'http://www.whois.eu/whois/GetDomainStatus.htm?domainName=%DOMAIN%',
164
+ :free => /AVAILABLE/im,
165
+ :registered => /REGISTERED/im,
166
+ :pending => /APPLICATION PENDING/im,
167
+ :error => /NOT ALLOWED/im
168
+ )
169
+ Whois::Server.define(
170
+ 'info',
171
+ 'whois.afilias.info',
172
+ :error => /Not a valid domain search pattern/im,
173
+ :registered => /Domain Name:/im,
174
+ :free => /NOT FOUND/im
175
+ )
176
+ Whois::Server.define(
177
+ 'name',
178
+ 'whois.nic.name',
179
+ :registered => /Not available for registration./im,
180
+ :preserved => /Not available for second level registration./im,
181
+ :free => /No match./im
182
+ )
183
+ Whois::Server.define(
184
+ 'net',
185
+ 'whois.verisign-grs.com',
186
+ :registered => /Domain Name:/im,
187
+ :free => /No match for/im
188
+ )
189
+ Whois::Server.define(
190
+ 'nl',
191
+ 'whois.domain-registry.nl',
192
+ :registered => /ims active/im,
193
+ :free => /ims free/im,
194
+ :error => /imnvalid name/im,
195
+ :preserved => /ims excluded/im
196
+ )
197
+ Whois::Server.define(
198
+ 'org',
199
+ 'whois.publicinterestregistry.net',
200
+ :registered => /Domain Name:/im,
201
+ :free => /NOT FOUND/im,
202
+ :error => /Not a valid domain search pattern/im
203
+ )
204
+ Whois::Server.define(
205
+ 'cc',
206
+ 'whois.nic.cc',
207
+ :registered => /Domain Name:/im,
208
+ :free => /No match for/im
209
+
210
+ )
211
+ Whois::Server.define(
212
+ 'ru',
213
+ 'whois.ripn.net',
214
+ :registered => /domain:/im,
215
+ :free => /No entries found/im
216
+
217
+ )
218
+ Whois::Server.define(
219
+ 'cat',
220
+ 'whois.cat',
221
+ :registered => /Domain Name: /im,
222
+ :free => /NOT FOUND/im
223
+
224
+ )
225
+ Whois::Server.define(
226
+ %w(travel jobs aero mobi pw tw),
227
+ 'whois.encirca.com',
228
+ :registered => /Domain Registrar Status:/im,
229
+ :free => /Not found:/im
230
+ )
231
+ Whois::Server.define(
232
+ 'ca',
233
+ 'whois.cira.ca',
234
+ :registered => /EXIST/im,
235
+ :free => /AVAIL/im
236
+ )
237
+ Whois::Server.define('asia', 'whois.nic.asia',
238
+ :registered => /Domain ID/im,
239
+ :free => /NOT FOUND/im
240
+ )
data/test/whois.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/universal_ruby_whois'
3
+
4
+ class WhoisTest < Test::Unit::TestCase
5
+
6
+ def test_unavailable
7
+ domain = Whois::Server.find("google.com")
8
+ assert !domain.available?
9
+ assert domain.registered?
10
+ end
11
+
12
+ def test_available
13
+ domain = Whois::Server.find("j983jf89ej2e09d2jd.com")
14
+ assert domain.available?
15
+ assert !domain.registered?
16
+ end
17
+
18
+ def test_creation_date
19
+ domain = Whois::Server.find("google.com")
20
+ domain.created_date == Time.local(*ParseDate.parsedate("1997-09-15"))
21
+ end
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mlightner-universal_ruby_whois
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Lightner
8
+ autorequire: name
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-09 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.4
23
+ version:
24
+ description:
25
+ email: mlightner@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README
32
+ - LICENSE
33
+ files:
34
+ - README
35
+ - LICENSE
36
+ - lib/universal_ruby_whois.rb
37
+ - lib/universal_ruby_whois/domain.rb
38
+ - lib/universal_ruby_whois/server.rb
39
+ - lib/universal_ruby_whois/server_list.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/mlightner/universal_ruby_whois/tree/master
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: A module that attempts to act as a universal WHOIS output interpreter allowing you to get information about most domain name extensions.
66
+ test_files:
67
+ - test/whois.rb