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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +5 -7
  3. data/.github/workflows/release.yml +3 -2
  4. data/.github/workflows/tests.yml +5 -4
  5. data/.rubocop.yml +1 -1
  6. data/.rubocop_todo.yml +11 -88
  7. data/.tool-versions +1 -1
  8. data/CHANGELOG.md +14 -0
  9. data/CONTRIBUTING.md +6 -6
  10. data/Gemfile +2 -2
  11. data/bin/whoisrb +3 -3
  12. data/data/tld.json +18 -791
  13. data/lib/whois/client.rb +1 -1
  14. data/lib/whois/record.rb +1 -1
  15. data/lib/whois/server/adapters/arpa.rb +3 -5
  16. data/lib/whois/server/adapters/base.rb +3 -3
  17. data/lib/whois/server/adapters/none.rb +1 -1
  18. data/lib/whois/server/adapters/not_implemented.rb +1 -1
  19. data/lib/whois/server/adapters/web.rb +1 -1
  20. data/lib/whois/server/socket_handler.rb +3 -3
  21. data/lib/whois/server.rb +5 -5
  22. data/lib/whois/version.rb +1 -1
  23. data/lib/whois.rb +18 -18
  24. data/spec/integration/whois_spec.rb +2 -2
  25. data/spec/spec_helper.rb +2 -2
  26. data/spec/whois/client_spec.rb +1 -1
  27. data/spec/whois/record/part_spec.rb +1 -1
  28. data/spec/whois/record_spec.rb +26 -18
  29. data/spec/whois/server/adapters/afilias_spec.rb +1 -1
  30. data/spec/whois/server/adapters/arin_spec.rb +1 -1
  31. data/spec/whois/server/adapters/arpa_spec.rb +2 -2
  32. data/spec/whois/server/adapters/base_spec.rb +17 -12
  33. data/spec/whois/server/adapters/formatted_spec.rb +1 -1
  34. data/spec/whois/server/adapters/none_spec.rb +1 -1
  35. data/spec/whois/server/adapters/not_implemented_spec.rb +2 -2
  36. data/spec/whois/server/adapters/standard_spec.rb +1 -1
  37. data/spec/whois/server/adapters/verisign_spec.rb +1 -1
  38. data/spec/whois/server/adapters/web_spec.rb +1 -1
  39. data/spec/whois/server/socket_handler_spec.rb +9 -5
  40. data/spec/whois/server_spec.rb +51 -51
  41. data/spec/whois/web_interface_error_spec.rb +1 -1
  42. data/spec/whois/whois_spec.rb +1 -1
  43. data/utils/deftld.rb +0 -1
  44. metadata +4 -9
  45. data/.github/workflows/codeql-analysis.yml +0 -64
  46. data/4.0-Upgrade.md +0 -143
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
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
- Whois::Server.define(Whois::Server::TYPE_TLD, "foo", "whois.foo")
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
- Whois::Server.define(Whois::Server::TYPE_TLD, "foo", "whois.foo")
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
- Whois::Server.define(Whois::Server::TYPE_TLD, "foo", "whois.foo", foo: "bar")
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 = Whois::Server.factory(:tld, "test", "whois.test")
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 = Whois::Server.factory(:tld, "test", "whois.test")
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 = Whois::Server.factory(:tld, "test", "whois.test", adapter: a)
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 = Whois::Server.factory(:tld, "test", "whois.test", adapter: :none)
108
+ server = described_class.factory(:tld, "test", "whois.test", adapter: :none)
109
109
  expect(server).to be_a(Whois::Server::Adapters::None)
110
- server = Whois::Server.factory(:tld, "test", "whois.test", adapter: "none")
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 = Whois::Server.factory(:tld, "test", "whois.test", adapter: Whois::Server::Adapters::None, foo: "bar")
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 = Whois::Server.guess(".com")
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 = Whois::Server.guess("example.com")
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 = Whois::Server.guess("127.0.0.1")
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 = Whois::Server.guess("2001:0db8:85a3:0000:0000:8a2e:0370:7334")
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 = Whois::Server.guess("2002::1")
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 = Whois::Server.guess("AS23456")
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 = Whois::Server.guess("AS131072")
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
- Whois::Server.guess("email@example.org")
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
- Whois::Server.guess("invalid")
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(Whois::Server.guess(".com")).to eq(Whois::Server.factory(:tld, ".", "whois.iana.org"))
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(Whois::Server.guess(".xn--fiqs8s")).to eq(Whois::Server.factory(:tld, ".", "whois.iana.org"))
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
- Whois::Server.define(:tld, "test", "whois.test")
190
- expect(Whois::Server.guess("example.test")).to eq(Whois::Server.factory(:tld, "test", "whois.test"))
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
- Whois::Server.define(:tld, "no.com", "whois.no.com")
197
- Whois::Server.define(:tld, "com", "whois.com")
198
- expect(Whois::Server.guess("antoniocangiano.com")).to eq(Whois::Server.factory(:tld, "com", "whois.com"))
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
- Whois::Server.define(:tld, "com", com = "whois.com")
205
- Whois::Server.define(:tld, "com.foo", comfoo = "whois.com.foo")
206
- Whois::Server.define(:tld, "foo.com", foocom = "whois.foo.com")
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(Whois::Server.guess("example.com").host).to eq(com)
209
- expect(Whois::Server.guess("example.com.foo").host).to eq(comfoo)
210
- expect(Whois::Server.guess("example.foo.com").host).to eq(foocom)
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
- Whois::Server.define(:asn16, "0 65535", "whois.test")
219
- expect(Whois::Server.guess("AS65535")).to eq(Whois::Server.factory(:asn16, "0 65535", "whois.test"))
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
- Whois::Server.define(:asn16, "0 60000", "whois.test")
225
+ described_class.define(:asn16, "0 60000", "whois.test")
226
226
  expect {
227
- Whois::Server.guess("AS65535")
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
- Whois::Server.define(:asn32, "65536 394239", "whois.test")
237
- expect(Whois::Server.guess("AS65536")).to eq(Whois::Server.factory(:asn32, "65536 394239", "whois.test"))
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
- Whois::Server.define(:asn32, "65536 131071", "whois.test")
243
+ described_class.define(:asn32, "65536 131071", "whois.test")
244
244
  expect {
245
- Whois::Server.guess("AS200000")
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
- Whois::Server.define(:ipv4, "192.168.1.0/10", "whois.test")
255
- expect(Whois::Server.find_for_ip("192.168.1.1")).to eq(Whois::Server.factory(:ipv4, "192.168.1.0/10", "whois.test"))
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
- Whois::Server.define(:ipv4, "192.168.1.0/10", "whois.test")
261
+ described_class.define(:ipv4, "192.168.1.0/10", "whois.test")
262
262
  expect {
263
- Whois::Server.guess("192.192.0.1")
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
- Whois::Server.define(:ipv6, "2001:0200::/23", "whois.test")
273
- expect(Whois::Server.guess("2001:0200::1")).to eq(Whois::Server.factory(:ipv6, "2001:0200::/23", "whois.test"))
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
- Whois::Server.define(:ipv6, "::1", "whois.test")
279
+ described_class.define(:ipv6, "::1", "whois.test")
280
280
  expect {
281
- Whois::Server.guess("2002:0300::1")
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
- Whois::Server.define(:ipv6, "::192.168.1.1", "whois.test")
289
- expect(Whois::Server.guess("::192.168.1.1")).to eq(Whois::Server.factory(:ipv6, "::192.168.1.1", "whois.test"))
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
- Whois::Server.guess("f53")
296
+ described_class.guess("f53")
297
297
  }.to raise_error(Whois::AllocationUnknown)
298
298
  end
299
299
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe Whois::WebInterfaceError do
6
6
  describe "#initialize" do
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe Whois do
6
6
  describe ".lookup" do
data/utils/deftld.rb CHANGED
@@ -35,7 +35,6 @@ class TldDefs
35
35
  format: :format,
36
36
  url: :url,
37
37
 
38
- group: :_group,
39
38
  note: :_note,
40
39
  type: :_type,
41
40
  }
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.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: 2024-08-05 00:00:00.000000000 Z
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.5.11
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.