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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +12 -0
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/release.yml +19 -0
- data/.github/workflows/tests.yml +29 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.rubocop.yml +27 -0
- data/.rubocop_opinionated.yml +115 -0
- data/.rubocop_todo.yml +89 -0
- data/.simplecov +6 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +147 -44
- data/CONTRIBUTING.md +18 -6
- data/Gemfile +8 -0
- data/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/Rakefile +28 -0
- data/SECURITY.md +24 -0
- data/bin/console +1 -0
- data/bin/whoisrb +6 -5
- data/data/ipv4.json +1 -3
- data/data/tld.json +125 -1049
- data/lib/whois/client.rb +5 -7
- data/lib/whois/errors.rb +4 -6
- data/lib/whois/record/part.rb +5 -6
- data/lib/whois/record.rb +5 -8
- data/lib/whois/server/adapters/afilias.rb +4 -5
- data/lib/whois/server/adapters/arin.rb +7 -8
- data/lib/whois/server/adapters/arpa.rb +19 -24
- data/lib/whois/server/adapters/base.rb +29 -46
- data/lib/whois/server/adapters/formatted.rb +4 -6
- data/lib/whois/server/adapters/none.rb +4 -6
- data/lib/whois/server/adapters/not_implemented.rb +4 -6
- data/lib/whois/server/adapters/standard.rb +4 -6
- data/lib/whois/server/adapters/verisign.rb +4 -5
- data/lib/whois/server/adapters/web.rb +4 -6
- data/lib/whois/server/socket_handler.rb +11 -12
- data/lib/whois/server.rb +73 -64
- data/lib/whois/version.rb +4 -2
- data/lib/whois.rb +32 -33
- data/spec/fixtures/referrals/afilias.bz.txt +23 -0
- data/spec/fixtures/referrals/arin_referral_apnic.txt +78 -0
- data/spec/fixtures/referrals/arin_referral_missing.txt +52 -0
- data/spec/fixtures/referrals/arin_referral_ripe.txt +50 -0
- data/spec/fixtures/referrals/arin_referral_rwhois.txt +63 -0
- data/spec/fixtures/referrals/arin_referral_servernap.txt +63 -0
- data/spec/fixtures/referrals/arin_referral_whois.txt +56 -0
- data/spec/fixtures/referrals/crsnic.com.txt +60 -0
- data/spec/fixtures/referrals/crsnic.com_referral.txt +56 -0
- data/spec/fixtures/referrals/crsnic.com_referral_missing.txt +50 -0
- data/spec/integration/whois_spec.rb +73 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/helpers/connectivity_helper.rb +15 -0
- data/spec/support/helpers/spec_helper.rb +31 -0
- data/spec/whois/client_spec.rb +143 -0
- data/spec/whois/record/part_spec.rb +38 -0
- data/spec/whois/record_spec.rb +168 -0
- data/spec/whois/server/adapters/afilias_spec.rb +49 -0
- data/spec/whois/server/adapters/arin_spec.rb +83 -0
- data/spec/whois/server/adapters/arpa_spec.rb +29 -0
- data/spec/whois/server/adapters/base_spec.rb +155 -0
- data/spec/whois/server/adapters/formatted_spec.rb +53 -0
- data/spec/whois/server/adapters/none_spec.rb +23 -0
- data/spec/whois/server/adapters/not_implemented_spec.rb +24 -0
- data/spec/whois/server/adapters/standard_spec.rb +42 -0
- data/spec/whois/server/adapters/verisign_spec.rb +60 -0
- data/spec/whois/server/adapters/web_spec.rb +24 -0
- data/spec/whois/server/socket_handler_spec.rb +33 -0
- data/spec/whois/server_spec.rb +302 -0
- data/spec/whois/web_interface_error_spec.rb +23 -0
- data/spec/whois/whois_spec.rb +15 -0
- data/utils/compare-whois.rb +30 -0
- data/utils/deftld.rb +230 -0
- data/utils/defutils.rb +26 -0
- data/utils/fixupd.rb +60 -0
- data/utils/matrix.rb +68 -0
- data/utils/mkwhois.rb +31 -0
- data/whois.gemspec +19 -32
- metadata +58 -11
- data/4.0-Upgrade.md +0 -143
- 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")
|