whois 4.0.6 → 6.0.3

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +12 -0
  3. data/.github/dependabot.yml +17 -0
  4. data/.github/workflows/release.yml +19 -0
  5. data/.github/workflows/tests.yml +29 -0
  6. data/.gitignore +11 -0
  7. data/.rspec +1 -0
  8. data/.rubocop.yml +27 -0
  9. data/.rubocop_opinionated.yml +115 -0
  10. data/.rubocop_todo.yml +89 -0
  11. data/.simplecov +6 -0
  12. data/.tool-versions +1 -0
  13. data/CHANGELOG.md +147 -44
  14. data/CONTRIBUTING.md +18 -6
  15. data/Gemfile +8 -0
  16. data/LICENSE.txt +1 -1
  17. data/README.md +4 -4
  18. data/Rakefile +28 -0
  19. data/SECURITY.md +24 -0
  20. data/bin/console +1 -0
  21. data/bin/whoisrb +6 -5
  22. data/data/ipv4.json +1 -3
  23. data/data/tld.json +125 -1049
  24. data/lib/whois/client.rb +5 -7
  25. data/lib/whois/errors.rb +4 -6
  26. data/lib/whois/record/part.rb +5 -6
  27. data/lib/whois/record.rb +5 -8
  28. data/lib/whois/server/adapters/afilias.rb +4 -5
  29. data/lib/whois/server/adapters/arin.rb +7 -8
  30. data/lib/whois/server/adapters/arpa.rb +19 -24
  31. data/lib/whois/server/adapters/base.rb +29 -46
  32. data/lib/whois/server/adapters/formatted.rb +4 -6
  33. data/lib/whois/server/adapters/none.rb +4 -6
  34. data/lib/whois/server/adapters/not_implemented.rb +4 -6
  35. data/lib/whois/server/adapters/standard.rb +4 -6
  36. data/lib/whois/server/adapters/verisign.rb +4 -5
  37. data/lib/whois/server/adapters/web.rb +4 -6
  38. data/lib/whois/server/socket_handler.rb +11 -12
  39. data/lib/whois/server.rb +73 -64
  40. data/lib/whois/version.rb +4 -2
  41. data/lib/whois.rb +32 -33
  42. data/spec/fixtures/referrals/afilias.bz.txt +23 -0
  43. data/spec/fixtures/referrals/arin_referral_apnic.txt +78 -0
  44. data/spec/fixtures/referrals/arin_referral_missing.txt +52 -0
  45. data/spec/fixtures/referrals/arin_referral_ripe.txt +50 -0
  46. data/spec/fixtures/referrals/arin_referral_rwhois.txt +63 -0
  47. data/spec/fixtures/referrals/arin_referral_servernap.txt +63 -0
  48. data/spec/fixtures/referrals/arin_referral_whois.txt +56 -0
  49. data/spec/fixtures/referrals/crsnic.com.txt +60 -0
  50. data/spec/fixtures/referrals/crsnic.com_referral.txt +56 -0
  51. data/spec/fixtures/referrals/crsnic.com_referral_missing.txt +50 -0
  52. data/spec/integration/whois_spec.rb +73 -0
  53. data/spec/spec_helper.rb +19 -0
  54. data/spec/support/helpers/connectivity_helper.rb +15 -0
  55. data/spec/support/helpers/spec_helper.rb +31 -0
  56. data/spec/whois/client_spec.rb +143 -0
  57. data/spec/whois/record/part_spec.rb +38 -0
  58. data/spec/whois/record_spec.rb +168 -0
  59. data/spec/whois/server/adapters/afilias_spec.rb +49 -0
  60. data/spec/whois/server/adapters/arin_spec.rb +83 -0
  61. data/spec/whois/server/adapters/arpa_spec.rb +29 -0
  62. data/spec/whois/server/adapters/base_spec.rb +155 -0
  63. data/spec/whois/server/adapters/formatted_spec.rb +53 -0
  64. data/spec/whois/server/adapters/none_spec.rb +23 -0
  65. data/spec/whois/server/adapters/not_implemented_spec.rb +24 -0
  66. data/spec/whois/server/adapters/standard_spec.rb +42 -0
  67. data/spec/whois/server/adapters/verisign_spec.rb +60 -0
  68. data/spec/whois/server/adapters/web_spec.rb +24 -0
  69. data/spec/whois/server/socket_handler_spec.rb +33 -0
  70. data/spec/whois/server_spec.rb +302 -0
  71. data/spec/whois/web_interface_error_spec.rb +23 -0
  72. data/spec/whois/whois_spec.rb +15 -0
  73. data/utils/compare-whois.rb +30 -0
  74. data/utils/deftld.rb +230 -0
  75. data/utils/defutils.rb +26 -0
  76. data/utils/fixupd.rb +60 -0
  77. data/utils/matrix.rb +68 -0
  78. data/utils/mkwhois.rb +31 -0
  79. data/whois.gemspec +19 -32
  80. metadata +58 -11
  81. data/4.0-Upgrade.md +0 -143
  82. data/bin/setup +0 -8
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server::Adapters::Formatted do
6
+ let(:definition) { [:tld, ".de", "whois.denic.de", { format: "-T dn,ace -C US-ASCII %s" }] }
7
+
8
+
9
+ describe "#lookup" do
10
+ it "returns the WHOIS record" do
11
+ response = "Whois Response"
12
+ expected = response
13
+ server = described_class.new(*definition)
14
+ expect(server.query_handler).to receive(:call).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 43).and_return(response)
15
+
16
+ record = server.lookup("domain.de")
17
+ expect(record.to_s).to eq(expected)
18
+ expect(record.parts).to eq([Whois::Record::Part.new(body: response, host: "whois.denic.de")])
19
+ end
20
+
21
+ context "without format option" do
22
+ it "raises an error" do
23
+ server = described_class.new(:tld, ".de", "whois.denic.de", {})
24
+ expect(server.query_handler).not_to receive(:call)
25
+
26
+ expect {
27
+ server.lookup("domain.de")
28
+ }.to raise_error(Whois::ServerError)
29
+ end
30
+ end
31
+
32
+ context "with port option" do
33
+ it "sends the request to given port" do
34
+ response = "Whois Response"
35
+ server = described_class.new(:tld, ".de", "whois.denic.de", { format: "-T dn,ace -C US-ASCII %s", port: 20 })
36
+ expect(server.query_handler).to receive(:call).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 20).and_return(response)
37
+
38
+ server.lookup("domain.de")
39
+ end
40
+ end
41
+
42
+ context "with bind option" do
43
+ it "binds the request to given host and port" do
44
+ response = "Whois Response"
45
+ server = described_class.new(:tld, ".de", "whois.denic.de", { format: "-T dn,ace -C US-ASCII %s" })
46
+ server.configure(bind_host: "192.168.1.1", bind_port: 3000)
47
+ expect(server.query_handler).to receive(:call).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 43, "192.168.1.1", 3000).and_return(response)
48
+
49
+ server.lookup("domain.de")
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server::Adapters::None do
6
+ describe "#lookup" do
7
+ it "raises Whois::NoInterfaceError" do
8
+ expect {
9
+ described_class.new(:tld, ".test", nil).lookup("example.test")
10
+ }.to raise_error(Whois::NoInterfaceError)
11
+ end
12
+
13
+ it "customizes the error message according to the type" do
14
+ expect {
15
+ described_class.new(:tld, ".test", nil).lookup("example.test")
16
+ }.to raise_error(Whois::NoInterfaceError, /tld/)
17
+
18
+ expect {
19
+ described_class.new(:ipv4, "127.0.0.1", nil).lookup("127.0.0.1")
20
+ }.to raise_error(Whois::NoInterfaceError, /ipv4/)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server::Adapters::NotImplemented do
6
+ before do
7
+ @definition = [:ipv6, "2001:0000::/32", "teredo", { adapter: described_class }]
8
+ end
9
+
10
+
11
+ describe "#lookup" do
12
+ it "raises Whois::ServerNotImplemented" do
13
+ expect {
14
+ described_class.new(*@definition).lookup("example.test")
15
+ }.to raise_error(Whois::ServerNotImplemented)
16
+ end
17
+
18
+ it "customizes the error message according to the host" do
19
+ expect {
20
+ described_class.new(*@definition).lookup("example.test")
21
+ }.to raise_error(Whois::ServerNotImplemented, /teredo/)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server::Adapters::Standard do
6
+ let(:definition) { [:tld, ".test", "whois.test", {}] }
7
+
8
+
9
+ describe "#lookup" do
10
+ it "returns the WHOIS record" do
11
+ response = "Whois Response"
12
+ expected = response
13
+ server = described_class.new(*definition)
14
+ expect(server.query_handler).to receive(:call).with("domain.test", "whois.test", 43).and_return(response)
15
+
16
+ record = server.lookup("domain.test")
17
+ expect(record.to_s).to eq(expected)
18
+ expect(record.parts).to eq([Whois::Record::Part.new(body: response, host: "whois.test")])
19
+ end
20
+
21
+ context "with port option" do
22
+ it "sends the request to given port" do
23
+ response = "Whois Response"
24
+ server = described_class.new(:tld, ".test", "whois.test", { port: 20 })
25
+ expect(server.query_handler).to receive(:call).with("domain.test", "whois.test", 20).and_return(response)
26
+
27
+ server.lookup("domain.test")
28
+ end
29
+ end
30
+
31
+ context "with bind option" do
32
+ it "binds the request to given host and port" do
33
+ response = "Whois Response"
34
+ server = described_class.new(:tld, ".test", "whois.test", { port: 20 })
35
+ server.configure(bind_host: "192.168.1.100", bind_port: 3000)
36
+ expect(server.query_handler).to receive(:call).with("domain.test", "whois.test", 20, "192.168.1.100", 3000).and_return(response)
37
+
38
+ server.lookup("domain.test")
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server::Adapters::Verisign do
6
+ let(:definition) { [:tld, ".test", "whois.test", {}] }
7
+ let(:server) { described_class.new(*definition) }
8
+
9
+
10
+ describe "#lookup" do
11
+ context "without referral" do
12
+ it "returns the WHOIS record" do
13
+ response = "No match for example.test."
14
+ expected = response
15
+ expect(server.query_handler).to receive(:call).with("=example.test", "whois.test", 43).and_return(response)
16
+
17
+ record = server.lookup("example.test")
18
+ expect(record.to_s).to eq(expected)
19
+ expect(record.parts.size).to eq(1)
20
+ expect(record.parts).to eq([Whois::Record::Part.new(body: response, host: "whois.test")])
21
+ end
22
+ end
23
+
24
+ context "with referral" do
25
+ it "follows all referrals" do
26
+ referral = File.read(fixture("referrals/crsnic.com.txt"))
27
+ response = "Match for example.test."
28
+ expected = "#{referral}\n#{response}"
29
+ expect(server.query_handler).to receive(:call).with("=example.test", "whois.test", 43).and_return(referral)
30
+ expect(server.query_handler).to receive(:call).with("example.test", "whois.markmonitor.com", 43).and_return(response)
31
+
32
+ record = server.lookup("example.test")
33
+ expect(record.to_s).to eq(expected)
34
+ expect(record.parts.size).to eq(2)
35
+ expect(record.parts).to eq([Whois::Record::Part.new(body: referral, host: "whois.test"), Whois::Record::Part.new(body: response, host: "whois.markmonitor.com")])
36
+ end
37
+
38
+ it "ignores referral if options[:referral] is false" do
39
+ referral = File.read(fixture("referrals/crsnic.com.txt"))
40
+ server.options[:referral] = false
41
+ expect(server.query_handler).to receive(:call).with("=example.test", "whois.test", 43).and_return(referral)
42
+ expect(server.query_handler).not_to receive(:call)
43
+
44
+ record = server.lookup("example.test")
45
+ expect(record.parts.size).to eq(1)
46
+ end
47
+
48
+ # (see #103)
49
+ # This is the case of vrsn-20100925-dnssecmonitor86.net
50
+ it "ignores referral (gracefully) if missing" do
51
+ referral = File.read(fixture("referrals/crsnic.com_referral_missing.txt"))
52
+ expect(server.query_handler).to receive(:call).with("=example.test", "whois.test", 43).and_return(referral)
53
+ expect(server.query_handler).not_to receive(:call)
54
+
55
+ record = server.lookup("example.test")
56
+ expect(record.parts.size).to eq(1)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server::Adapters::Web do
6
+ before do
7
+ @definition = [:tld, ".test", nil, { url: "http://whois.test" }]
8
+ end
9
+
10
+
11
+ describe "#lookup" do
12
+ it "raises Whois::WebInterfaceError" do
13
+ expect {
14
+ described_class.new(*@definition).lookup("example.test")
15
+ }.to raise_error(Whois::WebInterfaceError)
16
+ end
17
+
18
+ it "customizes the error message with the WHOIS web url" do
19
+ expect {
20
+ described_class.new(*@definition).lookup("example.test")
21
+ }.to raise_error(Whois::WebInterfaceError, /whois\.test/)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "whois/server/socket_handler"
5
+
6
+ describe Whois::Server::SocketHandler do
7
+ describe "#call" do
8
+ [Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::EPIPE, SocketError].each do |error|
9
+ it "re-raises #{error} as Whois::ConnectionError" do
10
+ handler = described_class.new
11
+ expect(handler).to receive(:execute).and_raise(error)
12
+
13
+ expect {
14
+ handler.call("example.test", "whois.test", 43)
15
+ }.to raise_error(Whois::ConnectionError, "#{error}: #{error.new.message}")
16
+ end
17
+
18
+ it "executes a socket connection for given args" do
19
+ socket = instance_double(TCPSocket)
20
+ expect(socket).to receive(:write).with("example.test\r\n")
21
+ expect(socket).to receive(:read)
22
+ expect(socket).to receive(:close)
23
+
24
+ expect(TCPSocket).to receive(:new)
25
+ .with("whois.test", 43)
26
+ .and_return(socket)
27
+
28
+ handler = described_class.new
29
+ handler.call("example.test", "whois.test", 43)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,302 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::Server do
6
+ describe ".load_json" do
7
+ it "loads a definition from a JSON file" do
8
+ expect(File).to receive(:read).with("tld.json").and_return(<<~JSON)
9
+ {
10
+ "ae.org": {
11
+ "host": "whois.centralnic.com"
12
+ },
13
+ "ar.com": {
14
+ "host": "whois.centralnic.com"
15
+ }
16
+ }
17
+ JSON
18
+ with_definitions do
19
+ described_class.load_json("tld.json")
20
+ expect(described_class.definitions(:tld)).to eq([
21
+ ["ae.org", "whois.centralnic.com", {}],
22
+ ["ar.com", "whois.centralnic.com", {}],
23
+ ])
24
+ end
25
+ end
26
+
27
+ it "convert option keys to Symbol" do
28
+ expect(File).to receive(:read).with("tld.json").and_return(<<~JSON)
29
+ {
30
+ "com": {
31
+ "host": "whois.crsnic.net",
32
+ "adapter": "verisign"
33
+ }
34
+ }
35
+ JSON
36
+ with_definitions do
37
+ described_class.load_json("tld.json")
38
+ expect(described_class.definitions(:tld)).to eq([
39
+ ["com", "whois.crsnic.net", { adapter: "verisign" }],
40
+ ])
41
+ end
42
+ end
43
+ end
44
+
45
+ describe ".definitions" do
46
+ it "returns the definitions array for given type" do
47
+ with_definitions do
48
+ described_class.define(Whois::Server::TYPE_TLD, "foo", "whois.foo")
49
+ definition = described_class.definitions(Whois::Server::TYPE_TLD)
50
+ expect(definition).to be_a(Array)
51
+ expect(definition).to eq([["foo", "whois.foo", {}]])
52
+ end
53
+ end
54
+
55
+ it "raises ArgumentError when the type is invalid" do
56
+ with_definitions do
57
+ expect {
58
+ described_class.definitions(:foo)
59
+ }.to raise_error(ArgumentError)
60
+ end
61
+ end
62
+ end
63
+
64
+ describe ".define" do
65
+ it "adds a new definition with given arguments" do
66
+ with_definitions do
67
+ described_class.define(Whois::Server::TYPE_TLD, "foo", "whois.foo")
68
+ expect(described_class.definitions(Whois::Server::TYPE_TLD)).to eq([["foo", "whois.foo", {}]])
69
+ end
70
+ end
71
+
72
+ it "accepts a hash of options" do
73
+ with_definitions do
74
+ described_class.define(Whois::Server::TYPE_TLD, "foo", "whois.foo", foo: "bar")
75
+ expect(described_class.definitions(Whois::Server::TYPE_TLD)).to eq([["foo", "whois.foo", { foo: "bar" }]])
76
+ end
77
+ end
78
+ end
79
+
80
+ describe ".factory" do
81
+ it "returns an adapter initialized with given arguments" do
82
+ server = described_class.factory(:tld, "test", "whois.test")
83
+ expect(server.type).to eq(:tld)
84
+ expect(server.allocation).to eq("test")
85
+ expect(server.host).to eq("whois.test")
86
+ expect(server.options).to eq({})
87
+ end
88
+
89
+ it "returns a standard adapter by default" do
90
+ server = described_class.factory(:tld, "test", "whois.test")
91
+ expect(server).to be_a(Whois::Server::Adapters::Standard)
92
+ end
93
+
94
+ it "accepts an :adapter option as Class and returns an instance of given adapter" do
95
+ a = Class.new do
96
+ attr_reader :args
97
+
98
+ def initialize(*args)
99
+ @args = args
100
+ end
101
+ end
102
+ server = described_class.factory(:tld, "test", "whois.test", adapter: a)
103
+ expect(server).to be_a(a)
104
+ expect(server.args).to eq([:tld, "test", "whois.test", {}])
105
+ end
106
+
107
+ it "accepts an :adapter option as Symbol or String, load Class and returns an instance of given adapter" do
108
+ server = described_class.factory(:tld, "test", "whois.test", adapter: :none)
109
+ expect(server).to be_a(Whois::Server::Adapters::None)
110
+ server = described_class.factory(:tld, "test", "whois.test", adapter: "none")
111
+ expect(server).to be_a(Whois::Server::Adapters::None)
112
+ end
113
+
114
+ it "deletes the adapter option" do
115
+ server = described_class.factory(:tld, "test", "whois.test", adapter: Whois::Server::Adapters::None, foo: "bar")
116
+ expect(server.options).to eq({ foo: "bar" })
117
+ end
118
+ end
119
+
120
+ describe ".guess" do
121
+ it "recognizes tld" do
122
+ server = described_class.guess(".com")
123
+ expect(server).to be_a(Whois::Server::Adapters::Base)
124
+ expect(server.type).to eq(Whois::Server::TYPE_TLD)
125
+ end
126
+
127
+ it "recognizes domain" do
128
+ server = described_class.guess("example.com")
129
+ expect(server).to be_a(Whois::Server::Adapters::Base)
130
+ expect(server.type).to eq(Whois::Server::TYPE_TLD)
131
+ end
132
+
133
+ it "recognizes ipv4" do
134
+ server = described_class.guess("127.0.0.1")
135
+ expect(server).to be_a(Whois::Server::Adapters::Base)
136
+ expect(server.type).to eq(Whois::Server::TYPE_IPV4)
137
+ end
138
+
139
+ it "recognizes ipv6" do
140
+ server = described_class.guess("2001:0db8:85a3:0000:0000:8a2e:0370:7334")
141
+ expect(server).to be_a(Whois::Server::Adapters::Base)
142
+ expect(server.type).to eq(Whois::Server::TYPE_IPV6)
143
+ end
144
+
145
+ it "recognizes ipv6 when zero groups" do
146
+ server = described_class.guess("2002::1")
147
+ expect(server).to be_a(Whois::Server::Adapters::Base)
148
+ expect(server.type).to eq(Whois::Server::TYPE_IPV6)
149
+ end
150
+
151
+ it "recognizes asn16" do
152
+ server = described_class.guess("AS23456")
153
+ expect(server).to be_a(Whois::Server::Adapters::Base)
154
+ expect(server.type).to eq(Whois::Server::TYPE_ASN16)
155
+ end
156
+
157
+ it "recognizes asn32" do
158
+ server = described_class.guess("AS131072")
159
+ expect(server).to be_a(Whois::Server::Adapters::Base)
160
+ expect(server.type).to eq(Whois::Server::TYPE_ASN32)
161
+ end
162
+
163
+ it "recognizes email" do
164
+ expect {
165
+ described_class.guess("email@example.org")
166
+ }.to raise_error(Whois::ServerNotSupported, /email/)
167
+ end
168
+
169
+ it "raises when unrecognized value" do
170
+ expect {
171
+ described_class.guess("invalid")
172
+ }.to raise_error(Whois::ServerNotFound)
173
+ end
174
+
175
+
176
+ context "when the input is a tld" do
177
+ it "returns a IANA adapter" do
178
+ expect(described_class.guess(".com")).to eq(described_class.factory(:tld, ".", "whois.iana.org"))
179
+ end
180
+
181
+ it "returns a IANA adapter when the input is an idn" do
182
+ expect(described_class.guess(".xn--fiqs8s")).to eq(described_class.factory(:tld, ".", "whois.iana.org"))
183
+ end
184
+ end
185
+
186
+ context "when the input is a domain" do
187
+ it "lookups definitions and returns the adapter" do
188
+ with_definitions do
189
+ described_class.define(:tld, "test", "whois.test")
190
+ expect(described_class.guess("example.test")).to eq(described_class.factory(:tld, "test", "whois.test"))
191
+ end
192
+ end
193
+
194
+ it "doesn't consider the dot as a regexp pattern" do
195
+ with_definitions do
196
+ described_class.define(:tld, "no.com", "whois.no.com")
197
+ described_class.define(:tld, "com", "whois.com")
198
+ expect(described_class.guess("antoniocangiano.com")).to eq(described_class.factory(:tld, "com", "whois.com"))
199
+ end
200
+ end
201
+
202
+ it "returns the closer definition" do
203
+ with_definitions do
204
+ described_class.define(:tld, "com", com = "whois.com")
205
+ described_class.define(:tld, "com.foo", comfoo = "whois.com.foo")
206
+ described_class.define(:tld, "foo.com", foocom = "whois.foo.com")
207
+
208
+ expect(described_class.guess("example.com").host).to eq(com)
209
+ expect(described_class.guess("example.com.foo").host).to eq(comfoo)
210
+ expect(described_class.guess("example.foo.com").host).to eq(foocom)
211
+ end
212
+ end
213
+ end
214
+
215
+ context "when the input is an asn16" do
216
+ it "lookups definitions and returns the adapter" do
217
+ with_definitions do
218
+ described_class.define(:asn16, "0 65535", "whois.test")
219
+ expect(described_class.guess("AS65535")).to eq(described_class.factory(:asn16, "0 65535", "whois.test"))
220
+ end
221
+ end
222
+
223
+ it "raises if definition is not found" do
224
+ with_definitions do
225
+ described_class.define(:asn16, "0 60000", "whois.test")
226
+ expect {
227
+ described_class.guess("AS65535")
228
+ }.to raise_error(Whois::AllocationUnknown)
229
+ end
230
+ end
231
+ end
232
+
233
+ context "when the input is an asn32" do
234
+ it "lookups definitions and returns the adapter" do
235
+ with_definitions do
236
+ described_class.define(:asn32, "65536 394239", "whois.test")
237
+ expect(described_class.guess("AS65536")).to eq(described_class.factory(:asn32, "65536 394239", "whois.test"))
238
+ end
239
+ end
240
+
241
+ it "raises if definition is not found" do
242
+ with_definitions do
243
+ described_class.define(:asn32, "65536 131071", "whois.test")
244
+ expect {
245
+ described_class.guess("AS200000")
246
+ }.to raise_error(Whois::AllocationUnknown)
247
+ end
248
+ end
249
+ end
250
+
251
+ context "when the input is a ipv4" do
252
+ it "lookups definitions and returns the adapter" do
253
+ with_definitions do
254
+ described_class.define(:ipv4, "192.168.1.0/10", "whois.test")
255
+ expect(described_class.find_for_ip("192.168.1.1")).to eq(described_class.factory(:ipv4, "192.168.1.0/10", "whois.test"))
256
+ end
257
+ end
258
+
259
+ it "raises if definition is not found" do
260
+ with_definitions do
261
+ described_class.define(:ipv4, "192.168.1.0/10", "whois.test")
262
+ expect {
263
+ described_class.guess("192.192.0.1")
264
+ }.to raise_error(Whois::AllocationUnknown)
265
+ end
266
+ end
267
+ end
268
+
269
+ context "when the input is a ipv6" do
270
+ it "lookups definitions and returns the adapter" do
271
+ with_definitions do
272
+ described_class.define(:ipv6, "2001:0200::/23", "whois.test")
273
+ expect(described_class.guess("2001:0200::1")).to eq(described_class.factory(:ipv6, "2001:0200::/23", "whois.test"))
274
+ end
275
+ end
276
+
277
+ it "raises if definition is not found" do
278
+ with_definitions do
279
+ described_class.define(:ipv6, "::1", "whois.test")
280
+ expect {
281
+ described_class.guess("2002:0300::1")
282
+ }.to raise_error(Whois::AllocationUnknown)
283
+ end
284
+ end
285
+
286
+ it "recognizes ipv4 compatibility mode" do
287
+ with_definitions do
288
+ described_class.define(:ipv6, "::192.168.1.1", "whois.test")
289
+ expect(described_class.guess("::192.168.1.1")).to eq(described_class.factory(:ipv6, "::192.168.1.1", "whois.test"))
290
+ end
291
+ end
292
+
293
+ it "rescues IPAddr ArgumentError", issue: "weppos/whois#174" do
294
+ with_definitions do
295
+ expect {
296
+ described_class.guess("f53")
297
+ }.to raise_error(Whois::AllocationUnknown)
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois::WebInterfaceError do
6
+ describe "#initialize" do
7
+ it "sets the URL" do
8
+ expect(described_class.new("http://example.com").url).to eq("http://example.com")
9
+ end
10
+
11
+ it "requires the URL argument" do
12
+ expect do
13
+ described_class.new
14
+ end.to raise_error(ArgumentError)
15
+ end
16
+ end
17
+
18
+ describe "#message" do
19
+ it "interpolates the URL" do
20
+ expect(described_class.new("http://example.com").message).to match(%r{http://example.com})
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Whois do
6
+ describe ".lookup" do
7
+ it "delegates the lookup to a new client" do
8
+ client = double
9
+ expect(client).to receive(:lookup).with("example.com").and_return(:result)
10
+ expect(Whois::Client).to receive(:new).and_return(client)
11
+
12
+ expect(described_class.lookup("example.com")).to eq(:result)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby -wKU
2
+
3
+ $:.unshift(File.expand_path("../../lib", __FILE__))
4
+
5
+ require 'whois'
6
+
7
+ IANAWHOIS_DIR = "~/Code/ianawhois"
8
+
9
+ servers = {}
10
+ definitions = Whois::Server.definitions(:tld).inject({}) do |hash, item|
11
+ hash.merge(item[0] => item[1])
12
+ end
13
+
14
+ Dir.glob("#{File.expand_path(IANAWHOIS_DIR)}/*").each do |entry|
15
+ basename = File.basename(entry)
16
+ next unless basename.match?(/^[A-Z]+$/)
17
+ content = File.read(entry)
18
+ server = content =~ /^whois:\s+(.+)\n$/ && $1
19
+ servers[".#{basename.downcase}"] = server
20
+ end
21
+
22
+ diffs = []
23
+ servers.each do |host, server|
24
+ iana, whois = server, definitions[host]
25
+ if iana != whois
26
+ diffs << "#{host}: #{whois.inspect} -> #{iana.inspect}"
27
+ end
28
+ end
29
+
30
+ puts diffs.join("\n")