whois 2.6.2 → 2.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.yardopts +1 -1
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +11 -13
  4. data/lib/whois.rb +2 -2
  5. data/lib/whois/errors.rb +1 -1
  6. data/lib/whois/record.rb +49 -43
  7. data/lib/whois/record/parser.rb +102 -102
  8. data/lib/whois/record/parser/base.rb +4 -4
  9. data/lib/whois/record/parser/whois.aero.rb +4 -0
  10. data/lib/whois/record/parser/whois.ati.tn.rb +1 -1
  11. data/lib/whois/record/parser/whois.audns.net.au.rb +1 -1
  12. data/lib/whois/record/parser/whois.cira.ca.rb +1 -1
  13. data/lib/whois/record/parser/whois.dns.hr.rb +1 -1
  14. data/lib/whois/record/parser/whois.dreamhost.com.rb +1 -1
  15. data/lib/whois/record/parser/whois.enom.com.rb +1 -1
  16. data/lib/whois/record/parser/whois.fi.rb +1 -1
  17. data/lib/whois/record/parser/whois.nc.rb +1 -1
  18. data/lib/whois/record/parser/whois.networksolutions.com.rb +1 -1
  19. data/lib/whois/record/parser/whois.nic.lk.rb +1 -1
  20. data/lib/whois/record/parser/whois.registry.om.rb +1 -1
  21. data/lib/whois/record/parser/whois.registrypro.pro.rb +5 -50
  22. data/lib/whois/record/parser/whois.rnids.rs.rb +1 -1
  23. data/lib/whois/record/parser/whois.sx.rb +1 -1
  24. data/lib/whois/record/parser/whois.ua.rb +2 -2
  25. data/lib/whois/record/scanners/whois.ati.tn.rb +1 -1
  26. data/lib/whois/record/scanners/whois.audns.net.au.rb +1 -1
  27. data/lib/whois/record/scanners/whois.centralnic.com.rb +1 -1
  28. data/lib/whois/record/scanners/whois.cira.ca.rb +1 -1
  29. data/lib/whois/record/scanners/whois.dns.hr.rb +1 -1
  30. data/lib/whois/record/scanners/whois.nc.rb +1 -1
  31. data/lib/whois/record/scanners/whois.registry.om.rb +1 -1
  32. data/lib/whois/record/scanners/whois.rnids.rs.rb +1 -1
  33. data/lib/whois/record/scanners/whois.sx.rb +1 -1
  34. data/lib/whois/server.rb +9 -5
  35. data/lib/whois/server/adapters/base.rb +3 -3
  36. data/lib/whois/version.rb +1 -1
  37. data/spec/fixtures/responses/whois.aero/status_registered.expected +36 -36
  38. data/spec/fixtures/responses/whois.registrypro.pro/status_available.expected +34 -0
  39. data/spec/fixtures/responses/whois.registrypro.pro/status_available.txt +1 -20
  40. data/spec/fixtures/responses/whois.registrypro.pro/status_registered.expected +87 -9
  41. data/spec/fixtures/responses/whois.registrypro.pro/status_registered.txt +94 -55
  42. data/spec/fixtures/responses/whois.ua/property_created_at_outofrange.expected +2 -0
  43. data/spec/fixtures/responses/whois.ua/property_created_at_outofrange.txt +93 -0
  44. data/spec/tlds +1 -1
  45. data/spec/whois/record/parser/responses/whois.aero/status_registered_spec.rb +36 -36
  46. data/spec/whois/record/parser/responses/whois.registrypro.pro/status_available_spec.rb +48 -0
  47. data/spec/whois/record/parser/responses/whois.registrypro.pro/status_registered_spec.rb +101 -9
  48. data/spec/whois/record/parser/responses/whois.ua/property_created_at_outofrange_spec.rb +29 -0
  49. data/spec/whois/record/parser_spec.rb +4 -0
  50. data/spec/whois/server_spec.rb +11 -2
  51. data/whois.gemspec +3 -3
  52. metadata +5 -2
data/.yardopts CHANGED
@@ -1,2 +1,2 @@
1
- --readme README.rdoc
1
+ --readme README.md
2
2
  --title 'Whois API Documentation'
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## Release 2.6.3
5
+
6
+ * NEW: whois.registrypro.pro is now a full parser.
7
+
8
+ * FIXED: In some cases the parser class is not correctly detected from hostname (GH-173). [Thanks @JustinCampbell]
9
+
10
+ * FIXED: whois.ua parser raises ArgumentError when the created_on object invalid data.
11
+
12
+ * FIXED: Whois::Server may occasionally raise an error trying to resolve an IPv6 matching query object (GH-174). [Thanks @aeden].
13
+
14
+ * CHANGED: Updated whois.registrypro.pro parser to the new response format.
15
+
16
+
4
17
  ## Release 2.6.2
5
18
 
6
19
  * SERVER: Added .SX TLD server (GH-170).
data/README.md CHANGED
@@ -6,11 +6,20 @@
6
6
 
7
7
  *Whois* is a OS-independent library and doesn't require any external binaries or C libraries: it is a 100% Ruby software.
8
8
 
9
- This library was developed to power [RoboDomain](https://www.robodomain.com) and, since July 2009, it ran more than thousands requests.
9
+ This library was developed to power [RoboDomain](https://www.robodomain.com/) and [RoboWhois](http://www.robowhois.com/). It has been performing queries in production since July 2009.
10
10
 
11
11
  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.
12
12
 
13
13
 
14
+ ## Donations
15
+
16
+ [Support Whois at Pledgie](http://www.pledgie.com/campaigns/11383).
17
+
18
+ <a href='http://www.pledgie.com/campaigns/11383'><img alt='Click here to lend your support to: whois and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/11383.png?skin_name=chrome' border='0' /></a>
19
+
20
+ *Whois* is free software, but it costs money to write, test, and distribute it. You can support the development by sending a donation. **Any amount, even $5, is greatly appreciated**.
21
+
22
+
14
23
  ## Features
15
24
 
16
25
  * Ability to query registry data for [IPv4, IPv6, TLDs, and domain names](http://www.ruby-whois.org/manual/usage.html#usage-objects)
@@ -183,15 +192,6 @@ Pull requests are very welcome! Please include spec and/or feature coverage for
183
192
  Report issues or feature requests to [GitHub Issues](https://github.com/weppos/whois/issues).
184
193
 
185
194
 
186
- ## Donations
187
-
188
- [Support Whois at Pledgie](http://www.pledgie.com/campaigns/11383).
189
-
190
- <a href='http://www.pledgie.com/campaigns/11383'><img alt='Click here to lend your support to: whois and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/11383.png?skin_name=chrome' border='0' /></a>
191
-
192
- Whois is free software, but it costs money to write, test, and distribute it. You can support the development by sending a donation. **Any amount, even $5, is greatly appreciated**.
193
-
194
-
195
195
  ## More
196
196
 
197
197
  - [Homepage](http://www.ruby-whois.org/)
@@ -207,6 +207,4 @@ See the [CHANGELOG](CHANGELOG.md) file for details.
207
207
 
208
208
  ## License
209
209
 
210
- Copyright (c) 2009-2012 Simone Carletti.
211
-
212
- This is Free Software distributed under the MIT license.
210
+ Copyright (c) 2009-2012 Simone Carletti. This is Free Software distributed under the MIT license.
data/lib/whois.rb CHANGED
@@ -112,7 +112,7 @@ module Whois
112
112
  # @param [String] message The message to display.
113
113
  # @return [void]
114
114
  #
115
- # @api internal
115
+ # @api private
116
116
  # @private
117
117
  def deprecate(message = nil, callstack = caller)
118
118
  message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
@@ -127,7 +127,7 @@ module Whois
127
127
  # @param [String] message
128
128
  # @return [void]
129
129
  #
130
- # @api internal
130
+ # @api private
131
131
  # @private
132
132
  def bug!(error, message)
133
133
  raise error, message.dup <<
data/lib/whois/errors.rb CHANGED
@@ -132,7 +132,7 @@ module Whois
132
132
 
133
133
  # Raised when attempting to access a property when the response is unavailable.
134
134
  #
135
- # @since 2.0.3
135
+ # @since 2.0.3
136
136
  # @see Whois::Record::Parser::Base#response_unavailable?
137
137
  class ResponseIsUnavailable < ResponseError
138
138
  end
data/lib/whois/record.rb CHANGED
@@ -39,6 +39,7 @@ module Whois
39
39
  # for {Parser::PROPERTIES} and {Parser::METHODS}.
40
40
  #
41
41
  # @return [Boolean]
42
+ #
42
43
  def respond_to?(symbol, include_private = false)
43
44
  super || Parser::PROPERTIES.include?(symbol) || Parser::METHODS.include?(symbol)
44
45
  end
@@ -46,6 +47,7 @@ module Whois
46
47
  # Returns a String representation of this record.
47
48
  #
48
49
  # @return [String] The record content.
50
+ #
49
51
  def to_s
50
52
  content.to_s
51
53
  end
@@ -53,6 +55,7 @@ module Whois
53
55
  # Returns a human-readable representation of this record.
54
56
  #
55
57
  # @return [String] The result of {#inspect} on content.
58
+ #
56
59
  def inspect
57
60
  content.inspect
58
61
  end
@@ -62,6 +65,7 @@ module Whois
62
65
  #
63
66
  # @param [Whois::Record] other The record to compare.
64
67
  # @return [Boolean]
68
+ #
65
69
  def ==(other)
66
70
  if equal?(other)
67
71
  true
@@ -78,7 +82,7 @@ module Whois
78
82
  # Invokes {#match} on record {#content}
79
83
  # and returns the match as <tt>MatchData</tt> or <tt>nil</tt>.
80
84
  #
81
- # @param [Regexp, String] match
85
+ # @param [Regexp, String] pattern The regex pattern to match.
82
86
  # @return [MatchData] If pattern matches #content
83
87
  # @return [nil] If pattern doesn't match #content
84
88
  #
@@ -91,7 +95,7 @@ module Whois
91
95
  # Invokes {#match} and returns <tt>true</tt> if <tt>pattern</tt>
92
96
  # matches {#content}, <tt>false</tt> otherwise.
93
97
  #
94
- # @param [Regexp, String] match
98
+ # @param [Regexp, String] pattern The regex pattern to match.
95
99
  # @return [Boolean]
96
100
  #
97
101
  # @see #match
@@ -122,6 +126,7 @@ module Whois
122
126
  # Lazy-loads and returns the parser proxy for current record.
123
127
  #
124
128
  # @return [Whois::Record::Parser]
129
+ #
125
130
  def parser
126
131
  @parser ||= Parser.new(self)
127
132
  end
@@ -145,6 +150,7 @@ module Whois
145
150
  # along with corresponding values.
146
151
  #
147
152
  # @return [{ Symbol => Object }]
153
+ #
148
154
  def properties
149
155
  hash = {}
150
156
  Parser::PROPERTIES.each { |property| hash[property] = send(property) }
@@ -288,54 +294,54 @@ module Whois
288
294
  # @endgroup
289
295
 
290
296
 
291
- private
297
+ private
292
298
 
293
- # @api internal
294
- def self.define_property_method(method)
295
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
296
- def #{method}(*args, &block)
297
- if property_supported?(:#{method})
298
- parser.#{method}(*args, &block)
299
- end
299
+ # @api private
300
+ def self.define_property_method(method)
301
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
302
+ def #{method}(*args, &block)
303
+ if property_supported?(:#{method})
304
+ parser.#{method}(*args, &block)
300
305
  end
301
- RUBY
302
- end
303
-
304
- # @api internal
305
- def self.define_method_method(method)
306
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
307
- def #{method}(*args, &block)
308
- if parser.respond_to?(:#{method})
309
- parser.#{method}(*args, &block)
310
- end
311
- end
312
- RUBY
313
- end
306
+ end
307
+ RUBY
308
+ end
314
309
 
315
- # @api internal
316
- def self.define_question_method(method)
317
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
318
- def #{method}?
319
- !#{method}.nil?
310
+ # @api private
311
+ def self.define_method_method(method)
312
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
313
+ def #{method}(*args, &block)
314
+ if parser.respond_to?(:#{method})
315
+ parser.#{method}(*args, &block)
320
316
  end
321
- RUBY
322
- end
317
+ end
318
+ RUBY
319
+ end
323
320
 
324
- # Delegates all method calls to the internal parser.
325
- def method_missing(method, *args, &block)
326
- if Parser::PROPERTIES.include?(method)
327
- self.class.define_property_method(method)
328
- send(method, *args, &block)
329
- elsif Parser::METHODS.include?(method)
330
- self.class.define_method_method(method)
331
- send(method, *args, &block)
332
- elsif method.to_s =~ /([a-z_]+)\?/ and (Parser::PROPERTIES + Parser::METHODS).include?($1.to_sym)
333
- self.class.define_question_method($1)
334
- send(method)
335
- else
336
- super
321
+ # @api private
322
+ def self.define_question_method(method)
323
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
324
+ def #{method}?
325
+ !#{method}.nil?
337
326
  end
327
+ RUBY
328
+ end
329
+
330
+ # Delegates all method calls to the internal parser.
331
+ def method_missing(method, *args, &block)
332
+ if Parser::PROPERTIES.include?(method)
333
+ self.class.define_property_method(method)
334
+ send(method, *args, &block)
335
+ elsif Parser::METHODS.include?(method)
336
+ self.class.define_method_method(method)
337
+ send(method, *args, &block)
338
+ elsif method.to_s =~ /([a-z_]+)\?/ and (Parser::PROPERTIES + Parser::METHODS).include?($1.to_sym)
339
+ self.class.define_question_method($1)
340
+ send(method)
341
+ else
342
+ super
338
343
  end
344
+ end
339
345
 
340
346
  end
341
347
 
@@ -114,7 +114,7 @@ module Whois
114
114
  # # => "WhoisNicInfoIt"
115
115
  #
116
116
  def self.host_to_parser(host)
117
- host.to_s.
117
+ host.to_s.downcase.
118
118
  gsub(/[.-]/, '_').
119
119
  gsub(/(?:^|_)(.)/) { $1.upcase }
120
120
  end
@@ -136,7 +136,7 @@ module Whois
136
136
 
137
137
  # Initializes and return a new parser from +record+.
138
138
  #
139
- # @param [Whois::Record]
139
+ # @param [Whois::Record] record
140
140
  #
141
141
  def initialize(record)
142
142
  @record = record
@@ -262,119 +262,119 @@ module Whois
262
262
  # @endgroup
263
263
 
264
264
 
265
- private
265
+ private
266
266
 
267
- # @api internal
268
- def self.define_missing_method(method)
269
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
270
- def #{method}(*args, &block)
271
- delegate_to_parsers(:#{method}, *args, &block)
272
- end
273
- RUBY
274
- end
275
-
276
- def method_missing(method, *args, &block)
277
- if PROPERTIES.include?(method)
278
- self.class.define_missing_method(method)
279
- send(method, *args, &block)
280
- elsif METHODS.include?(method)
281
- self.class.define_missing_method(method)
282
- send(method, *args, &block)
283
- else
284
- super
267
+ # @api private
268
+ def self.define_missing_method(method)
269
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
270
+ def #{method}(*args, &block)
271
+ delegate_to_parsers(:#{method}, *args, &block)
285
272
  end
286
- end
273
+ RUBY
274
+ end
287
275
 
288
- def delegate_to_parsers(method, *args, &block)
289
- # Raise an error without any parser
290
- if parsers.empty?
291
- raise ParserError, "Unable to select a parser because the record is empty"
292
-
293
- # Select a parser where the property is supported
294
- # and call the method.
295
- elsif parser = select_parser(method, :supported)
296
- parser.send(method, *args, &block)
297
-
298
- # Select a parser where the property is defined but not supported
299
- # and call the method.
300
- # The call is expected to raise an exception.
301
- elsif parser = select_parser(method, :not_supported)
302
- parser.send(method, *args, &block)
303
-
304
- # The property is not supported nor defined.
305
- else
306
- raise PropertyNotAvailable, "Unable to find a parser for `#{method}'"
307
- end
276
+ def method_missing(method, *args, &block)
277
+ if PROPERTIES.include?(method)
278
+ self.class.define_missing_method(method)
279
+ send(method, *args, &block)
280
+ elsif METHODS.include?(method)
281
+ self.class.define_missing_method(method)
282
+ send(method, *args, &block)
283
+ else
284
+ super
308
285
  end
286
+ end
309
287
 
310
- # Loops through all record parts, for each part
311
- # tries to guess the appropriate parser object whenever available,
312
- # and returns the final array of server-specific parsers.
313
- #
314
- # Parsers are initialized in reverse order for performance reason.
315
- #
316
- # @return [Array<Class>] An array of Class,
317
- # where each item is the parts reverse-N specific parser {Class}.
318
- # Each {Class} is expected to be a child of {Whois::Record::Parser::Base}.
319
- #
320
- # @example
321
- #
322
- # parser.parts
323
- # # => [whois.foo.com, whois.bar.com]
324
- #
325
- # parser.parsers
326
- # # => [Whois::Record::Parser::WhoisBarCom, Whois::Record::Parser::WhoisFooCom]
327
- #
328
- # @see Whois::Record::Parser#select_parser
329
- #
330
- def init_parsers
331
- record.parts.reverse.map { |part| self.class.parser_for(part) }
288
+ def delegate_to_parsers(method, *args, &block)
289
+ # Raise an error without any parser
290
+ if parsers.empty?
291
+ raise ParserError, "Unable to select a parser because the record is empty"
292
+
293
+ # Select a parser where the property is supported
294
+ # and call the method.
295
+ elsif parser = select_parser(method, :supported)
296
+ parser.send(method, *args, &block)
297
+
298
+ # Select a parser where the property is defined but not supported
299
+ # and call the method.
300
+ # The call is expected to raise an exception.
301
+ elsif parser = select_parser(method, :not_supported)
302
+ parser.send(method, *args, &block)
303
+
304
+ # The property is not supported nor defined.
305
+ else
306
+ raise PropertyNotAvailable, "Unable to find a parser for `#{method}'"
332
307
  end
308
+ end
333
309
 
334
- # Selects the first parser in {#parsers}
335
- # where given property matches <tt>status</tt>.
336
- #
337
- # @param [Symbol] property The property to search for.
338
- # @param [Symbol] status The status value.
339
- #
340
- # @return [Whois::Record::Parser::Base]
341
- # The parser which satisfies given requirement.
342
- # @return [nil]
343
- # If the parser wasn't found.
344
- #
345
- # @example
346
- #
347
- # select_parser(:nameservers)
348
- # # => #<Whois::Record::Parser::WhoisExampleCom>
349
- #
350
- # select_parser(:nameservers, :supported)
351
- # # => nil
352
- #
353
- def select_parser(property, status = :any)
354
- parsers.each do |parser|
355
- return parser if parser.class.property_registered?(property, status)
356
- end
357
- nil
310
+ # Loops through all record parts, for each part
311
+ # tries to guess the appropriate parser object whenever available,
312
+ # and returns the final array of server-specific parsers.
313
+ #
314
+ # Parsers are initialized in reverse order for performance reason.
315
+ #
316
+ # @return [Array<Class>] An array of Class,
317
+ # where each item is the parts reverse-N specific parser {Class}.
318
+ # Each {Class} is expected to be a child of {Whois::Record::Parser::Base}.
319
+ #
320
+ # @example
321
+ #
322
+ # parser.parts
323
+ # # => [whois.foo.com, whois.bar.com]
324
+ #
325
+ # parser.parsers
326
+ # # => [Whois::Record::Parser::WhoisBarCom, Whois::Record::Parser::WhoisFooCom]
327
+ #
328
+ # @see Whois::Record::Parser#select_parser
329
+ #
330
+ def init_parsers
331
+ record.parts.reverse.map { |part| self.class.parser_for(part) }
332
+ end
333
+
334
+ # Selects the first parser in {#parsers}
335
+ # where given property matches <tt>status</tt>.
336
+ #
337
+ # @param [Symbol] property The property to search for.
338
+ # @param [Symbol] status The status value.
339
+ #
340
+ # @return [Whois::Record::Parser::Base]
341
+ # The parser which satisfies given requirement.
342
+ # @return [nil]
343
+ # If the parser wasn't found.
344
+ #
345
+ # @example
346
+ #
347
+ # select_parser(:nameservers)
348
+ # # => #<Whois::Record::Parser::WhoisExampleCom>
349
+ #
350
+ # select_parser(:nameservers, :supported)
351
+ # # => nil
352
+ #
353
+ def select_parser(property, status = :any)
354
+ parsers.each do |parser|
355
+ return parser if parser.class.property_registered?(property, status)
358
356
  end
357
+ nil
358
+ end
359
359
 
360
- # @api internal
361
- def all_in_parallel?(*args)
362
- count = args.first.size
363
- index = 0
360
+ # @api private
361
+ def all_in_parallel?(*args)
362
+ count = args.first.size
363
+ index = 0
364
364
 
365
- while index < count
366
- return false unless yield(*args.map { |arg| arg[index] })
367
- index += 1
368
- end
369
- true
365
+ while index < count
366
+ return false unless yield(*args.map { |arg| arg[index] })
367
+ index += 1
370
368
  end
369
+ true
370
+ end
371
371
 
372
- # @api internal
373
- def any_is?(collection, symbol)
374
- collection.any? { |item| item.is(symbol) }
375
- end
372
+ # @api private
373
+ def any_is?(collection, symbol)
374
+ collection.any? { |item| item.is(symbol) }
375
+ end
376
376
 
377
377
  end
378
378
 
379
379
  end
380
- end
380
+ end