whois 6.0.0 → 6.0.2
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/dependabot.yml +5 -7
- data/.github/workflows/release.yml +3 -2
- data/.github/workflows/tests.yml +5 -4
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +11 -88
- data/.tool-versions +1 -1
- data/CHANGELOG.md +14 -0
- data/CONTRIBUTING.md +6 -6
- data/Gemfile +2 -2
- data/bin/whoisrb +3 -3
- data/data/tld.json +18 -791
- data/lib/whois/client.rb +1 -1
- data/lib/whois/record.rb +1 -1
- data/lib/whois/server/adapters/arpa.rb +3 -5
- data/lib/whois/server/adapters/base.rb +3 -3
- data/lib/whois/server/adapters/none.rb +1 -1
- data/lib/whois/server/adapters/not_implemented.rb +1 -1
- data/lib/whois/server/adapters/web.rb +1 -1
- data/lib/whois/server/socket_handler.rb +3 -3
- data/lib/whois/server.rb +5 -5
- data/lib/whois/version.rb +1 -1
- data/lib/whois.rb +18 -18
- data/spec/integration/whois_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -2
- data/spec/whois/client_spec.rb +1 -1
- data/spec/whois/record/part_spec.rb +1 -1
- data/spec/whois/record_spec.rb +26 -18
- data/spec/whois/server/adapters/afilias_spec.rb +1 -1
- data/spec/whois/server/adapters/arin_spec.rb +1 -1
- data/spec/whois/server/adapters/arpa_spec.rb +2 -2
- data/spec/whois/server/adapters/base_spec.rb +17 -12
- data/spec/whois/server/adapters/formatted_spec.rb +1 -1
- data/spec/whois/server/adapters/none_spec.rb +1 -1
- data/spec/whois/server/adapters/not_implemented_spec.rb +2 -2
- data/spec/whois/server/adapters/standard_spec.rb +1 -1
- data/spec/whois/server/adapters/verisign_spec.rb +1 -1
- data/spec/whois/server/adapters/web_spec.rb +1 -1
- data/spec/whois/server/socket_handler_spec.rb +9 -5
- data/spec/whois/server_spec.rb +51 -51
- data/spec/whois/web_interface_error_spec.rb +1 -1
- data/spec/whois/whois_spec.rb +1 -1
- data/utils/deftld.rb +0 -1
- metadata +4 -9
- data/.github/workflows/codeql-analysis.yml +0 -64
- data/4.0-Upgrade.md +0 -143
data/spec/whois/server_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe Whois::Server do
|
6
6
|
describe ".load_json" do
|
@@ -45,7 +45,7 @@ describe Whois::Server do
|
|
45
45
|
describe ".definitions" do
|
46
46
|
it "returns the definitions array for given type" do
|
47
47
|
with_definitions do
|
48
|
-
|
48
|
+
described_class.define(Whois::Server::TYPE_TLD, "foo", "whois.foo")
|
49
49
|
definition = described_class.definitions(Whois::Server::TYPE_TLD)
|
50
50
|
expect(definition).to be_a(Array)
|
51
51
|
expect(definition).to eq([["foo", "whois.foo", {}]])
|
@@ -64,14 +64,14 @@ describe Whois::Server do
|
|
64
64
|
describe ".define" do
|
65
65
|
it "adds a new definition with given arguments" do
|
66
66
|
with_definitions do
|
67
|
-
|
67
|
+
described_class.define(Whois::Server::TYPE_TLD, "foo", "whois.foo")
|
68
68
|
expect(described_class.definitions(Whois::Server::TYPE_TLD)).to eq([["foo", "whois.foo", {}]])
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
72
|
it "accepts a hash of options" do
|
73
73
|
with_definitions do
|
74
|
-
|
74
|
+
described_class.define(Whois::Server::TYPE_TLD, "foo", "whois.foo", foo: "bar")
|
75
75
|
expect(described_class.definitions(Whois::Server::TYPE_TLD)).to eq([["foo", "whois.foo", { foo: "bar" }]])
|
76
76
|
end
|
77
77
|
end
|
@@ -79,7 +79,7 @@ describe Whois::Server do
|
|
79
79
|
|
80
80
|
describe ".factory" do
|
81
81
|
it "returns an adapter initialized with given arguments" do
|
82
|
-
server =
|
82
|
+
server = described_class.factory(:tld, "test", "whois.test")
|
83
83
|
expect(server.type).to eq(:tld)
|
84
84
|
expect(server.allocation).to eq("test")
|
85
85
|
expect(server.host).to eq("whois.test")
|
@@ -87,7 +87,7 @@ describe Whois::Server do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
it "returns a standard adapter by default" do
|
90
|
-
server =
|
90
|
+
server = described_class.factory(:tld, "test", "whois.test")
|
91
91
|
expect(server).to be_a(Whois::Server::Adapters::Standard)
|
92
92
|
end
|
93
93
|
|
@@ -99,115 +99,115 @@ describe Whois::Server do
|
|
99
99
|
@args = args
|
100
100
|
end
|
101
101
|
end
|
102
|
-
server =
|
102
|
+
server = described_class.factory(:tld, "test", "whois.test", adapter: a)
|
103
103
|
expect(server).to be_a(a)
|
104
104
|
expect(server.args).to eq([:tld, "test", "whois.test", {}])
|
105
105
|
end
|
106
106
|
|
107
107
|
it "accepts an :adapter option as Symbol or String, load Class and returns an instance of given adapter" do
|
108
|
-
server =
|
108
|
+
server = described_class.factory(:tld, "test", "whois.test", adapter: :none)
|
109
109
|
expect(server).to be_a(Whois::Server::Adapters::None)
|
110
|
-
server =
|
110
|
+
server = described_class.factory(:tld, "test", "whois.test", adapter: "none")
|
111
111
|
expect(server).to be_a(Whois::Server::Adapters::None)
|
112
112
|
end
|
113
113
|
|
114
114
|
it "deletes the adapter option" do
|
115
|
-
server =
|
115
|
+
server = described_class.factory(:tld, "test", "whois.test", adapter: Whois::Server::Adapters::None, foo: "bar")
|
116
116
|
expect(server.options).to eq({ foo: "bar" })
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
describe ".guess" do
|
121
121
|
it "recognizes tld" do
|
122
|
-
server =
|
122
|
+
server = described_class.guess(".com")
|
123
123
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
124
124
|
expect(server.type).to eq(Whois::Server::TYPE_TLD)
|
125
125
|
end
|
126
126
|
|
127
127
|
it "recognizes domain" do
|
128
|
-
server =
|
128
|
+
server = described_class.guess("example.com")
|
129
129
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
130
130
|
expect(server.type).to eq(Whois::Server::TYPE_TLD)
|
131
131
|
end
|
132
132
|
|
133
133
|
it "recognizes ipv4" do
|
134
|
-
server =
|
134
|
+
server = described_class.guess("127.0.0.1")
|
135
135
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
136
136
|
expect(server.type).to eq(Whois::Server::TYPE_IPV4)
|
137
137
|
end
|
138
138
|
|
139
139
|
it "recognizes ipv6" do
|
140
|
-
server =
|
140
|
+
server = described_class.guess("2001:0db8:85a3:0000:0000:8a2e:0370:7334")
|
141
141
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
142
142
|
expect(server.type).to eq(Whois::Server::TYPE_IPV6)
|
143
143
|
end
|
144
144
|
|
145
145
|
it "recognizes ipv6 when zero groups" do
|
146
|
-
server =
|
146
|
+
server = described_class.guess("2002::1")
|
147
147
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
148
148
|
expect(server.type).to eq(Whois::Server::TYPE_IPV6)
|
149
149
|
end
|
150
150
|
|
151
151
|
it "recognizes asn16" do
|
152
|
-
server =
|
152
|
+
server = described_class.guess("AS23456")
|
153
153
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
154
154
|
expect(server.type).to eq(Whois::Server::TYPE_ASN16)
|
155
155
|
end
|
156
156
|
|
157
157
|
it "recognizes asn32" do
|
158
|
-
server =
|
158
|
+
server = described_class.guess("AS131072")
|
159
159
|
expect(server).to be_a(Whois::Server::Adapters::Base)
|
160
160
|
expect(server.type).to eq(Whois::Server::TYPE_ASN32)
|
161
161
|
end
|
162
162
|
|
163
163
|
it "recognizes email" do
|
164
164
|
expect {
|
165
|
-
|
165
|
+
described_class.guess("email@example.org")
|
166
166
|
}.to raise_error(Whois::ServerNotSupported, /email/)
|
167
167
|
end
|
168
168
|
|
169
169
|
it "raises when unrecognized value" do
|
170
170
|
expect {
|
171
|
-
|
171
|
+
described_class.guess("invalid")
|
172
172
|
}.to raise_error(Whois::ServerNotFound)
|
173
173
|
end
|
174
174
|
|
175
175
|
|
176
176
|
context "when the input is a tld" do
|
177
177
|
it "returns a IANA adapter" do
|
178
|
-
expect(
|
178
|
+
expect(described_class.guess(".com")).to eq(described_class.factory(:tld, ".", "whois.iana.org"))
|
179
179
|
end
|
180
180
|
|
181
181
|
it "returns a IANA adapter when the input is an idn" do
|
182
|
-
expect(
|
182
|
+
expect(described_class.guess(".xn--fiqs8s")).to eq(described_class.factory(:tld, ".", "whois.iana.org"))
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
186
|
context "when the input is a domain" do
|
187
187
|
it "lookups definitions and returns the adapter" do
|
188
188
|
with_definitions do
|
189
|
-
|
190
|
-
expect(
|
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
191
|
end
|
192
192
|
end
|
193
193
|
|
194
194
|
it "doesn't consider the dot as a regexp pattern" do
|
195
195
|
with_definitions do
|
196
|
-
|
197
|
-
|
198
|
-
expect(
|
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
199
|
end
|
200
200
|
end
|
201
201
|
|
202
202
|
it "returns the closer definition" do
|
203
203
|
with_definitions do
|
204
|
-
|
205
|
-
|
206
|
-
|
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
207
|
|
208
|
-
expect(
|
209
|
-
expect(
|
210
|
-
expect(
|
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
211
|
end
|
212
212
|
end
|
213
213
|
end
|
@@ -215,16 +215,16 @@ describe Whois::Server do
|
|
215
215
|
context "when the input is an asn16" do
|
216
216
|
it "lookups definitions and returns the adapter" do
|
217
217
|
with_definitions do
|
218
|
-
|
219
|
-
expect(
|
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
220
|
end
|
221
221
|
end
|
222
222
|
|
223
223
|
it "raises if definition is not found" do
|
224
224
|
with_definitions do
|
225
|
-
|
225
|
+
described_class.define(:asn16, "0 60000", "whois.test")
|
226
226
|
expect {
|
227
|
-
|
227
|
+
described_class.guess("AS65535")
|
228
228
|
}.to raise_error(Whois::AllocationUnknown)
|
229
229
|
end
|
230
230
|
end
|
@@ -233,16 +233,16 @@ describe Whois::Server do
|
|
233
233
|
context "when the input is an asn32" do
|
234
234
|
it "lookups definitions and returns the adapter" do
|
235
235
|
with_definitions do
|
236
|
-
|
237
|
-
expect(
|
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
238
|
end
|
239
239
|
end
|
240
240
|
|
241
241
|
it "raises if definition is not found" do
|
242
242
|
with_definitions do
|
243
|
-
|
243
|
+
described_class.define(:asn32, "65536 131071", "whois.test")
|
244
244
|
expect {
|
245
|
-
|
245
|
+
described_class.guess("AS200000")
|
246
246
|
}.to raise_error(Whois::AllocationUnknown)
|
247
247
|
end
|
248
248
|
end
|
@@ -251,16 +251,16 @@ describe Whois::Server do
|
|
251
251
|
context "when the input is a ipv4" do
|
252
252
|
it "lookups definitions and returns the adapter" do
|
253
253
|
with_definitions do
|
254
|
-
|
255
|
-
expect(
|
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
256
|
end
|
257
257
|
end
|
258
258
|
|
259
259
|
it "raises if definition is not found" do
|
260
260
|
with_definitions do
|
261
|
-
|
261
|
+
described_class.define(:ipv4, "192.168.1.0/10", "whois.test")
|
262
262
|
expect {
|
263
|
-
|
263
|
+
described_class.guess("192.192.0.1")
|
264
264
|
}.to raise_error(Whois::AllocationUnknown)
|
265
265
|
end
|
266
266
|
end
|
@@ -269,31 +269,31 @@ describe Whois::Server do
|
|
269
269
|
context "when the input is a ipv6" do
|
270
270
|
it "lookups definitions and returns the adapter" do
|
271
271
|
with_definitions do
|
272
|
-
|
273
|
-
expect(
|
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
274
|
end
|
275
275
|
end
|
276
276
|
|
277
277
|
it "raises if definition is not found" do
|
278
278
|
with_definitions do
|
279
|
-
|
279
|
+
described_class.define(:ipv6, "::1", "whois.test")
|
280
280
|
expect {
|
281
|
-
|
281
|
+
described_class.guess("2002:0300::1")
|
282
282
|
}.to raise_error(Whois::AllocationUnknown)
|
283
283
|
end
|
284
284
|
end
|
285
285
|
|
286
286
|
it "recognizes ipv4 compatibility mode" do
|
287
287
|
with_definitions do
|
288
|
-
|
289
|
-
expect(
|
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
290
|
end
|
291
291
|
end
|
292
292
|
|
293
293
|
it "rescues IPAddr ArgumentError", issue: "weppos/whois#174" do
|
294
294
|
with_definitions do
|
295
295
|
expect {
|
296
|
-
|
296
|
+
described_class.guess("f53")
|
297
297
|
}.to raise_error(Whois::AllocationUnknown)
|
298
298
|
end
|
299
299
|
end
|
data/spec/whois/whois_spec.rb
CHANGED
data/utils/deftld.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whois
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.
|
4
|
+
version: 6.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simone Carletti
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rake
|
@@ -61,12 +60,11 @@ executables:
|
|
61
60
|
- whoisrb
|
62
61
|
extensions: []
|
63
62
|
extra_rdoc_files:
|
64
|
-
- LICENSE.txt
|
65
63
|
- ".yardopts"
|
64
|
+
- LICENSE.txt
|
66
65
|
files:
|
67
66
|
- ".github/FUNDING.yml"
|
68
67
|
- ".github/dependabot.yml"
|
69
|
-
- ".github/workflows/codeql-analysis.yml"
|
70
68
|
- ".github/workflows/release.yml"
|
71
69
|
- ".github/workflows/tests.yml"
|
72
70
|
- ".gitignore"
|
@@ -77,7 +75,6 @@ files:
|
|
77
75
|
- ".simplecov"
|
78
76
|
- ".tool-versions"
|
79
77
|
- ".yardopts"
|
80
|
-
- 4.0-Upgrade.md
|
81
78
|
- CHANGELOG.md
|
82
79
|
- CONTRIBUTING.md
|
83
80
|
- Gemfile
|
@@ -152,7 +149,6 @@ homepage: https://whoisrb.org/
|
|
152
149
|
licenses:
|
153
150
|
- MIT
|
154
151
|
metadata: {}
|
155
|
-
post_install_message:
|
156
152
|
rdoc_options: []
|
157
153
|
require_paths:
|
158
154
|
- lib
|
@@ -167,8 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
163
|
- !ruby/object:Gem::Version
|
168
164
|
version: '0'
|
169
165
|
requirements: []
|
170
|
-
rubygems_version: 3.
|
171
|
-
signing_key:
|
166
|
+
rubygems_version: 3.6.9
|
172
167
|
specification_version: 4
|
173
168
|
summary: An intelligent pure Ruby WHOIS client and parser.
|
174
169
|
test_files: []
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# For most projects, this workflow file will not need changing; you simply need
|
2
|
-
# to commit it to your repository.
|
3
|
-
#
|
4
|
-
# You may wish to alter this file to override the set of languages analyzed,
|
5
|
-
# or to provide custom queries or build logic.
|
6
|
-
name: "CodeQL"
|
7
|
-
|
8
|
-
on:
|
9
|
-
push:
|
10
|
-
branches: [ main ]
|
11
|
-
pull_request:
|
12
|
-
# The branches below must be a subset of the branches above
|
13
|
-
branches: [ main ]
|
14
|
-
schedule:
|
15
|
-
- cron: '39 4 * * 0'
|
16
|
-
|
17
|
-
jobs:
|
18
|
-
analyze:
|
19
|
-
name: Analyze
|
20
|
-
runs-on: ubuntu-latest
|
21
|
-
permissions:
|
22
|
-
actions: read
|
23
|
-
contents: read
|
24
|
-
security-events: write
|
25
|
-
|
26
|
-
strategy:
|
27
|
-
fail-fast: false
|
28
|
-
matrix:
|
29
|
-
language: [ 'ruby' ]
|
30
|
-
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
31
|
-
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
32
|
-
|
33
|
-
steps:
|
34
|
-
- name: Checkout repository
|
35
|
-
uses: actions/checkout@v4
|
36
|
-
|
37
|
-
# Initializes the CodeQL tools for scanning.
|
38
|
-
- name: Initialize CodeQL
|
39
|
-
uses: github/codeql-action/init@v3
|
40
|
-
with:
|
41
|
-
languages: ${{ matrix.language }}
|
42
|
-
# If you wish to specify custom queries, you can do so here or in a config file.
|
43
|
-
# By default, queries listed here will override any specified in a config file.
|
44
|
-
# Prefix the list here with "+" to use these queries and those in the config file.
|
45
|
-
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
46
|
-
|
47
|
-
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
48
|
-
# If this step fails, then you should remove it and run the build manually (see below)
|
49
|
-
- name: Autobuild
|
50
|
-
uses: github/codeql-action/autobuild@v3
|
51
|
-
|
52
|
-
# ℹ️ Command-line programs to run using the OS shell.
|
53
|
-
# 📚 https://git.io/JvXDl
|
54
|
-
|
55
|
-
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
56
|
-
# and modify them (or add more) to build your code if your project
|
57
|
-
# uses a compiled language
|
58
|
-
|
59
|
-
#- run: |
|
60
|
-
# make bootstrap
|
61
|
-
# make release
|
62
|
-
|
63
|
-
- name: Perform CodeQL Analysis
|
64
|
-
uses: github/codeql-action/analyze@v3
|
data/4.0-Upgrade.md
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
# Welcome to Whois 4.0!
|
2
|
-
|
3
|
-
Whois 4 is a major upgrade compared to Whois 3. This library is now 7 years old, enough mature to offer pretty much all the features you need to perform WHOIS queries.
|
4
|
-
|
5
|
-
In these last 7 years the adoption of this library has grown beyond any expectation. Most of the time was spent updating the definitions to stay up to date with the various registrar changes (thanks ICANN for thew newGLTDs...), updating the registry parsers and polishing up the public interface.
|
6
|
-
|
7
|
-
For Whois 4 I decided to take a step back, and rewrite some of the internal components of this library to improve performance and readability. As a result of these changes, there are several compatibility breaks with Whois 4 that I'm going to document here.
|
8
|
-
|
9
|
-
-- Simone
|
10
|
-
|
11
|
-
## What's New
|
12
|
-
|
13
|
-
- The Whois client and the Whois parser are now two separate repositories, and they are also distributed as two separate gems:
|
14
|
-
|
15
|
-
- https://github.com/weppos/whois - https://rubygems.org/gems/whois
|
16
|
-
- https://github.com/weppos/whois-parser https://rubygems.org/gems/whois-parser
|
17
|
-
|
18
|
-
There are several reasons behind this change (see [weppos/whois#503](https://github.com/weppos/whois/pull/503)).
|
19
|
-
|
20
|
-
First of all, the maintenance of the whois-parser component is the most time consuming task. Updating a parser may require from a few minutes to several hours, depending on how big are the changes. It also requires to generate the appropriate fixtures, and write the necessary tests. In the last years I noticed that more than once client updates were delayed because of pending parser changes. Separating the repositories and the release cycles will likely speedup future released of the client gem.
|
21
|
-
|
22
|
-
Moreover, the parser component takes a lot of space (due to all the files and fixtures). If you just need a Ruby whois client, loading the entire parser component is inefficient and a waste of time/CPU/resources.
|
23
|
-
|
24
|
-
Last but not least, in the last years the Whois client inspired several ports in different languages. Most of these ports were not interested in porting the parser as well. However, the parser was so tightly coupled with the client that it made the client code harder to read.
|
25
|
-
|
26
|
-
- The definition files have been largely redesigned, in particular the TLD file. The definitions are now maintained using a set of CLI tools. The goal is to eventually extract the definition files into a separate, standalone repository that other WHOIS libraries can easily fetch.
|
27
|
-
|
28
|
-
## Upgrade
|
29
|
-
|
30
|
-
When upgrading, here's the most relevant changes to keep an eye on:
|
31
|
-
|
32
|
-
- If you are using the Whois parser, install and require the `whois-parser` gem. The parser will automatically download the appropriate `whois` dependency.
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
require 'whois-parser'
|
36
|
-
```
|
37
|
-
|
38
|
-
If you only need the client and you don't care about the parser, simply continue to require the `whois` gem directly.
|
39
|
-
|
40
|
-
```ruby
|
41
|
-
require 'whois'
|
42
|
-
```
|
43
|
-
|
44
|
-
- `Whois::Server.definitions` no longer return the internal definitions. Definitions are no longer accessible directly, because their internal representation may change at any time. If you need to modify the definitions, use the public API.
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
Whois::Server.define(Whois::Server::TYPE_TLD, ...)
|
48
|
-
```
|
49
|
-
|
50
|
-
You can still use `Whois::Server.definitions`, but it will return a copy of the internal definitions, and you have to specify which type of definitions you want to access.
|
51
|
-
|
52
|
-
```ruby
|
53
|
-
Whois::Server.definitions(Whois::Server::TYPE_TLD)
|
54
|
-
```
|
55
|
-
|
56
|
-
- **The parser methods are no longer accessible directly within the response object.**
|
57
|
-
|
58
|
-
This is probably one of the most important changes, and it is explained in details at [weppos/whois-parser#5](https://github.com/weppos/whois-parser/pull/5).
|
59
|
-
|
60
|
-
In Whois 3, you can invoke a property method on a record object and the record will automatically route the method call to the underlying parser. If the property is not supported or defined in any of the parsers, then the method will return nil.
|
61
|
-
|
62
|
-
However, this behavior is often the cause of confusion and misunderstandings, especially for partially implemented parsers. Without to mention that the code required for this feature to work added an extra layer of complexity to the `Whois::Record` implementation.
|
63
|
-
|
64
|
-
Starting from Whois 4, the `Whois::Record` doesn't expose any parsing methods anymore. If you want to parse a record, you have to istantiate a parser manually. Of course, you also need to use the `whois-parser` library instead of `whois`.
|
65
|
-
|
66
|
-
Whois 3:
|
67
|
-
|
68
|
-
```ruby
|
69
|
-
require 'whois-parser'
|
70
|
-
|
71
|
-
record = Whois.whois("example.it")
|
72
|
-
record.expires_on
|
73
|
-
```
|
74
|
-
|
75
|
-
Whois 4:
|
76
|
-
|
77
|
-
```ruby
|
78
|
-
require 'whois-parser'
|
79
|
-
|
80
|
-
record = Whois.whois("example.it")
|
81
|
-
parser = Whois::Parser.new(record)
|
82
|
-
parser.expires_on
|
83
|
-
```
|
84
|
-
|
85
|
-
You can still use the convenient helper `record.parser` to initialize a parser:
|
86
|
-
|
87
|
-
```ruby
|
88
|
-
require 'whois-parser'
|
89
|
-
|
90
|
-
record = Whois.whois("example.it")
|
91
|
-
record.parser.expires_on
|
92
|
-
```
|
93
|
-
|
94
|
-
Also note that any parser method, such as `parser.expires_on`, will raise an error if the property is not implemented, as opposite to silently returning `nil` as it was in Whois 3.
|
95
|
-
|
96
|
-
- **Parser extensions**
|
97
|
-
|
98
|
-
The Parser features available in Whois 3 has been packaged into several extensions. Some of them are loaded by default in Whois 4 when you require `whois-parser`, others not anymore. The reason is because although some of them may appear convenient (because it makes you write more code), it turned out that they made some assumptions that were often source of confusion.
|
99
|
-
|
100
|
-
Check the header of the [`whois/parser.rb`](https://github.com/weppos/whois-parser/blob/master/lib/whois/parser.rb) file to learn more about the purpose of each extension.
|
101
|
-
|
102
|
-
Requiring **all** the extensions will essentially force Whois 4 to work pretty much like Whois 3. This is not recommended, and you should not rely on those extensions to be there forever. Instead, you should write the code depending on what you actually need.
|
103
|
-
|
104
|
-
There is also an ENV variable you can set to rollback compatibility to Whois 3.
|
105
|
-
|
106
|
-
```ruby
|
107
|
-
ENV["WHOISRB_4EXTENSIONS"] = 1
|
108
|
-
```
|
109
|
-
|
110
|
-
Again, this flag exists only as temporary helper, and it should not become a permanent upgrade workaround.
|
111
|
-
|
112
|
-
- **SafeRecord**
|
113
|
-
|
114
|
-
In the previous point I mentioned that you should write the code you need to customize the `Whois::Record` and extract information with the `Whois::Parser`. However, I omitted an important additional recommendation: avoid monkey patching the Whois::Record object, and instead prefer composition via delegation.
|
115
|
-
|
116
|
-
The SafeRecord is an example of a wrapper around a Record object, that expose a Whois 3 alike interface, without injecting the parser methods directly into the `Whois::Record` itself.
|
117
|
-
|
118
|
-
The advantages are:
|
119
|
-
|
120
|
-
- the code is more maintainable, as it is not tighlty coupled to the Whois::Record
|
121
|
-
- you don't monkey patch `Whois::Record` in your code, which is an object you don't have control of because it is packaged in a third party library (and can change)
|
122
|
-
- the library can easily be tested separately
|
123
|
-
|
124
|
-
In these 10 years of writing Ruby code, I've noticed an increasing attitude to monkey patch Ruby classes you don't control, instead of writing your own code and delegate to them. It looks like in several cases Ruby programmers are afraid of writing Ruby code. This results in very fragile code, where methods can easily conflict each other (especially between dependencies).
|
125
|
-
|
126
|
-
The `Whois::SafeRecord` is an alternative example of how you can restore Whois 3 behavior by using a custom object.
|
127
|
-
|
128
|
-
```ruby
|
129
|
-
require 'whois/parser'
|
130
|
-
require 'whois/safe_record'
|
131
|
-
|
132
|
-
record = Whois.whois('example.com')
|
133
|
-
record.disclaimer
|
134
|
-
# => Whois::AttributeNotSupported
|
135
|
-
|
136
|
-
safe_record = Whois::SafeRecord.new(record)
|
137
|
-
safe_record.disclaimer
|
138
|
-
# => nil
|
139
|
-
```
|
140
|
-
|
141
|
-
This is preferred over requiring the `whois/parser_extensions` or enabling v3 compatibility mode.
|
142
|
-
|
143
|
-
Please note that the parser extension is provided as example. It may be removed from future versions therefore, once again, you should write the code you need to access the parsed data.
|