whois 0.5.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +55 -0
- data/Manifest +43 -8
- data/README.rdoc +53 -20
- data/lib/whois.rb +69 -1
- data/lib/whois/answer.rb +126 -0
- data/lib/whois/answer/contact.rb +55 -0
- data/lib/whois/answer/parser.rb +110 -0
- data/lib/whois/answer/parser/README.rdoc +21 -0
- data/lib/whois/answer/parser/base.rb +144 -0
- data/lib/whois/answer/parser/blank.rb +45 -0
- data/lib/whois/answer/parser/whois.crsnic.net.rb +209 -0
- data/lib/whois/answer/parser/whois.denic.de.rb +202 -0
- data/lib/whois/answer/parser/whois.nic.it.rb +330 -0
- data/lib/whois/answer/parser/whois.publicinterestregistry.net.rb +232 -0
- data/lib/whois/answer/part.rb +35 -0
- data/lib/whois/answer/registrar.rb +42 -0
- data/lib/whois/answer/super_struct.rb +57 -0
- data/lib/whois/client.rb +6 -0
- data/lib/whois/definitions/tlds.rb +2 -2
- data/lib/whois/errors.rb +25 -8
- data/lib/whois/server.rb +0 -1
- data/lib/whois/server/adapters/afilias.rb +5 -5
- data/lib/whois/server/adapters/base.rb +31 -4
- data/lib/whois/server/adapters/formatted.rb +3 -1
- data/lib/whois/server/adapters/none.rb +20 -1
- data/lib/whois/server/adapters/pir.rb +5 -5
- data/lib/whois/server/adapters/standard.rb +13 -2
- data/lib/whois/server/adapters/verisign.rb +5 -5
- data/lib/whois/server/adapters/web.rb +15 -0
- data/lib/whois/version.rb +2 -2
- data/lib/whois/whois.rb +2 -2
- data/test/answer/parser/base_test.rb +27 -0
- data/test/answer/parser/blank_test.rb +19 -0
- data/test/answer/parser/whois_crsnic_net_test.rb +175 -0
- data/test/answer/parser/whois_denic_de_test.rb +209 -0
- data/test/answer/parser/whois_nic_it_test.rb +255 -0
- data/test/answer/parser/whois_publicinterestregistry_net_test.rb +210 -0
- data/test/answer/parser_test.rb +77 -0
- data/test/answer_test.rb +99 -0
- data/test/client_test.rb +3 -3
- data/test/integration_test.rb +31 -0
- data/test/{adapters → server/adapters}/afilias_test.rb +10 -5
- data/test/server/adapters/base_test.rb +15 -0
- data/test/server/adapters/formatted_test.rb +26 -0
- data/test/{adapters → server/adapters}/none_test.rb +0 -0
- data/test/{adapters → server/adapters}/not_implemented_test.rb +0 -0
- data/test/{adapters → server/adapters}/pir_test.rb +10 -5
- data/test/server/adapters/standard_test.rb +29 -0
- data/test/{adapters → server/adapters}/verisign_test.rb +10 -5
- data/test/{adapters → server/adapters}/web_test.rb +0 -0
- data/test/server_test.rb +5 -1
- data/test/testcases/responses/super_struct_test.rb +25 -0
- data/test/testcases/responses/whois.crsnic.net/available.txt +43 -0
- data/test/testcases/responses/whois.crsnic.net/registered.txt +57 -0
- data/test/testcases/responses/whois.denic.de/available.txt +30 -0
- data/test/testcases/responses/whois.denic.de/registered.txt +77 -0
- data/test/testcases/responses/whois.nic.it/available.txt +2 -0
- data/test/testcases/responses/{it.txt → whois.nic.it/registered.txt} +1 -0
- data/test/testcases/responses/whois.nic.it/status_active.txt +53 -0
- data/test/testcases/responses/whois.nic.it/status_available.txt +2 -0
- data/test/testcases/responses/whois.publicinterestregistry.net/available.txt +1 -0
- data/test/testcases/responses/whois.publicinterestregistry.net/registered.txt +85 -0
- data/test/whois_test.rb +23 -1
- data/utils/bm_delegation_vs_inheritance.rb +150 -0
- data/whois.gemspec +6 -6
- metadata +78 -18
- data/test/adapters/standard_test.rb +0 -23
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,61 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
3
|
|
4
|
+
== Release 0.8.0
|
5
|
+
|
6
|
+
* FIXED: Server definition with :format doesn't use the Formatted adapter (closes #305)
|
7
|
+
|
8
|
+
* ADDED: whois.denic.de (.de TLD) parser [Aaron Mueller]
|
9
|
+
|
10
|
+
* ADDED: introduced support for multipart answers and Parser proxy class. This is useful in case of thin servers such as .com or .net because the parser needs to know all different responses in order to load all single scanners.
|
11
|
+
|
12
|
+
* ADDED: whois.crsnic.net (.com, .net, ... TLDs) parser.
|
13
|
+
|
14
|
+
* CHANGED: extracted all scanners into separated classes in order to make easier extract shared features.
|
15
|
+
|
16
|
+
* CHANGED: renamed Whois::Response to Whois::Answer. This change is required to avoid confusion between query-answer and server request-response. A Whois::Answer is composed by one or more parts, corresponding to single server answers.
|
17
|
+
|
18
|
+
* REMOVED: Whois::Answer#i_am_feeling_lucky (formerly Whois::Answer#i_am_feeling_lucky) become obsolete since the introduction of Answer parsers.
|
19
|
+
|
20
|
+
|
21
|
+
== Release 0.6.0
|
22
|
+
|
23
|
+
* ADDED: new more convenient method to query a whois server in addition to the existing Whois::whois method.
|
24
|
+
|
25
|
+
Whois::query("domain.com")
|
26
|
+
# same as Whois::whois but added to normalize application interfaces.
|
27
|
+
|
28
|
+
Whois::available?("domain.com")
|
29
|
+
# returns true if the domain is available.
|
30
|
+
|
31
|
+
Whois::registered?("domain.com")
|
32
|
+
# returns true if the domain is registered.
|
33
|
+
|
34
|
+
* ADDED: Experimental support for whois response parsing. This release is shipped with two parsers for the .it and .net TLD.
|
35
|
+
|
36
|
+
r = Whois::query("google.it")
|
37
|
+
r.available?
|
38
|
+
# => false
|
39
|
+
r.created_on
|
40
|
+
# => Time.parse("1999-12-10 00:00:00")
|
41
|
+
r.Nameservers
|
42
|
+
# => ["ns1.google.com", "ns2.google.com", ...]
|
43
|
+
|
44
|
+
* CHANGED: A whois query now returns a custom Whois::Response object instead of a simple string.
|
45
|
+
The previous interface is still supported, so you can continue to compare the response with Strings
|
46
|
+
but this behavior will be deprecated in a future release.
|
47
|
+
|
48
|
+
r = Whois::query("domain.com")
|
49
|
+
# supported but deprecated in a future version
|
50
|
+
r == "NOT FOUND"
|
51
|
+
# explicitly cast the object to string instead
|
52
|
+
r.to_s == "NOT FOUND"
|
53
|
+
# or use one of the other Whois::Response methods.
|
54
|
+
|
55
|
+
Note. This is an experimental version (EAP) and it should not be considered production-ready.
|
56
|
+
API might change at any time without previous notice.
|
57
|
+
|
58
|
+
|
4
59
|
== Release 0.5.3
|
5
60
|
|
6
61
|
FIXED: self.valid_ipv6?(addr) references valid_v4? instead of valid_ipv4? (closes #300)
|
data/Manifest
CHANGED
@@ -6,6 +6,19 @@ data/make_ip6_del.pl
|
|
6
6
|
data/make_ip_del.pl
|
7
7
|
data/make_tld_serv.pl
|
8
8
|
data/tld_serv_list
|
9
|
+
lib/whois/answer/contact.rb
|
10
|
+
lib/whois/answer/parser/base.rb
|
11
|
+
lib/whois/answer/parser/blank.rb
|
12
|
+
lib/whois/answer/parser/README.rdoc
|
13
|
+
lib/whois/answer/parser/whois.crsnic.net.rb
|
14
|
+
lib/whois/answer/parser/whois.denic.de.rb
|
15
|
+
lib/whois/answer/parser/whois.nic.it.rb
|
16
|
+
lib/whois/answer/parser/whois.publicinterestregistry.net.rb
|
17
|
+
lib/whois/answer/parser.rb
|
18
|
+
lib/whois/answer/part.rb
|
19
|
+
lib/whois/answer/registrar.rb
|
20
|
+
lib/whois/answer/super_struct.rb
|
21
|
+
lib/whois/answer.rb
|
9
22
|
lib/whois/client.rb
|
10
23
|
lib/whois/definitions/ipv4.rb
|
11
24
|
lib/whois/definitions/ipv4.txt
|
@@ -33,22 +46,44 @@ Manifest
|
|
33
46
|
Rakefile
|
34
47
|
README.rdoc
|
35
48
|
tasks/server.rake
|
36
|
-
test/
|
37
|
-
test/
|
38
|
-
test/
|
39
|
-
test/
|
40
|
-
test/
|
41
|
-
test/
|
42
|
-
test/
|
49
|
+
test/answer/parser/base_test.rb
|
50
|
+
test/answer/parser/blank_test.rb
|
51
|
+
test/answer/parser/whois_crsnic_net_test.rb
|
52
|
+
test/answer/parser/whois_denic_de_test.rb
|
53
|
+
test/answer/parser/whois_nic_it_test.rb
|
54
|
+
test/answer/parser/whois_publicinterestregistry_net_test.rb
|
55
|
+
test/answer/parser_test.rb
|
56
|
+
test/answer_test.rb
|
43
57
|
test/client_test.rb
|
44
58
|
test/deprecated_test.rb
|
59
|
+
test/integration_test.rb
|
60
|
+
test/server/adapters/afilias_test.rb
|
61
|
+
test/server/adapters/base_test.rb
|
62
|
+
test/server/adapters/formatted_test.rb
|
63
|
+
test/server/adapters/none_test.rb
|
64
|
+
test/server/adapters/not_implemented_test.rb
|
65
|
+
test/server/adapters/pir_test.rb
|
66
|
+
test/server/adapters/standard_test.rb
|
67
|
+
test/server/adapters/verisign_test.rb
|
68
|
+
test/server/adapters/web_test.rb
|
45
69
|
test/server_test.rb
|
46
70
|
test/test_helper.rb
|
47
71
|
test/testcases/referrals/afilias.bz.txt
|
48
72
|
test/testcases/referrals/crsnic.com.txt
|
49
73
|
test/testcases/referrals/niccc.cc.txt
|
50
74
|
test/testcases/referrals/pir.org.txt
|
51
|
-
test/testcases/responses/
|
75
|
+
test/testcases/responses/super_struct_test.rb
|
76
|
+
test/testcases/responses/whois.crsnic.net/available.txt
|
77
|
+
test/testcases/responses/whois.crsnic.net/registered.txt
|
78
|
+
test/testcases/responses/whois.denic.de/available.txt
|
79
|
+
test/testcases/responses/whois.denic.de/registered.txt
|
80
|
+
test/testcases/responses/whois.nic.it/available.txt
|
81
|
+
test/testcases/responses/whois.nic.it/registered.txt
|
82
|
+
test/testcases/responses/whois.nic.it/status_active.txt
|
83
|
+
test/testcases/responses/whois.nic.it/status_available.txt
|
84
|
+
test/testcases/responses/whois.publicinterestregistry.net/available.txt
|
85
|
+
test/testcases/responses/whois.publicinterestregistry.net/registered.txt
|
52
86
|
test/whois_test.rb
|
87
|
+
utils/bm_delegation_vs_inheritance.rb
|
53
88
|
utils/bm_shell_vs_pure.rb
|
54
89
|
utils/tlds.txt
|
data/README.rdoc
CHANGED
@@ -1,21 +1,24 @@
|
|
1
1
|
= Whois
|
2
2
|
|
3
|
-
Whois is an intelligent pure Ruby WHOIS client.
|
3
|
+
Whois is an intelligent pure Ruby WHOIS client and parser.
|
4
4
|
|
5
5
|
It is a os-independent library and doesn't require external C libraries or GEMS: it is a 100% Ruby software with all the advantages and disadvantages that it involves.
|
6
6
|
|
7
|
-
This software was developed to power RoboDomain[http://www.robodomain.com] and,
|
7
|
+
This software was developed to power RoboDomain[http://www.robodomain.com] and, since July 2009, it run more than thousands requests.
|
8
8
|
|
9
9
|
An extensive test suite is available to verify the library correctness but you must be aware that registrant might change Whois interfaces without notice and at any time causing queries to specific hosts to stop working.
|
10
10
|
|
11
11
|
|
12
12
|
== Features
|
13
13
|
|
14
|
-
*
|
15
|
-
*
|
14
|
+
* Pure Ruby library without any external dependency other than Ruby itself
|
15
|
+
* Intelligent Ruby client
|
16
|
+
* Flexible and extensible configuration with support for user-defined servers
|
17
|
+
* Powerful whois response parser
|
16
18
|
* Support for ipv6, ipv4 and top level domain whois queries
|
17
19
|
* Object oriented design
|
18
20
|
* Compatible with older Whois version (Whois 0.4.2, see below)
|
21
|
+
* Compatible with Ruby 1.8.6 and greater, including Ruby 1.9
|
19
22
|
|
20
23
|
|
21
24
|
== Requirements
|
@@ -43,26 +46,28 @@ You might need administrator privileges on your system to install it.
|
|
43
46
|
|
44
47
|
== Getting Started
|
45
48
|
|
46
|
-
Note. This section covers only the essentials for getting started with the Whois library.
|
49
|
+
Note. This section covers only the essentials for getting started with the Whois library. The {documentation}[http://code.simonecarletti.com/wiki/whois] provides a more accurate explanation including tutorials, more examples and technical details about the client/server/answer/parser architecture.
|
47
50
|
|
48
|
-
|
51
|
+
=== Querying the Server
|
52
|
+
|
53
|
+
Whois provides the ability to get WHOIS information for hostnames, ipv4 and ipv6 ip addresses. The client is smart enough to guess the best WHOIS server according to given query, send the request and return the response.
|
49
54
|
|
50
55
|
Checkout the following examples:
|
51
56
|
|
52
57
|
# Domain Whois
|
53
58
|
w = Whois::Client.new
|
54
59
|
w.query("google.com")
|
55
|
-
# =>
|
60
|
+
# => #<Whois::Answer>
|
56
61
|
|
57
62
|
# IPv4 Whois
|
58
63
|
w = Whois::Client.new
|
59
64
|
w.query("74.125.67.100")
|
60
|
-
# =>
|
65
|
+
# => #<Whois::Answer>
|
61
66
|
|
62
67
|
# IPv6 Whois
|
63
68
|
w = Whois::Client.new
|
64
69
|
w.query("2001:db8::1428:57ab")
|
65
|
-
# =>
|
70
|
+
# => #<Whois::Answer>
|
66
71
|
|
67
72
|
The query method is stateless. For this reason, you can safely re-use the same client instance for multiple queries.
|
68
73
|
|
@@ -72,6 +77,43 @@ The query method is stateless. For this reason, you can safely re-use the same c
|
|
72
77
|
w.query("2001:db8::1428:57ab")
|
73
78
|
w.query("google.it")
|
74
79
|
|
80
|
+
If you just need a WHOIS response and you don't care about a full control of the WHOIS Client, Whois comes with a simple method called whois. This is the simplest way to send a WHOIS request.
|
81
|
+
|
82
|
+
Whois.whois("google.com")
|
83
|
+
# => #<Whois::Answer>
|
84
|
+
|
85
|
+
=== Consuming the Answer
|
86
|
+
|
87
|
+
As of release 0.8, a WHOIS query no longer returns a simple string. Instead, you get a full Whois::Answer instance and this is just the beginning of the story.
|
88
|
+
|
89
|
+
Whois::Answer is a super powerful object. It encapsulates the full WHOIS answer and it provides you the ability to parse the WHOIS response with a full object oriented notation.
|
90
|
+
|
91
|
+
a = Whois.whois("google.it")
|
92
|
+
# => #<Whois::Answer>
|
93
|
+
|
94
|
+
a.available?
|
95
|
+
# => false
|
96
|
+
a.registered?
|
97
|
+
# => true
|
98
|
+
|
99
|
+
a.created_on
|
100
|
+
# => Fri Dec 10 00:00:00 +0100 1999
|
101
|
+
|
102
|
+
t = a.techinical
|
103
|
+
# => #<Whois::Answer::Contact>
|
104
|
+
t.id
|
105
|
+
# => "TS7016-ITNIC"
|
106
|
+
t.name
|
107
|
+
# => "Technical Services"
|
108
|
+
|
109
|
+
a.nameservers.each do |nameserver|
|
110
|
+
puts nameserver
|
111
|
+
end
|
112
|
+
|
113
|
+
This feature is made possible by the Whois answer parsers. Unfortunately, due to the lack of a global standard, each WHOIS server requires a specific parser. For this reason, the library doesn't support all existing WHOIS servers.
|
114
|
+
|
115
|
+
If you create a new parser, please consider releasing it to the public so that it can be included in a next version.
|
116
|
+
|
75
117
|
=== Timeout
|
76
118
|
|
77
119
|
By default, each query run though the client has a timeout value of 5 seconds. If the execution exceeds timeout limit, the client raises a <tt>Timeout::Error</tt> exception.
|
@@ -101,7 +143,7 @@ The parser architecture (yet to come) has been inspired by the PHPWhois[http://p
|
|
101
143
|
Despite I spent weeks reading source code from the available whois libraries, Ruby Whois has been built from scratch trying to focus on long-term maintainability and flexibility and cannot be considered a Ruby port of any of other existing Whois libraries.
|
102
144
|
|
103
145
|
|
104
|
-
== Notice for users of Whois 0.4
|
146
|
+
== Notice for users of Whois 0.4 (or previous version)
|
105
147
|
|
106
148
|
As of release 0.5.0, the Whois GEM has been completely rewritten. As I explained in the Acknowledgment section, Cyril Mougel (the author of the original Whois package) yield me the privilege to use the Whois RubyForge project for my new Whois client.
|
107
149
|
|
@@ -117,7 +159,7 @@ Copyright (c) 2007 by Cyril Mougel (cyril.mougel@gmail.com)
|
|
117
159
|
== Credits
|
118
160
|
|
119
161
|
Author:: {Simone Carletti}[http://www.simonecarletti.com/] <weppos@weppos.net>
|
120
|
-
|
162
|
+
Author (Whois 0.4):: {Cyril Mougel}[http://blog.shingara.fr/] <cyril.mougel@gmail.com>
|
121
163
|
|
122
164
|
|
123
165
|
== FeedBack and Bug reports
|
@@ -132,8 +174,6 @@ Bug reports and Feature suggestions {are welcomed}[http://code.simonecarletti.co
|
|
132
174
|
* {Homepage}[http://code.simonecarletti.com/whois]
|
133
175
|
* {GitHub}[http://github.com/weppos/whois]
|
134
176
|
* {RubyForge}[http://rubyforge.org/projects/whois/]
|
135
|
-
|
136
|
-
* {Documentation}[http://code.simonecarletti.com/wiki/whois]
|
137
177
|
* {API}[http://whois.rubyforge.org/]
|
138
178
|
* {Discussion Group}[http://groups.google.com/group/ruby-whois]
|
139
179
|
|
@@ -143,13 +183,6 @@ Bug reports and Feature suggestions {are welcomed}[http://code.simonecarletti.co
|
|
143
183
|
See the CHANGELOG.rdoc file for details.
|
144
184
|
|
145
185
|
|
146
|
-
== Roadmap
|
147
|
-
|
148
|
-
* Implement intelligent Whois response parsing
|
149
|
-
|
150
|
-
For more details visit the {roadmap page}[http://code.simonecarletti.com/projects/roadmap/whois].
|
151
|
-
|
152
|
-
|
153
186
|
== License
|
154
187
|
|
155
188
|
Copyright (c) 2009 Simone Carletti, Whois is released under the MIT license.
|
data/lib/whois.rb
CHANGED
@@ -18,6 +18,7 @@ require 'whois/version'
|
|
18
18
|
require 'whois/errors'
|
19
19
|
require 'whois/client'
|
20
20
|
require 'whois/server'
|
21
|
+
require 'whois/answer'
|
21
22
|
require 'whois/whois'
|
22
23
|
|
23
24
|
|
@@ -26,8 +27,75 @@ module Whois
|
|
26
27
|
NAME = 'Whois'
|
27
28
|
GEM = 'whois'
|
28
29
|
AUTHORS = ['Simone Carletti <weppos@weppos.net>']
|
29
|
-
|
30
|
+
|
31
|
+
|
32
|
+
# Queries the right whois server for <tt>qstring</tt> and returns
|
33
|
+
# a <tt>Whois::Answer</tt> instance containing the response from the server.
|
34
|
+
#
|
35
|
+
# Whois.query("google.com")
|
36
|
+
# # => #<Whois::Answer>
|
37
|
+
#
|
38
|
+
# This is equivalent to
|
39
|
+
#
|
40
|
+
# Whois::Client.new.query("google.com")
|
41
|
+
# # => #<Whois::Answer>
|
42
|
+
#
|
30
43
|
def self.whois(qstring)
|
44
|
+
query(qstring)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns <tt>true</tt> whether <tt>qstring</tt> is available.
|
48
|
+
# <tt>qstring</tt> is intended to be a domain name,
|
49
|
+
# otherwise this method may return unexpected responses.
|
50
|
+
#
|
51
|
+
# Whois.available?("google.com")
|
52
|
+
# # => false
|
53
|
+
#
|
54
|
+
# Whois.available?("google-is-not-available-try-again-later.com")
|
55
|
+
# # => true
|
56
|
+
#
|
57
|
+
# Warning: this method is only available if a Whois parser exists
|
58
|
+
# for <tt>qstring</tt> top level domain. Otherwise you'll get a warning message
|
59
|
+
# and the method will return <tt>nil</tt>.
|
60
|
+
# This is a technical limitation. Browse the lib/whois/answer/parsers folder
|
61
|
+
# to view all available parsers.
|
62
|
+
#
|
63
|
+
def self.available?(qstring)
|
64
|
+
query(qstring).available?
|
65
|
+
rescue ParserNotFound => e
|
66
|
+
$stderr.puts "This method is not available for this kind of object.\n" +
|
67
|
+
"Use Whois.query('#{qstring}') instead."
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns <tt>true</tt> whether <tt>qstring</tt> is registered.
|
72
|
+
# <tt>qstring</tt> is intended to be a domain name,
|
73
|
+
# otherwise this method may return unexpected responses.
|
74
|
+
#
|
75
|
+
# Whois.registered?("google.com")
|
76
|
+
# # => true
|
77
|
+
#
|
78
|
+
# Whois.registered?("google-is-not-available-try-again-later.com")
|
79
|
+
# # => false
|
80
|
+
#
|
81
|
+
# Warning: this method is only available if a Whois parser exists
|
82
|
+
# for <tt>qstring</tt> top level domain. Otherwise you'll get a warning message
|
83
|
+
# and the method will return <tt>nil</tt>.
|
84
|
+
# This is a technical limitation. Browse the lib/whois/answer/parsers folder
|
85
|
+
# to view all available parsers.
|
86
|
+
#
|
87
|
+
def self.registered?(qstring)
|
88
|
+
query(qstring).registered?
|
89
|
+
rescue ParserNotFound => e
|
90
|
+
$stderr.puts "This method is not available for this kind of object.\n" +
|
91
|
+
"Use Whois.query('#{qstring}') instead."
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# See Whois#whois.
|
97
|
+
def self.query(qstring)
|
31
98
|
Client.new.query(qstring)
|
32
99
|
end
|
100
|
+
|
33
101
|
end
|
data/lib/whois/answer.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
#
|
2
|
+
# = Ruby Whois
|
3
|
+
#
|
4
|
+
# An intelligent pure Ruby WHOIS client.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Category:: Net
|
8
|
+
# Package:: Whois
|
9
|
+
# Author:: Simone Carletti <weppos@weppos.net>
|
10
|
+
# License:: MIT License
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
#
|
14
|
+
#++
|
15
|
+
|
16
|
+
|
17
|
+
require 'whois/answer/parser'
|
18
|
+
require 'whois/answer/parser/base'
|
19
|
+
|
20
|
+
|
21
|
+
module Whois
|
22
|
+
|
23
|
+
class Answer
|
24
|
+
|
25
|
+
attr_reader :server
|
26
|
+
attr_reader :parts
|
27
|
+
|
28
|
+
def initialize(server, parts)
|
29
|
+
@parts = parts
|
30
|
+
@server = server
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
content.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect
|
39
|
+
content.inspect
|
40
|
+
end
|
41
|
+
|
42
|
+
# Invokes <tt>match</tt> on answer <tt>@content</tt>
|
43
|
+
# and returns the <tt>MatchData</tt> or <tt>nil</tt>.
|
44
|
+
def match(pattern)
|
45
|
+
content.match(pattern)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns true if the <tt>object</tt> is the same object,
|
49
|
+
# or is a string and has the same content.
|
50
|
+
def ==(other)
|
51
|
+
(other.equal?(self)) ||
|
52
|
+
# This option should be deprecated
|
53
|
+
(other.instance_of?(String) && other == self.to_s) ||
|
54
|
+
(other.instance_of?(Answer) && other.to_s == self.to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delegates to ==.
|
58
|
+
def eql?(other)
|
59
|
+
self == other
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Returns the content of this answer as a string.
|
64
|
+
# This method joins all answer parts into a single string
|
65
|
+
# and separates each response with a newline character.
|
66
|
+
#
|
67
|
+
# answer = Whois::Answer.new([Whois::Answer::Part.new("First answer.")])
|
68
|
+
# answer.content
|
69
|
+
# # => "First answer."
|
70
|
+
#
|
71
|
+
# answer = Whois::Answer.new([Whois::Answer::Part.new("First answer."), Whois::Answer::Part.new("Second answer.")])
|
72
|
+
# answer.content
|
73
|
+
# # => "First answer.\nSecond answer."
|
74
|
+
#
|
75
|
+
def content
|
76
|
+
@content ||= parts.map { |part| part.response }.join("\n")
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns whether this answer changed compared to <tt>other</tt>.
|
80
|
+
#
|
81
|
+
# Comparing the Answer contents is not always as trivial as it seems.
|
82
|
+
# Whois servers sometimes inject dynamic method into the whois answer such as
|
83
|
+
# the timestamp the request was generated.
|
84
|
+
# This causes two answers to be different even if they actually should be considered equal
|
85
|
+
# because the registry data didn't change.
|
86
|
+
#
|
87
|
+
# This method should provide a bulletproof way to detect whether this answer
|
88
|
+
# changed if compared with <tt>other</tt>.
|
89
|
+
def changed?(other)
|
90
|
+
!unchanged?(other)
|
91
|
+
end
|
92
|
+
|
93
|
+
# The opposite of <tt>changed?</tt>.
|
94
|
+
def unchanged?(other)
|
95
|
+
self == other ||
|
96
|
+
parser.unchanged?(other.parser)
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Invokes <tt>match</tt> and returns <tt>true</tt> if <tt>pattern</tt>
|
101
|
+
# matches <tt>@content</tt>, <tt>false</tt> otherwise.
|
102
|
+
def match?(pattern)
|
103
|
+
!content.match(pattern).nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Lazy-loads and returns a <tt>Whois::Answer::Parser</tt> proxy for current answer.
|
108
|
+
def parser
|
109
|
+
@parser ||= Parser.new(self)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
protected
|
114
|
+
|
115
|
+
# Delegates all method calls to the internal parser.
|
116
|
+
def method_missing(method, *args, &block)
|
117
|
+
if Parser.registrable_methods.include?(method)
|
118
|
+
parser.send(method, *args, &block)
|
119
|
+
else
|
120
|
+
super
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|