net-imap 0.4.12 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +8 -1
- data/README.md +10 -4
- data/docs/styles.css +75 -14
- data/lib/net/imap/authenticators.rb +2 -2
- data/lib/net/imap/command_data.rb +61 -48
- data/lib/net/imap/config/attr_accessors.rb +75 -0
- data/lib/net/imap/config/attr_inheritance.rb +90 -0
- data/lib/net/imap/config/attr_type_coercion.rb +61 -0
- data/lib/net/imap/config.rb +470 -0
- data/lib/net/imap/data_encoding.rb +3 -3
- data/lib/net/imap/data_lite.rb +226 -0
- data/lib/net/imap/deprecated_client_options.rb +8 -5
- data/lib/net/imap/errors.rb +6 -0
- data/lib/net/imap/esearch_result.rb +180 -0
- data/lib/net/imap/fetch_data.rb +126 -47
- data/lib/net/imap/response_data.rb +124 -237
- data/lib/net/imap/response_parser/parser_utils.rb +11 -6
- data/lib/net/imap/response_parser.rb +187 -34
- data/lib/net/imap/sasl/anonymous_authenticator.rb +3 -3
- data/lib/net/imap/sasl/authentication_exchange.rb +52 -20
- data/lib/net/imap/sasl/authenticators.rb +8 -4
- data/lib/net/imap/sasl/client_adapter.rb +77 -26
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +4 -4
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +218 -56
- data/lib/net/imap/sasl/external_authenticator.rb +2 -2
- data/lib/net/imap/sasl/gs2_header.rb +7 -7
- data/lib/net/imap/sasl/login_authenticator.rb +4 -3
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +6 -6
- data/lib/net/imap/sasl/plain_authenticator.rb +7 -7
- data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
- data/lib/net/imap/sasl/scram_authenticator.rb +8 -8
- data/lib/net/imap/sasl.rb +7 -4
- data/lib/net/imap/sasl_adapter.rb +0 -1
- data/lib/net/imap/search_result.rb +2 -2
- data/lib/net/imap/sequence_set.rb +221 -82
- data/lib/net/imap/stringprep/nameprep.rb +1 -1
- data/lib/net/imap/stringprep/trace.rb +4 -4
- data/lib/net/imap/uidplus_data.rb +244 -0
- data/lib/net/imap/vanished_data.rb +56 -0
- data/lib/net/imap.rb +1010 -320
- data/net-imap.gemspec +3 -3
- data/rakelib/rfcs.rake +2 -0
- data/rakelib/string_prep_tables_generator.rb +2 -0
- metadata +12 -10
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/pages.yml +0 -46
- data/.github/workflows/push_gem.yml +0 -48
- data/.github/workflows/test.yml +0 -31
- data/.gitignore +0 -12
- data/.mailmap +0 -13
@@ -0,0 +1,470 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "config/attr_accessors"
|
4
|
+
require_relative "config/attr_inheritance"
|
5
|
+
require_relative "config/attr_type_coercion"
|
6
|
+
|
7
|
+
module Net
|
8
|
+
class IMAP
|
9
|
+
|
10
|
+
# Net::IMAP::Config <em>(available since +v0.4.13+)</em> stores
|
11
|
+
# configuration options for Net::IMAP clients. The global configuration can
|
12
|
+
# be seen at either Net::IMAP.config or Net::IMAP::Config.global, and the
|
13
|
+
# client-specific configuration can be seen at Net::IMAP#config.
|
14
|
+
#
|
15
|
+
# When creating a new client, all unhandled keyword arguments to
|
16
|
+
# Net::IMAP.new are delegated to Config.new. Every client has its own
|
17
|
+
# config.
|
18
|
+
#
|
19
|
+
# debug_client = Net::IMAP.new(hostname, debug: true)
|
20
|
+
# quiet_client = Net::IMAP.new(hostname, debug: false)
|
21
|
+
# debug_client.config.debug? # => true
|
22
|
+
# quiet_client.config.debug? # => false
|
23
|
+
#
|
24
|
+
# == Inheritance
|
25
|
+
#
|
26
|
+
# Configs have a parent[rdoc-ref:Config::AttrInheritance#parent] config, and
|
27
|
+
# any attributes which have not been set locally will inherit the parent's
|
28
|
+
# value. Every client creates its own specific config. By default, client
|
29
|
+
# configs inherit from Config.global.
|
30
|
+
#
|
31
|
+
# plain_client = Net::IMAP.new(hostname)
|
32
|
+
# debug_client = Net::IMAP.new(hostname, debug: true)
|
33
|
+
# quiet_client = Net::IMAP.new(hostname, debug: false)
|
34
|
+
#
|
35
|
+
# plain_client.config.inherited?(:debug) # => true
|
36
|
+
# debug_client.config.inherited?(:debug) # => false
|
37
|
+
# quiet_client.config.inherited?(:debug) # => false
|
38
|
+
#
|
39
|
+
# plain_client.config.debug? # => false
|
40
|
+
# debug_client.config.debug? # => true
|
41
|
+
# quiet_client.config.debug? # => false
|
42
|
+
#
|
43
|
+
# # Net::IMAP.debug is delegated to Net::IMAP::Config.global.debug
|
44
|
+
# Net::IMAP.debug = true
|
45
|
+
# plain_client.config.debug? # => true
|
46
|
+
# debug_client.config.debug? # => true
|
47
|
+
# quiet_client.config.debug? # => false
|
48
|
+
#
|
49
|
+
# Net::IMAP.debug = false
|
50
|
+
# plain_client.config.debug = true
|
51
|
+
# plain_client.config.inherited?(:debug) # => false
|
52
|
+
# plain_client.config.debug? # => true
|
53
|
+
# plain_client.config.reset(:debug)
|
54
|
+
# plain_client.config.inherited?(:debug) # => true
|
55
|
+
# plain_client.config.debug? # => false
|
56
|
+
#
|
57
|
+
# == Versioned defaults
|
58
|
+
#
|
59
|
+
# The effective default configuration for a specific +x.y+ version of
|
60
|
+
# +net-imap+ can be loaded with the +config+ keyword argument to
|
61
|
+
# Net::IMAP.new. Requesting default configurations for previous versions
|
62
|
+
# enables extra backward compatibility with those versions:
|
63
|
+
#
|
64
|
+
# client = Net::IMAP.new(hostname, config: 0.3)
|
65
|
+
# client.config.sasl_ir # => false
|
66
|
+
# client.config.responses_without_block # => :silence_deprecation_warning
|
67
|
+
#
|
68
|
+
# client = Net::IMAP.new(hostname, config: 0.4)
|
69
|
+
# client.config.sasl_ir # => true
|
70
|
+
# client.config.responses_without_block # => :silence_deprecation_warning
|
71
|
+
#
|
72
|
+
# client = Net::IMAP.new(hostname, config: 0.5)
|
73
|
+
# client.config.sasl_ir # => true
|
74
|
+
# client.config.responses_without_block # => :warn
|
75
|
+
#
|
76
|
+
# client = Net::IMAP.new(hostname, config: :future)
|
77
|
+
# client.config.sasl_ir # => true
|
78
|
+
# client.config.responses_without_block # => :frozen_dup
|
79
|
+
#
|
80
|
+
# The versioned default configs inherit certain specific config options from
|
81
|
+
# Config.global, for example #debug:
|
82
|
+
#
|
83
|
+
# client = Net::IMAP.new(hostname, config: 0.4)
|
84
|
+
# Net::IMAP.debug = false
|
85
|
+
# client.config.debug? # => false
|
86
|
+
#
|
87
|
+
# Net::IMAP.debug = true
|
88
|
+
# client.config.debug? # => true
|
89
|
+
#
|
90
|
+
# Use #load_defaults to globally behave like a specific version:
|
91
|
+
# client = Net::IMAP.new(hostname)
|
92
|
+
# client.config.sasl_ir # => true
|
93
|
+
# Net::IMAP.config.load_defaults 0.3
|
94
|
+
# client.config.sasl_ir # => false
|
95
|
+
#
|
96
|
+
# === Named defaults
|
97
|
+
# In addition to +x.y+ version numbers, the following aliases are supported:
|
98
|
+
#
|
99
|
+
# [+:default+]
|
100
|
+
# An alias for +:current+.
|
101
|
+
#
|
102
|
+
# >>>
|
103
|
+
# *NOTE*: This is _not_ the same as Config.default. It inherits some
|
104
|
+
# attributes from Config.global, for example: #debug.
|
105
|
+
# [+:current+]
|
106
|
+
# An alias for the current +x.y+ version's defaults.
|
107
|
+
# [+:next+]
|
108
|
+
# The _planned_ config for the next +x.y+ version.
|
109
|
+
# [+:future+]
|
110
|
+
# The _planned_ eventual config for some future +x.y+ version.
|
111
|
+
#
|
112
|
+
# For example, to disable all currently deprecated behavior:
|
113
|
+
# client = Net::IMAP.new(hostname, config: :future)
|
114
|
+
# client.config.response_without_args # => :frozen_dup
|
115
|
+
# client.responses.frozen? # => true
|
116
|
+
# client.responses.values.all?(&:frozen?) # => true
|
117
|
+
#
|
118
|
+
# == Thread Safety
|
119
|
+
#
|
120
|
+
# *NOTE:* Updates to config objects are not synchronized for thread-safety.
|
121
|
+
#
|
122
|
+
class Config
|
123
|
+
# Array of attribute names that are _not_ loaded by #load_defaults.
|
124
|
+
DEFAULT_TO_INHERIT = %i[debug].freeze
|
125
|
+
private_constant :DEFAULT_TO_INHERIT
|
126
|
+
|
127
|
+
# The default config, which is hardcoded and frozen.
|
128
|
+
def self.default; @default end
|
129
|
+
|
130
|
+
# The global config object. Also available from Net::IMAP.config.
|
131
|
+
def self.global; @global if defined?(@global) end
|
132
|
+
|
133
|
+
# A hash of hard-coded configurations, indexed by version number or name.
|
134
|
+
def self.version_defaults; @version_defaults end
|
135
|
+
@version_defaults = {}
|
136
|
+
|
137
|
+
# :call-seq:
|
138
|
+
# Net::IMAP::Config[number] -> versioned config
|
139
|
+
# Net::IMAP::Config[symbol] -> named config
|
140
|
+
# Net::IMAP::Config[hash] -> new frozen config
|
141
|
+
# Net::IMAP::Config[config] -> same config
|
142
|
+
#
|
143
|
+
# Given a version number, returns the default configuration for the target
|
144
|
+
# version. See Config@Versioned+defaults.
|
145
|
+
#
|
146
|
+
# Given a version name, returns the default configuration for the target
|
147
|
+
# version. See Config@Named+defaults.
|
148
|
+
#
|
149
|
+
# Given a Hash, creates a new _frozen_ config which inherits from
|
150
|
+
# Config.global. Use Config.new for an unfrozen config.
|
151
|
+
#
|
152
|
+
# Given a config, returns that same config.
|
153
|
+
def self.[](config)
|
154
|
+
if config.is_a?(Config) then config
|
155
|
+
elsif config.nil? && global.nil? then nil
|
156
|
+
elsif config.respond_to?(:to_hash) then new(global, **config).freeze
|
157
|
+
else
|
158
|
+
version_defaults.fetch(config) do
|
159
|
+
case config
|
160
|
+
when Numeric
|
161
|
+
raise RangeError, "unknown config version: %p" % [config]
|
162
|
+
when Symbol
|
163
|
+
raise KeyError, "unknown config name: %p" % [config]
|
164
|
+
else
|
165
|
+
raise TypeError, "no implicit conversion of %s to %s" % [
|
166
|
+
config.class, Config
|
167
|
+
]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
include AttrAccessors
|
174
|
+
include AttrInheritance
|
175
|
+
include AttrTypeCoercion
|
176
|
+
|
177
|
+
# The debug mode (boolean). The default value is +false+.
|
178
|
+
#
|
179
|
+
# When #debug is +true+:
|
180
|
+
# * Data sent to and received from the server will be logged.
|
181
|
+
# * ResponseParser will print warnings with extra detail for parse
|
182
|
+
# errors. _This may include recoverable errors._
|
183
|
+
# * ResponseParser makes extra assertions.
|
184
|
+
#
|
185
|
+
# *NOTE:* Versioned default configs inherit #debug from Config.global, and
|
186
|
+
# #load_defaults will not override #debug.
|
187
|
+
attr_accessor :debug, type: :boolean
|
188
|
+
|
189
|
+
# method: debug?
|
190
|
+
# :call-seq: debug? -> boolean
|
191
|
+
#
|
192
|
+
# Alias for #debug
|
193
|
+
|
194
|
+
# Seconds to wait until a connection is opened.
|
195
|
+
#
|
196
|
+
# If the IMAP object cannot open a connection within this time,
|
197
|
+
# it raises a Net::OpenTimeout exception.
|
198
|
+
#
|
199
|
+
# See Net::IMAP.new.
|
200
|
+
#
|
201
|
+
# The default value is +30+ seconds.
|
202
|
+
attr_accessor :open_timeout, type: Integer
|
203
|
+
|
204
|
+
# Seconds to wait until an IDLE response is received, after
|
205
|
+
# the client asks to leave the IDLE state.
|
206
|
+
#
|
207
|
+
# See Net::IMAP#idle and Net::IMAP#idle_done.
|
208
|
+
#
|
209
|
+
# The default value is +5+ seconds.
|
210
|
+
attr_accessor :idle_response_timeout, type: Integer
|
211
|
+
|
212
|
+
# Whether to use the +SASL-IR+ extension when the server and \SASL
|
213
|
+
# mechanism both support it. Can be overridden by the +sasl_ir+ keyword
|
214
|
+
# parameter to Net::IMAP#authenticate.
|
215
|
+
#
|
216
|
+
# <em>(Support for +SASL-IR+ was added in +v0.4.0+.)</em>
|
217
|
+
#
|
218
|
+
# ==== Valid options
|
219
|
+
#
|
220
|
+
# [+false+ <em>(original behavior, before support was added)</em>]
|
221
|
+
# Do not use +SASL-IR+, even when it is supported by the server and the
|
222
|
+
# mechanism.
|
223
|
+
#
|
224
|
+
# [+true+ <em>(default since +v0.4+)</em>]
|
225
|
+
# Use +SASL-IR+ when it is supported by the server and the mechanism.
|
226
|
+
attr_accessor :sasl_ir, type: :boolean
|
227
|
+
|
228
|
+
# Controls the behavior of Net::IMAP#login when the +LOGINDISABLED+
|
229
|
+
# capability is present. When enforced, Net::IMAP will raise a
|
230
|
+
# LoginDisabledError when that capability is present.
|
231
|
+
#
|
232
|
+
# <em>(Support for +LOGINDISABLED+ was added in +v0.5.0+.)</em>
|
233
|
+
#
|
234
|
+
# ==== Valid options
|
235
|
+
#
|
236
|
+
# [+false+ <em>(original behavior, before support was added)</em>]
|
237
|
+
# Send the +LOGIN+ command without checking for +LOGINDISABLED+.
|
238
|
+
#
|
239
|
+
# [+:when_capabilities_cached+]
|
240
|
+
# Enforce the requirement when Net::IMAP#capabilities_cached? is true,
|
241
|
+
# but do not send a +CAPABILITY+ command to discover the capabilities.
|
242
|
+
#
|
243
|
+
# [+true+ <em>(default since +v0.5+)</em>]
|
244
|
+
# Only send the +LOGIN+ command if the +LOGINDISABLED+ capability is not
|
245
|
+
# present. When capabilities are unknown, Net::IMAP will automatically
|
246
|
+
# send a +CAPABILITY+ command first before sending +LOGIN+.
|
247
|
+
#
|
248
|
+
attr_accessor :enforce_logindisabled, type: [
|
249
|
+
false, :when_capabilities_cached, true
|
250
|
+
]
|
251
|
+
|
252
|
+
# Controls the behavior of Net::IMAP#responses when called without any
|
253
|
+
# arguments (+type+ or +block+).
|
254
|
+
#
|
255
|
+
# ==== Valid options
|
256
|
+
#
|
257
|
+
# [+:silence_deprecation_warning+ <em>(original behavior)</em>]
|
258
|
+
# Returns the mutable responses hash (without any warnings).
|
259
|
+
# <em>This is not thread-safe.</em>
|
260
|
+
#
|
261
|
+
# [+:warn+ <em>(default since +v0.5+)</em>]
|
262
|
+
# Prints a warning and returns the mutable responses hash.
|
263
|
+
# <em>This is not thread-safe.</em>
|
264
|
+
#
|
265
|
+
# [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
|
266
|
+
# Returns a frozen copy of the unhandled responses hash, with frozen
|
267
|
+
# array values.
|
268
|
+
#
|
269
|
+
# Note that calling IMAP#responses with a +type+ and without a block is
|
270
|
+
# not configurable and always behaves like +:frozen_dup+.
|
271
|
+
#
|
272
|
+
# <em>(+:frozen_dup+ config option was added in +v0.4.17+)</em>
|
273
|
+
#
|
274
|
+
# [+:raise+]
|
275
|
+
# Raise an ArgumentError with the deprecation warning.
|
276
|
+
#
|
277
|
+
# Note: #responses_without_args is an alias for #responses_without_block.
|
278
|
+
attr_accessor :responses_without_block, type: [
|
279
|
+
:silence_deprecation_warning, :warn, :frozen_dup, :raise,
|
280
|
+
]
|
281
|
+
|
282
|
+
alias responses_without_args responses_without_block # :nodoc:
|
283
|
+
alias responses_without_args= responses_without_block= # :nodoc:
|
284
|
+
|
285
|
+
##
|
286
|
+
# :attr_accessor: responses_without_args
|
287
|
+
#
|
288
|
+
# Alias for responses_without_block
|
289
|
+
|
290
|
+
# Whether ResponseParser should use the deprecated UIDPlusData or
|
291
|
+
# CopyUIDData for +COPYUID+ response codes, and UIDPlusData or
|
292
|
+
# AppendUIDData for +APPENDUID+ response codes.
|
293
|
+
#
|
294
|
+
# UIDPlusData stores its data in arrays of numbers, which is vulnerable to
|
295
|
+
# a memory exhaustion denial of service attack from an untrusted or
|
296
|
+
# compromised server. Set this option to +false+ to completely block this
|
297
|
+
# vulnerability. Otherwise, parser_max_deprecated_uidplus_data_size
|
298
|
+
# mitigates this vulnerability.
|
299
|
+
#
|
300
|
+
# AppendUIDData and CopyUIDData are _mostly_ backward-compatible with
|
301
|
+
# UIDPlusData. Most applications should be able to upgrade with little
|
302
|
+
# or no changes.
|
303
|
+
#
|
304
|
+
# <em>(Parser support for +UIDPLUS+ added in +v0.3.2+.)</em>
|
305
|
+
#
|
306
|
+
# <em>(Config option added in +v0.4.19+ and +v0.5.6+.)</em>
|
307
|
+
#
|
308
|
+
# <em>UIDPlusData will be removed in +v0.6+ and this config setting will
|
309
|
+
# be ignored.</em>
|
310
|
+
#
|
311
|
+
# ==== Valid options
|
312
|
+
#
|
313
|
+
# [+true+ <em>(original default)</em>]
|
314
|
+
# ResponseParser only uses UIDPlusData.
|
315
|
+
#
|
316
|
+
# [+:up_to_max_size+ <em>(default since +v0.5.6+)</em>]
|
317
|
+
# ResponseParser uses UIDPlusData when the +uid-set+ size is below
|
318
|
+
# parser_max_deprecated_uidplus_data_size. Above that size,
|
319
|
+
# ResponseParser uses AppendUIDData or CopyUIDData.
|
320
|
+
#
|
321
|
+
# [+false+ <em>(planned default for +v0.6+)</em>]
|
322
|
+
# ResponseParser _only_ uses AppendUIDData and CopyUIDData.
|
323
|
+
attr_accessor :parser_use_deprecated_uidplus_data, type: [
|
324
|
+
true, :up_to_max_size, false
|
325
|
+
]
|
326
|
+
|
327
|
+
# The maximum +uid-set+ size that ResponseParser will parse into
|
328
|
+
# deprecated UIDPlusData. This limit only applies when
|
329
|
+
# parser_use_deprecated_uidplus_data is not +false+.
|
330
|
+
#
|
331
|
+
# <em>(Parser support for +UIDPLUS+ added in +v0.3.2+.)</em>
|
332
|
+
#
|
333
|
+
# <em>Support for limiting UIDPlusData to a maximum size was added in
|
334
|
+
# +v0.3.8+, +v0.4.19+, and +v0.5.6+.</em>
|
335
|
+
#
|
336
|
+
# <em>UIDPlusData will be removed in +v0.6+.</em>
|
337
|
+
#
|
338
|
+
# ==== Versioned Defaults
|
339
|
+
#
|
340
|
+
# Because this limit guards against a remote server causing catastrophic
|
341
|
+
# memory exhaustion, the versioned default (used by #load_defaults) also
|
342
|
+
# applies to versions without the feature.
|
343
|
+
#
|
344
|
+
# * +0.3+ and prior: <tt>10,000</tt>
|
345
|
+
# * +0.4+: <tt>1,000</tt>
|
346
|
+
# * +0.5+: <tt>100</tt>
|
347
|
+
# * +0.6+: <tt>0</tt>
|
348
|
+
#
|
349
|
+
attr_accessor :parser_max_deprecated_uidplus_data_size, type: Integer
|
350
|
+
|
351
|
+
# Creates a new config object and initialize its attribute with +attrs+.
|
352
|
+
#
|
353
|
+
# If +parent+ is not given, the global config is used by default.
|
354
|
+
#
|
355
|
+
# If a block is given, the new config object is yielded to it.
|
356
|
+
def initialize(parent = Config.global, **attrs)
|
357
|
+
super(parent)
|
358
|
+
update(**attrs)
|
359
|
+
yield self if block_given?
|
360
|
+
end
|
361
|
+
|
362
|
+
# :call-seq: update(**attrs) -> self
|
363
|
+
#
|
364
|
+
# Assigns all of the provided +attrs+ to this config, and returns +self+.
|
365
|
+
#
|
366
|
+
# An ArgumentError is raised unless every key in +attrs+ matches an
|
367
|
+
# assignment method on Config.
|
368
|
+
#
|
369
|
+
# >>>
|
370
|
+
# *NOTE:* #update is not atomic. If an exception is raised due to an
|
371
|
+
# invalid attribute value, +attrs+ may be partially applied.
|
372
|
+
def update(**attrs)
|
373
|
+
unless (bad = attrs.keys.reject { respond_to?(:"#{_1}=") }).empty?
|
374
|
+
raise ArgumentError, "invalid config options: #{bad.join(", ")}"
|
375
|
+
end
|
376
|
+
attrs.each do send(:"#{_1}=", _2) end
|
377
|
+
self
|
378
|
+
end
|
379
|
+
|
380
|
+
# :call-seq:
|
381
|
+
# with(**attrs) -> config
|
382
|
+
# with(**attrs) {|config| } -> result
|
383
|
+
#
|
384
|
+
# Without a block, returns a new config which inherits from self. With a
|
385
|
+
# block, yields the new config and returns the block's result.
|
386
|
+
#
|
387
|
+
# If no keyword arguments are given, an ArgumentError will be raised.
|
388
|
+
#
|
389
|
+
# If +self+ is frozen, the copy will also be frozen.
|
390
|
+
def with(**attrs)
|
391
|
+
attrs.empty? and
|
392
|
+
raise ArgumentError, "expected keyword arguments, none given"
|
393
|
+
copy = new(**attrs)
|
394
|
+
copy.freeze if frozen?
|
395
|
+
block_given? ? yield(copy) : copy
|
396
|
+
end
|
397
|
+
|
398
|
+
# :call-seq: load_defaults(version) -> self
|
399
|
+
#
|
400
|
+
# Resets the current config to behave like the versioned default
|
401
|
+
# configuration for +version+. #parent will not be changed.
|
402
|
+
#
|
403
|
+
# Some config attributes default to inheriting from their #parent (which
|
404
|
+
# is usually Config.global) and are left unchanged, for example: #debug.
|
405
|
+
#
|
406
|
+
# See Config@Versioned+defaults and Config@Named+defaults.
|
407
|
+
def load_defaults(version)
|
408
|
+
[Numeric, Symbol, String].any? { _1 === version } or
|
409
|
+
raise ArgumentError, "expected number or symbol, got %p" % [version]
|
410
|
+
update(**Config[version].defaults_hash)
|
411
|
+
end
|
412
|
+
|
413
|
+
# :call-seq: to_h -> hash
|
414
|
+
#
|
415
|
+
# Returns all config attributes in a hash.
|
416
|
+
def to_h; data.members.to_h { [_1, send(_1)] } end
|
417
|
+
|
418
|
+
protected
|
419
|
+
|
420
|
+
def defaults_hash
|
421
|
+
to_h.reject {|k,v| DEFAULT_TO_INHERIT.include?(k) }
|
422
|
+
end
|
423
|
+
|
424
|
+
@default = new(
|
425
|
+
debug: false,
|
426
|
+
open_timeout: 30,
|
427
|
+
idle_response_timeout: 5,
|
428
|
+
sasl_ir: true,
|
429
|
+
enforce_logindisabled: true,
|
430
|
+
responses_without_block: :warn,
|
431
|
+
parser_use_deprecated_uidplus_data: :up_to_max_size,
|
432
|
+
parser_max_deprecated_uidplus_data_size: 100,
|
433
|
+
).freeze
|
434
|
+
|
435
|
+
@global = default.new
|
436
|
+
|
437
|
+
version_defaults[:default] = Config[default.send(:defaults_hash)]
|
438
|
+
version_defaults[:current] = Config[:default]
|
439
|
+
|
440
|
+
version_defaults[0] = Config[:current].dup.update(
|
441
|
+
sasl_ir: false,
|
442
|
+
responses_without_block: :silence_deprecation_warning,
|
443
|
+
enforce_logindisabled: false,
|
444
|
+
parser_use_deprecated_uidplus_data: true,
|
445
|
+
parser_max_deprecated_uidplus_data_size: 10_000,
|
446
|
+
).freeze
|
447
|
+
version_defaults[0.0] = Config[0]
|
448
|
+
version_defaults[0.1] = Config[0]
|
449
|
+
version_defaults[0.2] = Config[0]
|
450
|
+
version_defaults[0.3] = Config[0]
|
451
|
+
|
452
|
+
version_defaults[0.4] = Config[0.3].dup.update(
|
453
|
+
sasl_ir: true,
|
454
|
+
parser_max_deprecated_uidplus_data_size: 1000,
|
455
|
+
).freeze
|
456
|
+
|
457
|
+
version_defaults[0.5] = Config[:current]
|
458
|
+
|
459
|
+
version_defaults[0.6] = Config[0.5].dup.update(
|
460
|
+
responses_without_block: :frozen_dup,
|
461
|
+
parser_use_deprecated_uidplus_data: false,
|
462
|
+
parser_max_deprecated_uidplus_data_size: 0,
|
463
|
+
).freeze
|
464
|
+
version_defaults[:next] = Config[0.6]
|
465
|
+
version_defaults[:future] = Config[:next]
|
466
|
+
|
467
|
+
version_defaults.freeze
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
@@ -186,7 +186,7 @@ module Net
|
|
186
186
|
|
187
187
|
# Ensure argument is 'number' or raise DataFormatError
|
188
188
|
def ensure_number(num)
|
189
|
-
return if valid_number?(num)
|
189
|
+
return num if valid_number?(num)
|
190
190
|
|
191
191
|
msg = "number must be unsigned 32-bit integer: #{num}"
|
192
192
|
raise DataFormatError, msg
|
@@ -194,7 +194,7 @@ module Net
|
|
194
194
|
|
195
195
|
# Ensure argument is 'nz_number' or raise DataFormatError
|
196
196
|
def ensure_nz_number(num)
|
197
|
-
return if valid_nz_number?(num)
|
197
|
+
return num if valid_nz_number?(num)
|
198
198
|
|
199
199
|
msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
|
200
200
|
raise DataFormatError, msg
|
@@ -202,7 +202,7 @@ module Net
|
|
202
202
|
|
203
203
|
# Ensure argument is 'mod_sequence_value' or raise DataFormatError
|
204
204
|
def ensure_mod_sequence_value(num)
|
205
|
-
return if valid_mod_sequence_value?(num)
|
205
|
+
return num if valid_mod_sequence_value?(num)
|
206
206
|
|
207
207
|
msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}"
|
208
208
|
raise DataFormatError, msg
|