whois 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,17 @@
1
1
  = Changelog
2
2
 
3
3
 
4
+ == Release 1.1.3
5
+
6
+ * NEW: Added simple .tk TLD parser (whois.dot.tk).
7
+
8
+ * NEW: Added .sn TLD parser (whois.nic.sn).
9
+
10
+ * CHANGED: Whois::Answer#== and Whois::Answer#eql? should be able to compare Whois::Answer with subclasses.
11
+
12
+ * CHANGED: Deprecate Whois::Answer::Parser.properties. Use Whois::Answer::Parser::PROPERTIES instead.
13
+
14
+
4
15
  == Release 1.1.2
5
16
 
6
17
  * NEW: Whois::Answer::Contact#type property returns the type of the contact (ADMIN, TECHNICAL, ...).
data/Manifest CHANGED
@@ -21,6 +21,7 @@ lib/whois/answer/parser/NOTES.txt
21
21
  lib/whois/answer/parser/ast.rb
22
22
  lib/whois/answer/parser/base.rb
23
23
  lib/whois/answer/parser/blank.rb
24
+ lib/whois/answer/parser/example.rb
24
25
  lib/whois/answer/parser/jobswhois.verisign-grs.com.rb
25
26
  lib/whois/answer/parser/scanners/verisign.rb
26
27
  lib/whois/answer/parser/whois.adamsnames.tc.rb
@@ -44,6 +45,7 @@ lib/whois/answer/parser/whois.dns.lu.rb
44
45
  lib/whois/answer/parser/whois.domain-registry.nl.rb
45
46
  lib/whois/answer/parser/whois.domainregistry.ie.rb
46
47
  lib/whois/answer/parser/whois.domreg.lt.rb
48
+ lib/whois/answer/parser/whois.dot.tk.rb
47
49
  lib/whois/answer/parser/whois.dotmobiregistry.net.rb
48
50
  lib/whois/answer/parser/whois.educause.edu.rb
49
51
  lib/whois/answer/parser/whois.eu.org.rb
@@ -80,6 +82,7 @@ lib/whois/answer/parser/whois.nic.mx.rb
80
82
  lib/whois/answer/parser/whois.nic.name.rb
81
83
  lib/whois/answer/parser/whois.nic.nu.rb
82
84
  lib/whois/answer/parser/whois.nic.or.kr.rb
85
+ lib/whois/answer/parser/whois.nic.sn.rb
83
86
  lib/whois/answer/parser/whois.nic.st.rb
84
87
  lib/whois/answer/parser/whois.nic.tel.rb
85
88
  lib/whois/answer/parser/whois.nic.tl.rb
@@ -149,6 +152,7 @@ test/answer/parser/whois.dns.lu_test.rb
149
152
  test/answer/parser/whois.domain-registry.nl_test.rb
150
153
  test/answer/parser/whois.domainregistry.ie_test.rb
151
154
  test/answer/parser/whois.domreg.lt_test.rb
155
+ test/answer/parser/whois.dot.tk_test.rb
152
156
  test/answer/parser/whois.dotmobiregistry.net_test.rb
153
157
  test/answer/parser/whois.educause.edu_test.rb
154
158
  test/answer/parser/whois.eu.org_test.rb
@@ -185,6 +189,7 @@ test/answer/parser/whois.nic.mx_test.rb
185
189
  test/answer/parser/whois.nic.name_test.rb
186
190
  test/answer/parser/whois.nic.nu_test.rb
187
191
  test/answer/parser/whois.nic.or.kr_test.rb
192
+ test/answer/parser/whois.nic.sn_test.rb
188
193
  test/answer/parser/whois.nic.st_test.rb
189
194
  test/answer/parser/whois.nic.tel_test.rb
190
195
  test/answer/parser/whois.nic.tl_test.rb
@@ -300,6 +305,8 @@ test/testcases/responses/whois.domainregistry.ie/registered.txt
300
305
  test/testcases/responses/whois.domreg.lt/available.txt
301
306
  test/testcases/responses/whois.domreg.lt/property_nameservers_with_ip.txt
302
307
  test/testcases/responses/whois.domreg.lt/registered.txt
308
+ test/testcases/responses/whois.dot.tk/available.txt
309
+ test/testcases/responses/whois.dot.tk/registered.txt
303
310
  test/testcases/responses/whois.dotmobiregistry.net/available.txt
304
311
  test/testcases/responses/whois.dotmobiregistry.net/registered.txt
305
312
  test/testcases/responses/whois.educause.edu/available.txt
@@ -396,6 +403,8 @@ test/testcases/responses/whois.nic.nu/available.txt
396
403
  test/testcases/responses/whois.nic.nu/registered.txt
397
404
  test/testcases/responses/whois.nic.or.kr/available.txt
398
405
  test/testcases/responses/whois.nic.or.kr/registered.txt
406
+ test/testcases/responses/whois.nic.sn/available.txt
407
+ test/testcases/responses/whois.nic.sn/registered.txt
399
408
  test/testcases/responses/whois.nic.st/available.txt
400
409
  test/testcases/responses/whois.nic.st/registered.txt
401
410
  test/testcases/responses/whois.nic.tel/available.txt
@@ -1,12 +1,17 @@
1
1
  unless :to_proc.respond_to?(:to_proc)
2
2
  class Symbol
3
- # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
3
+ # Turns the symbol into a simple proc,
4
+ # which is especially useful for enumerations.
5
+ #
6
+ # Examples
4
7
  #
5
8
  # # The same as people.collect { |p| p.name }
6
9
  # people.collect(&:name)
7
10
  #
8
11
  # # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
9
12
  # people.select(&:manager?).collect(&:salary)
13
+ #
14
+ # Returns a Proc which incapsulates the method business logic.
10
15
  def to_proc
11
16
  Proc.new { |*args| args.shift.__send__(self, *args) }
12
17
  end
@@ -56,8 +56,8 @@ module Whois
56
56
  def ==(other)
57
57
  (other.equal?(self)) ||
58
58
  # This option should be deprecated
59
- (other.instance_of?(String) && other == self.to_s) ||
60
- (other.instance_of?(Answer) && other.to_s == self.to_s)
59
+ (other.is_a?(String) && other == self.to_s) ||
60
+ (other.is_a?(Answer) && other.to_s == self.to_s)
61
61
  end
62
62
 
63
63
  # Delegates to ==.
@@ -118,7 +118,7 @@ module Whois
118
118
  # along with corresponding values.
119
119
  def properties
120
120
  hash = {}
121
- Parser.properties.each { |property| hash[property] = send(property) }
121
+ Parser::PROPERTIES.each { |property| hash[property] = send(property) }
122
122
  hash
123
123
  end
124
124
 
@@ -134,7 +134,7 @@ module Whois
134
134
 
135
135
  # Delegates all method calls to the internal parser.
136
136
  def method_missing(method, *args, &block)
137
- if (Parser.properties + Parser::METHODS).include?(method)
137
+ if (Parser::PROPERTIES + Parser::METHODS).include?(method)
138
138
  self.class.class_eval foo = %{
139
139
  def #{method}(*args, &block)
140
140
  if property_supported?(:#{method})
@@ -28,7 +28,7 @@ module Whois
28
28
  :registrant, :admin, :technical,
29
29
  ]
30
30
 
31
- @@properties = [
31
+ PROPERTIES = [
32
32
  :disclaimer,
33
33
  :domain, :domain_id,
34
34
  :referral_whois, :referral_url,
@@ -39,13 +39,6 @@ module Whois
39
39
  :nameservers,
40
40
  ]
41
41
 
42
- # Returns an array containing the name of all properties
43
- # that can be registered and should be implemented by
44
- # server-specific parsers.
45
- def self.properties
46
- @@properties
47
- end
48
-
49
42
  attr_reader :answer
50
43
 
51
44
 
@@ -77,9 +70,9 @@ module Whois
77
70
  private
78
71
 
79
72
  def method_missing(method, *args, &block)
80
- if Parser.properties.include?(method)
73
+ if PROPERTIES.include?(method)
81
74
  delegate_to_parsers(method, *args, &block)
82
- elsif Parser::METHODS.include?(method)
75
+ elsif METHODS.include?(method)
83
76
  delegate_to_parsers(method, *args, &block)
84
77
  else
85
78
  super
@@ -108,22 +101,45 @@ module Whois
108
101
  end
109
102
  end
110
103
 
111
- # Loops through all answer parts, for each parts tries to guess
112
- # the appropriate Whois::Answer::Parser::<parser> if it exists
104
+ # Protected: Loops through all answer parts, for each parts tries to guess
105
+ # the appropriate parser object whenever available,
113
106
  # and returns the final array of server-specific parsers.
114
107
  #
115
108
  # Parsers are initialized in reverse order for performance reason.
116
- # See also <tt>select_parser</tt>.
109
+ # See also <tt>#select_parser</tt>.
110
+ #
111
+ # Examples
117
112
  #
118
113
  # parser.parts
119
114
  # # => [whois.foo.com, whois.bar.com]
120
115
  # parser.parsers
121
- # # => [parser(whois.bar.com), parser(whois.foo.com)]
116
+ # # => [Whois::Answer::Parser::WhoisBarCom, Whois::Answer::Parser::WhoisFooCom]
122
117
  #
118
+ # Returns an Array of Class, where
119
+ # each item is the parts reverse-N specific parser Class.
120
+ # Each Class is expected to be a child of Whois::Answer::Parser::Base.
123
121
  def init_parsers
124
122
  answer.parts.reverse.map { |part| self.class.parser_for(part) }
125
123
  end
126
124
 
125
+ # Protected: Selects the first parser in <tt>#parsers</tt>
126
+ # where <tt>given</tt> matches <tt>status</tt>.
127
+ #
128
+ # property - The Symbol property to search for
129
+ # status - The Symbol status (default: :any)
130
+ #
131
+ #
132
+ # Examples
133
+ #
134
+ # select_parser(:nameservers)
135
+ # # => #<Whois::Answer::Parser::WhoisExampleCom>
136
+ #
137
+ # select_parser(:nameservers, :supported)
138
+ # # => nil
139
+ #
140
+ # Returns an instance of Whois::Answer::Parser::Base
141
+ # with the parser which satisfies given requirement,
142
+ # or nil the parser wasn't found.
127
143
  def select_parser(property, status = :any)
128
144
  parsers.each do |parser|
129
145
  return parser if parser.class.property_registered?(property, status)
@@ -132,30 +148,54 @@ module Whois
132
148
  end
133
149
 
134
150
 
135
- # Returns the proper <tt>Whois::Answer::Parser::Base</tt> instance
136
- # for given <tt>part</tt>.
137
- # The parser class depends on the <tt>Whois::Answer::Part</tt> host.
151
+ # Public: Returns the proper parser instance for given <tt>part</tt>.
152
+ # The parser class is selected according to the
153
+ # value of the <tt>#host</tt> attribute for given <tt>part</tt>.
154
+ #
155
+ # part - The Whois::Answer::Parser::Part to get the parser for
156
+ #
157
+ # Examples
158
+ #
159
+ # # Parser for a known host
160
+ # Parser.parser_for("whois.example.com")
161
+ # #<Whois::Answer::Parser::WhoisExampleCom>
162
+ #
163
+ # # Parser for an unknown host
164
+ # Parser.parser_for("missing.example.com")
165
+ # #<Whois::Answer::Parser::Blank>
166
+ #
167
+ # Returns an instance of the specific parser for given part.
168
+ # The instance is expected to be a child of Whois::Answer::Parser::Base.
138
169
  def self.parser_for(part)
139
170
  parser_klass(part.host).new(part)
140
171
  end
141
172
 
142
- # Detects the proper parser class according to given <tt>host</tt>
173
+ # Public: Detects the proper parser class according to given <tt>host</tt>
143
174
  # and returns the class constant.
144
- # If no parser exists for <tt>host</tt>, then returns a generic
145
- # <tt>Whois::Answer::Parser::Blank</tt>.
146
175
  #
147
176
  # This method autoloads missing parser classes. If you want to define
148
177
  # a custom parser, simple make sure the class is loaded in the Ruby
149
178
  # environment before this method is called.
150
179
  #
151
- # Parser.parser_klass("whois.missing.com")
180
+ # host - A String with the host
181
+ #
182
+ # Examples
183
+ #
184
+ # Parser.parser_klass("missing.example.com")
152
185
  # # => Whois::Answer::Parser::Blank
153
186
  #
154
- # class Whois::Answer::Parser::WhoisMissingCom
187
+ # # Define a custom parser for missing.example.com
188
+ # class Whois::Answer::Parser::MissingExampleCom
155
189
  # end
156
- # Parser.parser_klass("whois.missing.com")
157
- # # => Whois::Answer::Parser::WhoisMissingCom
158
190
  #
191
+ # Parser.parser_klass("missing.example.com")
192
+ # # => Whois::Answer::Parser::MissingExampleCom
193
+ #
194
+ # Returns an instance of Class representing the parser Class
195
+ # corresponding to <tt>host</tt>.
196
+ # If <tt>host</tt> doesn't have a specific parser implementation,
197
+ # then returns the Whois::Answer::Parser::Blank Class.
198
+ # The Class is expected to be a child of Whois::Answer::Parser::Base.
159
199
  def self.parser_klass(host)
160
200
  name = host_to_parser(host)
161
201
  Parser.const_defined?(name) || autoload(host)
@@ -166,26 +206,40 @@ module Whois
166
206
  Parser::Blank
167
207
  end
168
208
 
169
- # Converts <tt>host</tt> to a parser class name.
170
- # Note. Returns a <tt>String</tt>, not a <tt>Class</tt>.
209
+ # Public: Converts <tt>host</tt> to the corresponding parser class name.
210
+ #
211
+ # host - A String with the host
212
+ #
213
+ # Examples
171
214
  #
172
215
  # Parser.host_to_parser("whois.nic.it")
173
216
  # # => "WhoisNicIt"
174
217
  # Parser.host_to_parser("whois.nic-info.it")
175
218
  # # => "WhoisNicInfoIt"
176
219
  #
220
+ # Returns a String with the class name.
177
221
  def self.host_to_parser(host)
178
222
  host.to_s.
179
223
  gsub(/[.-]/, '_').
180
224
  gsub(/(?:^|_)(.)/) { $1.upcase }
181
225
  end
182
226
 
183
- # Requires the file at "whois/answer/parser/#{name}".
227
+ # Public: Requires the file at <tt>whois/answer/parser/#{name}</tt>.
228
+ #
229
+ # name - A string with the file name
230
+ #
231
+ # Returns nothing.
184
232
  def self.autoload(name)
185
233
  file = "whois/answer/parser/#{name}"
186
234
  require file
187
235
  end
188
236
 
237
+
238
+ def self.properties # :nodoc
239
+ Whois.deprecate("Whois::Answer::Parser.properties is deprecated. Use the Whois::Answer::Parser::PROPERTIES constant.")
240
+ PROPERTIES
241
+ end
242
+
189
243
  end
190
244
 
191
245
  end
@@ -216,7 +216,7 @@ module Whois
216
216
  end
217
217
 
218
218
 
219
- ::Whois::Answer::Parser.properties.each do |property|
219
+ Whois::Answer::Parser::PROPERTIES.each do |property|
220
220
  property_not_implemented(property)
221
221
  end
222
222
 
@@ -32,7 +32,7 @@ module Whois
32
32
  #
33
33
  class Blank < Base
34
34
 
35
- ::Whois::Answer::Parser.properties.each do |method|
35
+ Whois::Answer::Parser::PROPERTIES.each do |method|
36
36
  define_method(method) do
37
37
  raise ParserNotFound, "Unable to find a parser for the server `#{part.host}'"
38
38
  end
@@ -0,0 +1,191 @@
1
+ #
2
+ # = Ruby Whois
3
+ #
4
+ # An intelligent pure Ruby WHOIS client and parser.
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/base'
18
+
19
+
20
+ module Whois
21
+ class Answer
22
+ class Parser
23
+
24
+ #
25
+ # = whois.example.com parser
26
+ #
27
+ # Parser for the whois.example.com server.
28
+ #
29
+ class WhoisExampleCom < Base
30
+
31
+ # Public: Gets the registry disclaimer that comes with the answer.
32
+ #
33
+ # Returns a String with the disclaimer if available,
34
+ # <tt>nil</tt> otherwise.
35
+ property_supported :disclaimer do
36
+ @disclaimer ||= nil
37
+ end
38
+
39
+
40
+ # Public: Gets the domain name as stored by the registry.
41
+ #
42
+ # Returns a String with the domain name if available,
43
+ # <tt>nil</tt> otherwise.
44
+ property_supported :domain do
45
+ @domain ||= nil
46
+ end
47
+
48
+ # Public: Gets the unique domain ID as stored by the registry.
49
+ #
50
+ # Returns a String with the domain ID if available,
51
+ # <tt>nil</tt> otherwise.
52
+ property_supported :domain_id do
53
+ @domain_id ||= nil
54
+ end
55
+
56
+
57
+ # Public: Gets the record status or statuses.
58
+ #
59
+ # Returns a String/Array with the record status if available,
60
+ # <tt>nil</tt> otherwise.
61
+ property_supported :status do
62
+ @status ||= nil
63
+ end
64
+
65
+ # Public: Checks whether this record is available.
66
+ #
67
+ # Returns true/false depending whether this record is available.
68
+ property_supported :available? do
69
+ @available ||= nil
70
+ end
71
+
72
+ # Public: Checks whether this record is registered.
73
+ #
74
+ # Returns true/false depending this record is available.
75
+ property_supported :registered? do
76
+ @registered ||= nil
77
+ end
78
+
79
+
80
+ # Public: Gets the date the record was created,
81
+ # according to the registry answer.
82
+ #
83
+ # Returns a Time object representing the date the record was created or
84
+ # <tt>nil</tt> otherwise.
85
+ property_supported :created_on do
86
+ @created_on ||= nil
87
+ end
88
+
89
+ # Public: Gets the date the record was last updated,
90
+ # according to the registry answer.
91
+ #
92
+ # Returns a Time object representing the date the record was last updated or
93
+ # <tt>nil</tt> if not available.
94
+ property_supported :updated_on do
95
+ @updated_on ||= nil
96
+ end
97
+
98
+ # Public: Gets the date the record is set to expire,
99
+ # according to the registry answer.
100
+ #
101
+ # Returns a Time object representing the date the record is set to expire or
102
+ # <tt>nil</tt> if not available.
103
+ property_supported :expires_on do
104
+ @expires_on ||= nil
105
+ end
106
+
107
+
108
+ # Public: Gets the registrar object containing the registrar details
109
+ # extracted from the registry answer.
110
+ #
111
+ # Returns an instance of <tt>Whois::Answer::Registrar</tt> representing the registrar or
112
+ # <tt>nil</tt> if not available.
113
+ property_supported :registrar do
114
+ @registrar ||= nil
115
+ end
116
+
117
+
118
+ # Public: Gets the registrant contact object containing the details of the record owner
119
+ # extracted from the registry answer.
120
+ #
121
+ # Returns an instance of <tt>Whois::Answer::Contact</tt> representing the registrant contact or
122
+ # <tt>nil</tt> if not available.
123
+ property_supported :registrant_contact do
124
+ @registrant_contact ||= nil
125
+ end
126
+
127
+ # Public: Gets the administrative contact object containing the details of the record administrator
128
+ # extracted from the registry answer.
129
+ #
130
+ # Returns an instance of <tt>Whois::Answer::Contact</tt> representing the administrative contact or
131
+ # <tt>nil</tt> if not available.
132
+ property_supported :admin_contact do
133
+ @admin_contact ||= nil
134
+ end
135
+
136
+ # Public: Gets the technical contact object containing the details of the technical representative
137
+ # extracted from the registry answer.
138
+ #
139
+ # Returns an instance of <tt>Whois::Answer::Contact</tt> representing the technical contact or
140
+ # <tt>nil</tt> if not available.
141
+ property_supported :technical_contact do
142
+ @technical_contact ||= nil
143
+ end
144
+
145
+
146
+ # Public: Gets the list of name server entries for this record,
147
+ # extracted from the registry answer.
148
+ #
149
+ # Examples
150
+ #
151
+ # nameserver
152
+ # # => []
153
+ # nameserver
154
+ # # => ["ns2.google.com", "ns1.google.com", "ns3.google.com"]
155
+ #
156
+ #
157
+ # Returns an Array of lower case String where each String is a name server entry,
158
+ # an empty Array if no name server was found.
159
+ property_supported :nameservers do
160
+ @nameservers ||= []
161
+ end
162
+
163
+
164
+ # Public: Checks whether this answer is different than <tt>other</tt>.
165
+ #
166
+ # Comparing the Answer contents is not always as trivial as it seems.
167
+ # Whois servers sometimes inject dynamic method into the whois answer such as
168
+ # the timestamp the request was generated.
169
+ # This causes two answers to be different even if they actually should be considered equal
170
+ # because the registry data didn't change.
171
+ #
172
+ # This method should provide a bulletproof way to detect whether this answer
173
+ # changed if compared with <tt>other</tt>.
174
+ #
175
+ # Returns true/false depending whether this answer is different than <tt>other</tt>.
176
+ property_supported :changed? do |other|
177
+ !unchanged?(other)
178
+ end
179
+
180
+ # Public: The opposite of <tt>#changed?</tt>.
181
+ #
182
+ # Returns true/false depending whether this answer is not different than <tt>other</tt>.
183
+ property_supported :unchanged? do |other|
184
+ false
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+ end
191
+ end