whois 0.5.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/CHANGELOG.rdoc +55 -0
  2. data/Manifest +43 -8
  3. data/README.rdoc +53 -20
  4. data/lib/whois.rb +69 -1
  5. data/lib/whois/answer.rb +126 -0
  6. data/lib/whois/answer/contact.rb +55 -0
  7. data/lib/whois/answer/parser.rb +110 -0
  8. data/lib/whois/answer/parser/README.rdoc +21 -0
  9. data/lib/whois/answer/parser/base.rb +144 -0
  10. data/lib/whois/answer/parser/blank.rb +45 -0
  11. data/lib/whois/answer/parser/whois.crsnic.net.rb +209 -0
  12. data/lib/whois/answer/parser/whois.denic.de.rb +202 -0
  13. data/lib/whois/answer/parser/whois.nic.it.rb +330 -0
  14. data/lib/whois/answer/parser/whois.publicinterestregistry.net.rb +232 -0
  15. data/lib/whois/answer/part.rb +35 -0
  16. data/lib/whois/answer/registrar.rb +42 -0
  17. data/lib/whois/answer/super_struct.rb +57 -0
  18. data/lib/whois/client.rb +6 -0
  19. data/lib/whois/definitions/tlds.rb +2 -2
  20. data/lib/whois/errors.rb +25 -8
  21. data/lib/whois/server.rb +0 -1
  22. data/lib/whois/server/adapters/afilias.rb +5 -5
  23. data/lib/whois/server/adapters/base.rb +31 -4
  24. data/lib/whois/server/adapters/formatted.rb +3 -1
  25. data/lib/whois/server/adapters/none.rb +20 -1
  26. data/lib/whois/server/adapters/pir.rb +5 -5
  27. data/lib/whois/server/adapters/standard.rb +13 -2
  28. data/lib/whois/server/adapters/verisign.rb +5 -5
  29. data/lib/whois/server/adapters/web.rb +15 -0
  30. data/lib/whois/version.rb +2 -2
  31. data/lib/whois/whois.rb +2 -2
  32. data/test/answer/parser/base_test.rb +27 -0
  33. data/test/answer/parser/blank_test.rb +19 -0
  34. data/test/answer/parser/whois_crsnic_net_test.rb +175 -0
  35. data/test/answer/parser/whois_denic_de_test.rb +209 -0
  36. data/test/answer/parser/whois_nic_it_test.rb +255 -0
  37. data/test/answer/parser/whois_publicinterestregistry_net_test.rb +210 -0
  38. data/test/answer/parser_test.rb +77 -0
  39. data/test/answer_test.rb +99 -0
  40. data/test/client_test.rb +3 -3
  41. data/test/integration_test.rb +31 -0
  42. data/test/{adapters → server/adapters}/afilias_test.rb +10 -5
  43. data/test/server/adapters/base_test.rb +15 -0
  44. data/test/server/adapters/formatted_test.rb +26 -0
  45. data/test/{adapters → server/adapters}/none_test.rb +0 -0
  46. data/test/{adapters → server/adapters}/not_implemented_test.rb +0 -0
  47. data/test/{adapters → server/adapters}/pir_test.rb +10 -5
  48. data/test/server/adapters/standard_test.rb +29 -0
  49. data/test/{adapters → server/adapters}/verisign_test.rb +10 -5
  50. data/test/{adapters → server/adapters}/web_test.rb +0 -0
  51. data/test/server_test.rb +5 -1
  52. data/test/testcases/responses/super_struct_test.rb +25 -0
  53. data/test/testcases/responses/whois.crsnic.net/available.txt +43 -0
  54. data/test/testcases/responses/whois.crsnic.net/registered.txt +57 -0
  55. data/test/testcases/responses/whois.denic.de/available.txt +30 -0
  56. data/test/testcases/responses/whois.denic.de/registered.txt +77 -0
  57. data/test/testcases/responses/whois.nic.it/available.txt +2 -0
  58. data/test/testcases/responses/{it.txt → whois.nic.it/registered.txt} +1 -0
  59. data/test/testcases/responses/whois.nic.it/status_active.txt +53 -0
  60. data/test/testcases/responses/whois.nic.it/status_available.txt +2 -0
  61. data/test/testcases/responses/whois.publicinterestregistry.net/available.txt +1 -0
  62. data/test/testcases/responses/whois.publicinterestregistry.net/registered.txt +85 -0
  63. data/test/whois_test.rb +23 -1
  64. data/utils/bm_delegation_vs_inheritance.rb +150 -0
  65. data/whois.gemspec +6 -6
  66. metadata +78 -18
  67. data/test/adapters/standard_test.rb +0 -23
@@ -17,7 +17,6 @@
17
17
  require 'ipaddr'
18
18
  require 'whois/server/adapters/base'
19
19
  require 'whois/server/adapters/afilias'
20
- require 'whois/server/adapters/arpa'
21
20
  require 'whois/server/adapters/formatted'
22
21
  require 'whois/server/adapters/none'
23
22
  require 'whois/server/adapters/not_implemented'
@@ -22,11 +22,11 @@ module Whois
22
22
 
23
23
  def request(qstring)
24
24
  response = ask_the_socket(qstring, "whois.afilias-grs.info", DEFAULT_WHOIS_PORT)
25
- endpoint = extract_referral(response)
26
- if endpoint
27
- response + "\n" + ask_the_socket(qstring, endpoint, DEFAULT_WHOIS_PORT)
28
- else
29
- response
25
+ append_to_buffer response, "whois.afilias-grs.info"
26
+
27
+ if endpoint = extract_referral(response)
28
+ response = ask_the_socket(qstring, endpoint, DEFAULT_WHOIS_PORT)
29
+ append_to_buffer response, endpoint
30
30
  end
31
31
  end
32
32
 
@@ -14,38 +14,65 @@
14
14
  #++
15
15
 
16
16
 
17
+ require 'whois/answer/part'
18
+ require 'whois/answer'
19
+
20
+
17
21
  module Whois
18
22
  class Server
19
23
  module Adapters
20
24
 
21
25
  class Base
22
26
 
27
+ # Default Whois request port.
23
28
  DEFAULT_WHOIS_PORT = 43
24
29
 
25
30
  attr_reader :type
26
31
  attr_reader :allocation
27
32
  attr_reader :host
28
33
  attr_reader :options
34
+ attr_reader :buffer
29
35
 
30
-
31
36
  def initialize(type, allocation, host, options = {})
32
37
  @type = type
33
38
  @allocation = allocation
34
39
  @host = host
35
40
  @options = options || {}
36
41
  end
37
-
42
+
43
+ # Performs a Whois query for <tt>qstring</tt>
44
+ # using current server adapter and returns a <tt>Whois::Response</tt>
45
+ # instance with the result of the request.
46
+ #
47
+ # server.query("google.com")
48
+ # # => Whois::Response
49
+ #
38
50
  def query(qstring)
39
- request(qstring)
51
+ with_buffer do |buffer|
52
+ request(qstring)
53
+ Answer.new(self, buffer)
54
+ end
40
55
  end
41
56
 
42
57
  def request(qstring)
43
58
  raise NotImplementedError
44
59
  end
45
60
 
46
-
61
+
47
62
  protected
48
63
 
64
+ def with_buffer(&block)
65
+ @buffer = []
66
+ result = yield(@buffer)
67
+ # @buffer = []
68
+ # result
69
+ end
70
+
71
+ # Store an answer part in <tt>@buffer</tt>.
72
+ def append_to_buffer(response, host)
73
+ @buffer << ::Whois::Answer::Part.new(response, host)
74
+ end
75
+
49
76
  def query_the_socket(qstring, host, port = nil)
50
77
  ask_the_socket(qstring, host, port || options[:port] || DEFAULT_WHOIS_PORT)
51
78
  end
@@ -21,7 +21,9 @@ module Whois
21
21
  class Formatted < Base
22
22
 
23
23
  def request(qstring)
24
- query_the_socket(sprintf(options[:format], qstring), host)
24
+ options[:format] || raise(ServerError, "Missing mandatory :format option for adapter `Formatted'")
25
+ response = query_the_socket(sprintf(options[:format], qstring), host)
26
+ append_to_buffer response, host
25
27
  end
26
28
 
27
29
  end
@@ -17,9 +17,28 @@
17
17
  module Whois
18
18
  class Server
19
19
  module Adapters
20
-
20
+
21
+ #
22
+ # = None Adapter
23
+ #
24
+ # Special adapter intended to be used when a WHOIS interface
25
+ # doesn't exist for given query.
26
+ # For example, the domain authority for some TLD doesn't offer
27
+ # any way to query for WHOIS data.
28
+ #
29
+ # In case the authority provides only a web based interface,
30
+ # you should use the <tt>Whois::Server::Adapters::Web</tt> adapter.
31
+ #
32
+ # Every query for an object associated to a <tt>Whois::Server::Adapters::None</tt>
33
+ # adapter raises a <tt>Whois::NoInterfaceError</tt> exception.
34
+ #
21
35
  class None < Base
22
36
 
37
+ # Always raises a <tt>Whois::NoInterfaceError</tt> exception.
38
+ #
39
+ # ==== Raises
40
+ # NoInterfaceError:: for every request
41
+ #
23
42
  def request(qstring)
24
43
  raise NoInterfaceError, "This `#{type}' has no whois server"
25
44
  end
@@ -22,11 +22,11 @@ module Whois
22
22
 
23
23
  def request(qstring)
24
24
  response = ask_the_socket("FULL #{qstring}", "whois.publicinterestregistry.net", DEFAULT_WHOIS_PORT)
25
- endpoint = extract_referral(response)
26
- if endpoint
27
- response + "\n" + ask_the_socket(qstring, endpoint, DEFAULT_WHOIS_PORT)
28
- else
29
- response
25
+ append_to_buffer response, "whois.publicinterestregistry.net"
26
+
27
+ if endpoint = extract_referral(response)
28
+ response = ask_the_socket(qstring, endpoint, DEFAULT_WHOIS_PORT)
29
+ append_to_buffer response, endpoint
30
30
  end
31
31
  end
32
32
 
@@ -17,11 +17,22 @@
17
17
  module Whois
18
18
  class Server
19
19
  module Adapters
20
-
20
+
21
+ #
22
+ # = Standard Adapter
23
+ #
24
+ # Provides ability to query standard WHOIS interfaces.
25
+ # A standard WHOIS interface accepts socket requests containing the name of the domain
26
+ # and returns a single response containing the answer for given query.
27
+ #
28
+ # By default the interface should listen on port 43.
29
+ # This adapter also supports an optional port number.
30
+ #
21
31
  class Standard < Base
22
32
 
23
33
  def request(qstring)
24
- query_the_socket(qstring, host)
34
+ response = query_the_socket(qstring, host)
35
+ append_to_buffer response, host
25
36
  end
26
37
 
27
38
  end
@@ -22,11 +22,11 @@ module Whois
22
22
 
23
23
  def request(qstring)
24
24
  response = ask_the_socket("=#{qstring}", host, DEFAULT_WHOIS_PORT)
25
- endpoint = extract_referral(response)
26
- if endpoint
27
- response + "\n" + ask_the_socket(qstring, endpoint, DEFAULT_WHOIS_PORT)
28
- else
29
- response
25
+ append_to_buffer response, host
26
+
27
+ if endpoint = extract_referral(response)
28
+ response = ask_the_socket(qstring, endpoint, DEFAULT_WHOIS_PORT)
29
+ append_to_buffer response, endpoint
30
30
  end
31
31
  end
32
32
 
@@ -18,8 +18,23 @@ module Whois
18
18
  class Server
19
19
  module Adapters
20
20
 
21
+ #
22
+ # = Web Adapter
23
+ #
24
+ # Special adapter intended to be used when you can only access
25
+ # the WHOIS database via an online interface.
26
+ #
27
+ # This adapter should be considered a <tt>Whois::Server::Adapters::None</tt>
28
+ # adapter a little more specific.
29
+ #
21
30
  class Web < Base
22
31
 
32
+ # Always raises a <tt>Whois::WebInterfaceError</tt> exception
33
+ # including the web address for the WHOIS inteface.
34
+ #
35
+ # ==== Raises
36
+ # WebInterfaceError:: for every request
37
+ #
23
38
  def request(qstring)
24
39
  raise WebInterfaceError, "This TLD has no whois server, " +
25
40
  "but you can access the whois database at `#{options[:web]}'"
@@ -18,8 +18,8 @@ module Whois
18
18
 
19
19
  module Version
20
20
  MAJOR = 0
21
- MINOR = 5
22
- TINY = 3
21
+ MINOR = 8
22
+ TINY = 0
23
23
 
24
24
  STRING = [MAJOR, MINOR, TINY].join('.')
25
25
  end
@@ -69,7 +69,7 @@ module Whois
69
69
  # If you want to save keystrokes, you can even use the handy <tt>Whois.query</tt> method.
70
70
  #
71
71
  # Whois.query '72.14.207.99'
72
- # # => whois response
72
+ # # => whois answer
73
73
  #
74
74
  class Whois # :nodoc
75
75
 
@@ -120,7 +120,7 @@ module Whois
120
120
  end
121
121
 
122
122
  def all
123
- ::Whois.deprecate "#all will be removed in a future release. You are responsible for storing the whois response in a custom variable."
123
+ ::Whois.deprecate "#all will be removed in a future release. You are responsible for storing the whois answer in a custom variable."
124
124
  @all
125
125
  end
126
126
 
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+ require 'whois/answer/parser/base'
3
+
4
+ class AnswerParserBaseTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @klass = Whois::Answer::Parser::Base
8
+ @part = Whois::Answer::Part.new("This is the response.", "whois.foo.com")
9
+ end
10
+
11
+
12
+ def test_initialize
13
+ parser = @klass.new(@part)
14
+ assert_instance_of @klass, parser
15
+ end
16
+
17
+ def test_initialize_should_require_part
18
+ assert_raise(ArgumentError) { @klass.new }
19
+ end
20
+
21
+
22
+ def test_content
23
+ parser = @klass.new(@part)
24
+ assert_equal @part.response, parser.content
25
+ end
26
+
27
+ end
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+ require 'whois/answer/parser/blank'
3
+
4
+ class AnswerParserBlankTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @klass = Whois::Answer::Parser::Blank
8
+ @part = Whois::Answer::Part.new("This is the response.", "whois.foo.com")
9
+ end
10
+
11
+ Whois::Answer::Parser.registrable_methods.each do |method|
12
+ define_method "test_#{method}_should_raise" do
13
+ parser = @klass.new(@part)
14
+ error = assert_raise(Whois::ParserNotFound) { parser.send(method) }
15
+ assert_match "whois.foo.com", error.message
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,175 @@
1
+ require 'test_helper'
2
+ require 'whois/answer/parser/whois.crsnic.net'
3
+
4
+ class AnswerParserWhoisCrsnicNetTest < Test::Unit::TestCase
5
+
6
+ TESTCASE_PATH = File.expand_path(File.dirname(__FILE__) + '/../../testcases/responses/whois.crsnic.net')
7
+
8
+ def setup
9
+ @klass = Whois::Answer::Parser::WhoisCrsnicNet
10
+ @host = "whois.crsnic.net"
11
+ end
12
+
13
+
14
+ def test_disclaimer
15
+ expected = <<-EOS.strip
16
+ TERMS OF USE: You are not authorized to access or query our Whois \
17
+ database through the use of electronic processes that are high-volume and \
18
+ automated except as reasonably necessary to register domain names or \
19
+ modify existing registrations; the Data in VeriSign Global Registry \
20
+ Services' ("VeriSign") Whois database is provided by VeriSign for \
21
+ information purposes only, and to assist persons in obtaining information \
22
+ about or related to a domain name registration record. VeriSign does not \
23
+ guarantee its accuracy. By submitting a Whois query, you agree to abide \
24
+ by the following terms of use: You agree that you may use this Data only \
25
+ for lawful purposes and that under no circumstances will you use this Data \
26
+ to: (1) allow, enable, or otherwise support the transmission of mass \
27
+ unsolicited, commercial advertising or solicitations via e-mail, telephone, \
28
+ or facsimile; or (2) enable high volume, automated, electronic processes \
29
+ that apply to VeriSign (or its computer systems). The compilation, \
30
+ repackaging, dissemination or other use of this Data is expressly \
31
+ prohibited without the prior written consent of VeriSign. You agree not to \
32
+ use electronic processes that are automated and high-volume to access or \
33
+ query the Whois database except as reasonably necessary to register \
34
+ domain names or modify existing registrations. VeriSign reserves the right \
35
+ to restrict your access to the Whois database in its sole discretion to ensure \
36
+ operational stability. VeriSign may restrict or terminate your access to the \
37
+ Whois database for failure to abide by these terms of use. VeriSign \
38
+ reserves the right to modify these terms at any time.
39
+ EOS
40
+ assert_equal expected,
41
+ @klass.new(load_part('/registered.txt')).disclaimer
42
+ end
43
+
44
+ def test_disclaimer_with_available
45
+ expected = <<-EOS.strip
46
+ TERMS OF USE: You are not authorized to access or query our Whois \
47
+ database through the use of electronic processes that are high-volume and \
48
+ automated except as reasonably necessary to register domain names or \
49
+ modify existing registrations; the Data in VeriSign Global Registry \
50
+ Services' ("VeriSign") Whois database is provided by VeriSign for \
51
+ information purposes only, and to assist persons in obtaining information \
52
+ about or related to a domain name registration record. VeriSign does not \
53
+ guarantee its accuracy. By submitting a Whois query, you agree to abide \
54
+ by the following terms of use: You agree that you may use this Data only \
55
+ for lawful purposes and that under no circumstances will you use this Data \
56
+ to: (1) allow, enable, or otherwise support the transmission of mass \
57
+ unsolicited, commercial advertising or solicitations via e-mail, telephone, \
58
+ or facsimile; or (2) enable high volume, automated, electronic processes \
59
+ that apply to VeriSign (or its computer systems). The compilation, \
60
+ repackaging, dissemination or other use of this Data is expressly \
61
+ prohibited without the prior written consent of VeriSign. You agree not to \
62
+ use electronic processes that are automated and high-volume to access or \
63
+ query the Whois database except as reasonably necessary to register \
64
+ domain names or modify existing registrations. VeriSign reserves the right \
65
+ to restrict your access to the Whois database in its sole discretion to ensure \
66
+ operational stability. VeriSign may restrict or terminate your access to the \
67
+ Whois database for failure to abide by these terms of use. VeriSign \
68
+ reserves the right to modify these terms at any time.
69
+ EOS
70
+ assert_equal expected,
71
+ @klass.new(load_part('/available.txt')).disclaimer
72
+ end
73
+
74
+
75
+ def test_domain
76
+ assert_equal "googlelkjhgfdfghjklkjhgf.net",
77
+ @klass.new(load_part('/available.txt')).domain
78
+ assert_equal "google.net",
79
+ @klass.new(load_part('/registered.txt')).domain
80
+ end
81
+
82
+ def test_domain_id
83
+ assert_equal nil,
84
+ @klass.new(load_part('/available.txt')).domain_id
85
+ assert_equal nil,
86
+ @klass.new(load_part('/registered.txt')).domain_id
87
+ end
88
+
89
+
90
+ def test_referral_whois
91
+ assert_equal nil,
92
+ @klass.new(load_part('/available.txt')).referral_whois
93
+ assert_equal "whois.markmonitor.com",
94
+ @klass.new(load_part('/registered.txt')).referral_whois
95
+ end
96
+
97
+ def test_referral_url
98
+ assert_equal nil,
99
+ @klass.new(load_part('/available.txt')).referral_url
100
+ assert_equal "http://www.markmonitor.com",
101
+ @klass.new(load_part('/registered.txt')).referral_url
102
+ end
103
+
104
+
105
+ def test_status
106
+ assert_equal nil,
107
+ @klass.new(load_part('/available.txt')).status
108
+ assert_equal ["clientDeleteProhibited", "clientTransferProhibited", "clientUpdateProhibited"],
109
+ @klass.new(load_part('/registered.txt')).status
110
+ end
111
+
112
+ def test_available?
113
+ assert !@klass.new(load_part('/registered.txt')).available?
114
+ assert @klass.new(load_part('/available.txt')).available?
115
+ end
116
+
117
+ def test_registered?
118
+ assert !@klass.new(load_part('/available.txt')).registered?
119
+ assert @klass.new(load_part('/registered.txt')).registered?
120
+ end
121
+
122
+
123
+ def test_created_on
124
+ assert_equal Time.parse("1999-03-15 00:00:00"),
125
+ @klass.new(load_part('/registered.txt')).created_on
126
+ end
127
+
128
+ def test_created_on_with_available
129
+ assert_equal nil,
130
+ @klass.new(load_part('/available.txt')).created_on
131
+ end
132
+
133
+ def test_updated_on
134
+ assert_equal Time.parse("2009-02-10 00:00:00"),
135
+ @klass.new(load_part('/registered.txt')).updated_on
136
+ end
137
+
138
+ def test_updated_on_with_available
139
+ assert_equal nil,
140
+ @klass.new(load_part('/available.txt')).updated_on
141
+ end
142
+
143
+ def test_expires_on
144
+ assert_equal Time.parse("2010-03-15 00:00:00"),
145
+ @klass.new(load_part('/registered.txt')).expires_on
146
+ end
147
+
148
+ def test_expires_on_with_available
149
+ assert_equal nil,
150
+ @klass.new(load_part('/available.txt')).expires_on
151
+ end
152
+
153
+
154
+ def test_registrar
155
+ assert_equal nil,
156
+ @klass.new(load_part('/registered.txt')).registrar
157
+ end
158
+
159
+ def test_registrar_with_available
160
+ assert_equal nil,
161
+ @klass.new(load_part('/available.txt')).registrar
162
+ end
163
+
164
+
165
+ protected
166
+
167
+ def load_part(path)
168
+ part(File.read(TESTCASE_PATH + path), @host)
169
+ end
170
+
171
+ def part(*args)
172
+ Whois::Answer::Part.new(*args)
173
+ end
174
+
175
+ end