net-imap 0.5.12 → 0.6.0
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/Gemfile +2 -1
- data/lib/net/imap/command_data.rb +0 -68
- data/lib/net/imap/config/attr_inheritance.rb +14 -1
- data/lib/net/imap/config/attr_version_defaults.rb +93 -0
- data/lib/net/imap/config.rb +210 -122
- data/lib/net/imap/connection_state.rb +1 -1
- data/lib/net/imap/data_encoding.rb +77 -28
- data/lib/net/imap/esearch_result.rb +6 -0
- data/lib/net/imap/response_data.rb +2 -3
- data/lib/net/imap/response_parser.rb +8 -13
- data/lib/net/imap/search_result.rb +6 -0
- data/lib/net/imap/sequence_set.rb +621 -311
- data/lib/net/imap/uidplus_data.rb +2 -63
- data/lib/net/imap.rb +17 -23
- data/net-imap.gemspec +1 -1
- metadata +4 -4
- data/lib/net/imap/data_lite.rb +0 -226
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 561e6151a9540c8eaa6c12fd16d625061843a053fb0b0c8a2f215eb1a518ef70
|
|
4
|
+
data.tar.gz: 5be61c15097d2e0007822fc6c4825f59795d6078d6cf9b5cbe6ed4dd2bd1d22e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f84a8adf89f177e953fe57e390b027232bc4c7325ecb0049221a88db87fccc76a09281aea87c4f48de05bc547db1248b628b9c271134a466aedba953305001cc
|
|
7
|
+
data.tar.gz: 0b82898fb8581bab9a30c5b3edb96c89d81c4bddf197ade29a25ef166db827983a6c2c25d1eda9989a9f985cfcbec52f4bf484dbc1b57cfde32f432dcd0dfbc3
|
data/Gemfile
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
require "date"
|
|
4
4
|
|
|
5
5
|
require_relative "errors"
|
|
6
|
-
require_relative "data_lite"
|
|
7
6
|
|
|
8
7
|
module Net
|
|
9
8
|
class IMAP < Protocol
|
|
@@ -185,73 +184,6 @@ module Net
|
|
|
185
184
|
end
|
|
186
185
|
end
|
|
187
186
|
|
|
188
|
-
# *DEPRECATED*. Replaced by SequenceSet.
|
|
189
|
-
class MessageSet < CommandData # :nodoc:
|
|
190
|
-
def send_data(imap, tag)
|
|
191
|
-
imap.__send__(:put_string, format_internal(data))
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def validate
|
|
195
|
-
validate_internal(data)
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
private
|
|
199
|
-
|
|
200
|
-
def initialize(data:)
|
|
201
|
-
super
|
|
202
|
-
warn("DEPRECATED: #{MessageSet} should be replaced with #{SequenceSet}.",
|
|
203
|
-
uplevel: 1, category: :deprecated)
|
|
204
|
-
begin
|
|
205
|
-
# to ensure the input works with SequenceSet, too
|
|
206
|
-
SequenceSet.new(data)
|
|
207
|
-
rescue
|
|
208
|
-
warn "MessageSet input is incompatible with SequenceSet: [%s] %s" % [
|
|
209
|
-
$!.class, $!.message
|
|
210
|
-
]
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def format_internal(data)
|
|
215
|
-
case data
|
|
216
|
-
when "*"
|
|
217
|
-
return data
|
|
218
|
-
when Integer
|
|
219
|
-
if data == -1
|
|
220
|
-
return "*"
|
|
221
|
-
else
|
|
222
|
-
return data.to_s
|
|
223
|
-
end
|
|
224
|
-
when Range
|
|
225
|
-
return format_internal(data.first) +
|
|
226
|
-
":" + format_internal(data.last)
|
|
227
|
-
when Array
|
|
228
|
-
return data.collect {|i| format_internal(i)}.join(",")
|
|
229
|
-
when ThreadMember
|
|
230
|
-
return data.seqno.to_s +
|
|
231
|
-
":" + data.children.collect {|i| format_internal(i).join(",")}
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def validate_internal(data)
|
|
236
|
-
case data
|
|
237
|
-
when "*"
|
|
238
|
-
when Integer
|
|
239
|
-
NumValidator.ensure_nz_number(data)
|
|
240
|
-
when Range
|
|
241
|
-
when Array
|
|
242
|
-
data.each do |i|
|
|
243
|
-
validate_internal(i)
|
|
244
|
-
end
|
|
245
|
-
when ThreadMember
|
|
246
|
-
data.children.each do |i|
|
|
247
|
-
validate_internal(i)
|
|
248
|
-
end
|
|
249
|
-
else
|
|
250
|
-
raise DataFormatError, data.inspect
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
|
|
255
187
|
class ClientID < CommandData # :nodoc:
|
|
256
188
|
|
|
257
189
|
def send_data(imap, tag)
|
|
@@ -54,9 +54,22 @@ module Net
|
|
|
54
54
|
# Creates a new config, which inherits from +self+.
|
|
55
55
|
def new(**attrs) self.class.new(self, **attrs) end
|
|
56
56
|
|
|
57
|
+
# :call-seq:
|
|
58
|
+
# inherited?(attr) -> true or false
|
|
59
|
+
# inherited?(*attrs) -> true or false
|
|
60
|
+
# inherited? -> true or false
|
|
61
|
+
#
|
|
57
62
|
# Returns +true+ if +attr+ is inherited from #parent and not overridden
|
|
58
63
|
# by this config.
|
|
59
|
-
|
|
64
|
+
#
|
|
65
|
+
# When multiple +attrs+ are given, returns +true+ if *all* of them are
|
|
66
|
+
# inherited, or +false+ if any of them are overriden. When no +attrs+
|
|
67
|
+
# are given, returns +true+ if *all* attributes are inherited, or
|
|
68
|
+
# +false+ if any attribute is overriden.
|
|
69
|
+
def inherited?(*attrs)
|
|
70
|
+
attrs = data.members if attrs.empty?
|
|
71
|
+
attrs.all? { data[_1] == INHERITED }
|
|
72
|
+
end
|
|
60
73
|
|
|
61
74
|
# :call-seq:
|
|
62
75
|
# reset -> self
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
module Net
|
|
6
|
+
class IMAP
|
|
7
|
+
class Config
|
|
8
|
+
# >>>
|
|
9
|
+
# *NOTE:* This module is an internal implementation detail, with no
|
|
10
|
+
# guarantee of backward compatibility.
|
|
11
|
+
#
|
|
12
|
+
# Adds a +defaults+ parameter to +attr_accessor+, which is used to compile
|
|
13
|
+
# Config.version_defaults.
|
|
14
|
+
module AttrVersionDefaults
|
|
15
|
+
# The <tt>x.y</tt> part of Net::IMAP::VERSION, as a Rational number.
|
|
16
|
+
CURRENT_VERSION = VERSION.to_r
|
|
17
|
+
|
|
18
|
+
# The config version used for <tt>Config[:next]</tt>.
|
|
19
|
+
NEXT_VERSION = CURRENT_VERSION + 0.1r
|
|
20
|
+
|
|
21
|
+
# The config version used for <tt>Config[:future]</tt>.
|
|
22
|
+
FUTURE_VERSION = 1.0r
|
|
23
|
+
|
|
24
|
+
VERSIONS = ((0.0r..FUTURE_VERSION) % 0.1r).to_a.freeze
|
|
25
|
+
|
|
26
|
+
# See Config.version_defaults.
|
|
27
|
+
singleton_class.attr_accessor :version_defaults
|
|
28
|
+
|
|
29
|
+
@version_defaults = Hash.new {|h, k|
|
|
30
|
+
# NOTE: String responds to both so the order is significant.
|
|
31
|
+
# And ignore non-numeric conversion to zero, because: "wat!?".to_r == 0
|
|
32
|
+
(h.fetch(k.to_r, nil) || h.fetch(k.to_f, nil) if k.is_a?(Numeric)) ||
|
|
33
|
+
(h.fetch(k.to_sym, nil) if k.respond_to?(:to_sym)) ||
|
|
34
|
+
(h.fetch(k.to_r, nil) if k.respond_to?(:to_r) && k.to_r != 0r) ||
|
|
35
|
+
(h.fetch(k.to_f, nil) if k.respond_to?(:to_f) && k.to_f != 0.0)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# :stopdoc: internal APIs only
|
|
39
|
+
|
|
40
|
+
def attr_accessor(name, defaults: nil, default: (unset = true), **kw)
|
|
41
|
+
unless unset
|
|
42
|
+
version = DEFAULT_TO_INHERIT.include?(name) ? nil : 0.0r
|
|
43
|
+
defaults = { version => default }
|
|
44
|
+
end
|
|
45
|
+
defaults&.each_pair do |version, default|
|
|
46
|
+
AttrVersionDefaults.version_defaults[version] ||= {}
|
|
47
|
+
AttrVersionDefaults.version_defaults[version][name] = default
|
|
48
|
+
end
|
|
49
|
+
super(name, **kw)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.compile_default!
|
|
53
|
+
raise "Config.default already compiled" if Config.default
|
|
54
|
+
default = VERSIONS.select { _1 <= CURRENT_VERSION }
|
|
55
|
+
.filter_map { version_defaults[_1] }
|
|
56
|
+
.prepend(version_defaults.delete(nil))
|
|
57
|
+
.inject(&:merge)
|
|
58
|
+
Config.new(**default).freeze
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.compile_version_defaults!
|
|
62
|
+
# Temporarily assign Config.default, enabling #load_defaults(:default)
|
|
63
|
+
version_defaults[:default] = Config.default
|
|
64
|
+
# Use #load_defaults so some attributes are inherited from global.
|
|
65
|
+
version_defaults[:default] = Config.new.load_defaults(:default).freeze
|
|
66
|
+
version_defaults[0.0r] = Config[version_defaults.fetch(0.0r)]
|
|
67
|
+
|
|
68
|
+
VERSIONS.each_cons(2) do |prior, version|
|
|
69
|
+
updates = version_defaults[version]
|
|
70
|
+
version_defaults[version] = version_defaults[prior]
|
|
71
|
+
.then { updates ? _1.dup.update(**updates).freeze : _1 }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Safe conversions one way only:
|
|
75
|
+
# 0.6r.to_f == 0.6 # => true
|
|
76
|
+
# 0.6 .to_r == 0.6r # => false
|
|
77
|
+
version_defaults.to_a.each do |k, v|
|
|
78
|
+
next unless k in Rational
|
|
79
|
+
version_defaults[k.to_f] = v
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
version_defaults[:original] = Config[0.0r]
|
|
83
|
+
version_defaults[:current] = Config[CURRENT_VERSION]
|
|
84
|
+
version_defaults[:next] = Config[NEXT_VERSION]
|
|
85
|
+
version_defaults[:future] = Config[FUTURE_VERSION]
|
|
86
|
+
|
|
87
|
+
version_defaults.freeze
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
data/lib/net/imap/config.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "config/attr_accessors"
|
|
4
4
|
require_relative "config/attr_inheritance"
|
|
5
5
|
require_relative "config/attr_type_coercion"
|
|
6
|
+
require_relative "config/attr_version_defaults"
|
|
6
7
|
|
|
7
8
|
module Net
|
|
8
9
|
class IMAP
|
|
@@ -141,15 +142,7 @@ module Net
|
|
|
141
142
|
# Net::IMAP::Config[0.5] == Net::IMAP::Config[0.5r] # => true
|
|
142
143
|
# Net::IMAP::Config["current"] == Net::IMAP::Config[:current] # => true
|
|
143
144
|
# Net::IMAP::Config["0.5.6"] == Net::IMAP::Config[0.5r] # => true
|
|
144
|
-
def self.version_defaults;
|
|
145
|
-
@version_defaults = Hash.new {|h, k|
|
|
146
|
-
# NOTE: String responds to both so the order is significant.
|
|
147
|
-
# And ignore non-numeric conversion to zero, because: "wat!?".to_r == 0
|
|
148
|
-
(h.fetch(k.to_r, nil) || h.fetch(k.to_f, nil) if k.is_a?(Numeric)) ||
|
|
149
|
-
(h.fetch(k.to_sym, nil) if k.respond_to?(:to_sym)) ||
|
|
150
|
-
(h.fetch(k.to_r, nil) if k.respond_to?(:to_r) && k.to_r != 0r) ||
|
|
151
|
-
(h.fetch(k.to_f, nil) if k.respond_to?(:to_f) && k.to_f != 0.0)
|
|
152
|
-
}
|
|
145
|
+
def self.version_defaults; AttrVersionDefaults.version_defaults end
|
|
153
146
|
|
|
154
147
|
# :call-seq:
|
|
155
148
|
# Net::IMAP::Config[number] -> versioned config
|
|
@@ -189,6 +182,7 @@ module Net
|
|
|
189
182
|
include AttrAccessors
|
|
190
183
|
include AttrInheritance
|
|
191
184
|
include AttrTypeCoercion
|
|
185
|
+
extend AttrVersionDefaults
|
|
192
186
|
|
|
193
187
|
# The debug mode (boolean). The default value is +false+.
|
|
194
188
|
#
|
|
@@ -200,7 +194,7 @@ module Net
|
|
|
200
194
|
#
|
|
201
195
|
# *NOTE:* Versioned default configs inherit #debug from Config.global, and
|
|
202
196
|
# #load_defaults will not override #debug.
|
|
203
|
-
attr_accessor :debug, type: :boolean
|
|
197
|
+
attr_accessor :debug, type: :boolean, default: false
|
|
204
198
|
|
|
205
199
|
# method: debug?
|
|
206
200
|
# :call-seq: debug? -> boolean
|
|
@@ -218,7 +212,7 @@ module Net
|
|
|
218
212
|
# See Net::IMAP.new and Net::IMAP#starttls.
|
|
219
213
|
#
|
|
220
214
|
# The default value is +30+ seconds.
|
|
221
|
-
attr_accessor :open_timeout, type: Integer
|
|
215
|
+
attr_accessor :open_timeout, type: Integer, default: 30
|
|
222
216
|
|
|
223
217
|
# Seconds to wait until an IDLE response is received, after
|
|
224
218
|
# the client asks to leave the IDLE state.
|
|
@@ -226,7 +220,7 @@ module Net
|
|
|
226
220
|
# See Net::IMAP#idle and Net::IMAP#idle_done.
|
|
227
221
|
#
|
|
228
222
|
# The default value is +5+ seconds.
|
|
229
|
-
attr_accessor :idle_response_timeout, type: Integer
|
|
223
|
+
attr_accessor :idle_response_timeout, type: Integer, default: 5
|
|
230
224
|
|
|
231
225
|
# Whether to use the +SASL-IR+ extension when the server and \SASL
|
|
232
226
|
# mechanism both support it. Can be overridden by the +sasl_ir+ keyword
|
|
@@ -240,9 +234,25 @@ module Net
|
|
|
240
234
|
# Do not use +SASL-IR+, even when it is supported by the server and the
|
|
241
235
|
# mechanism.
|
|
242
236
|
#
|
|
237
|
+
# [+:when_capabilities_cached+]
|
|
238
|
+
# Use +SASL-IR+ when Net::IMAP#capabilities_cached? is +true+ and it is
|
|
239
|
+
# supported by the server and the mechanism, but do not send a
|
|
240
|
+
# +CAPABILITY+ command to discover the server capabilities.
|
|
241
|
+
#
|
|
242
|
+
# <em>(+:when_capabilities_cached+ option was added by +v0.6.0+)</em>
|
|
243
|
+
#
|
|
243
244
|
# [+true+ <em>(default since +v0.4+)</em>]
|
|
244
245
|
# Use +SASL-IR+ when it is supported by the server and the mechanism.
|
|
245
|
-
attr_accessor :sasl_ir, type:
|
|
246
|
+
attr_accessor :sasl_ir, type: Enum[
|
|
247
|
+
false, :when_capabilities_cached, true
|
|
248
|
+
], defaults: {
|
|
249
|
+
0.0r => false,
|
|
250
|
+
0.4r => true,
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# :stopdoc:
|
|
254
|
+
alias sasl_ir? sasl_ir
|
|
255
|
+
# :startdoc:
|
|
246
256
|
|
|
247
257
|
# Controls the behavior of Net::IMAP#login when the +LOGINDISABLED+
|
|
248
258
|
# capability is present. When enforced, Net::IMAP will raise a
|
|
@@ -266,7 +276,10 @@ module Net
|
|
|
266
276
|
#
|
|
267
277
|
attr_accessor :enforce_logindisabled, type: Enum[
|
|
268
278
|
false, :when_capabilities_cached, true
|
|
269
|
-
]
|
|
279
|
+
], defaults: {
|
|
280
|
+
0.0r => false,
|
|
281
|
+
0.5r => true,
|
|
282
|
+
}
|
|
270
283
|
|
|
271
284
|
# The maximum allowed server response size. When +nil+, there is no limit
|
|
272
285
|
# on response size.
|
|
@@ -300,7 +313,10 @@ module Net
|
|
|
300
313
|
#
|
|
301
314
|
# * original: +nil+ <em>(no limit)</em>
|
|
302
315
|
# * +0.5+: 512 MiB
|
|
303
|
-
attr_accessor :max_response_size, type: Integer
|
|
316
|
+
attr_accessor :max_response_size, type: Integer?, defaults: {
|
|
317
|
+
0.0r => nil,
|
|
318
|
+
0.5r => 512 << 20, # 512 MiB
|
|
319
|
+
}
|
|
304
320
|
|
|
305
321
|
# Controls the behavior of Net::IMAP#responses when called without any
|
|
306
322
|
# arguments (+type+ or +block+).
|
|
@@ -330,7 +346,11 @@ module Net
|
|
|
330
346
|
# Note: #responses_without_args is an alias for #responses_without_block.
|
|
331
347
|
attr_accessor :responses_without_block, type: Enum[
|
|
332
348
|
:silence_deprecation_warning, :warn, :frozen_dup, :raise,
|
|
333
|
-
]
|
|
349
|
+
], defaults: {
|
|
350
|
+
0.0r => :silence_deprecation_warning,
|
|
351
|
+
0.5r => :warn,
|
|
352
|
+
0.6r => :frozen_dup,
|
|
353
|
+
}
|
|
334
354
|
|
|
335
355
|
alias responses_without_args responses_without_block # :nodoc:
|
|
336
356
|
alias responses_without_args= responses_without_block= # :nodoc:
|
|
@@ -340,66 +360,69 @@ module Net
|
|
|
340
360
|
#
|
|
341
361
|
# Alias for responses_without_block
|
|
342
362
|
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
#
|
|
346
|
-
#
|
|
347
|
-
# UIDPlusData stores its data in arrays of numbers, which is vulnerable to
|
|
348
|
-
# a memory exhaustion denial of service attack from an untrusted or
|
|
349
|
-
# compromised server. Set this option to +false+ to completely block this
|
|
350
|
-
# vulnerability. Otherwise, parser_max_deprecated_uidplus_data_size
|
|
351
|
-
# mitigates this vulnerability.
|
|
363
|
+
# **NOTE:** <em>+UIDPlusData+ has been removed since +v0.6.0+, and this
|
|
364
|
+
# config option only affects deprecation warnings.
|
|
365
|
+
# This config option will be **removed** in +v0.7.0+.</em>
|
|
352
366
|
#
|
|
353
|
-
#
|
|
354
|
-
#
|
|
355
|
-
#
|
|
367
|
+
# ResponseParser always returns CopyUIDData for +COPYUID+ response codes,
|
|
368
|
+
# and AppendUIDData for +APPENDUID+ response codes. Previously, this
|
|
369
|
+
# option determined when UIDPlusData would be returned instead.
|
|
356
370
|
#
|
|
357
|
-
#
|
|
371
|
+
# Parser support for +UIDPLUS+ added in +v0.3.2+.
|
|
358
372
|
#
|
|
359
|
-
#
|
|
373
|
+
# Config option added in +v0.4.19+ and +v0.5.6+.
|
|
360
374
|
#
|
|
361
|
-
# <em>UIDPlusData
|
|
362
|
-
# be ignored.</em>
|
|
375
|
+
# <em>UIDPlusData removed in +v0.6.0+.</em>
|
|
363
376
|
#
|
|
364
|
-
# ====
|
|
377
|
+
# ==== Options
|
|
365
378
|
#
|
|
366
379
|
# [+true+ <em>(original default)</em>]
|
|
367
|
-
#
|
|
380
|
+
# <em>Since v0.6.0:</em>
|
|
381
|
+
# Prints a deprecation warning when parsing +COPYUID+ or +APPENDUID+.
|
|
368
382
|
#
|
|
369
383
|
# [+:up_to_max_size+ <em>(default since +v0.5.6+)</em>]
|
|
370
|
-
#
|
|
371
|
-
#
|
|
372
|
-
# ResponseParser uses AppendUIDData or CopyUIDData.
|
|
384
|
+
# <em>Since v0.6.0:</em>
|
|
385
|
+
# Prints a deprecation warning when parsing +COPYUID+ or +APPENDUID+.
|
|
373
386
|
#
|
|
374
|
-
# [+false+ <em>(
|
|
375
|
-
#
|
|
387
|
+
# [+false+ <em>(default since +v0.6.0+)</em>]
|
|
388
|
+
# This is the only supported option <em>(since v0.6.0)</em>.
|
|
376
389
|
attr_accessor :parser_use_deprecated_uidplus_data, type: Enum[
|
|
377
390
|
true, :up_to_max_size, false
|
|
378
|
-
]
|
|
391
|
+
], defaults: {
|
|
392
|
+
0.0r => true,
|
|
393
|
+
0.5r => :up_to_max_size,
|
|
394
|
+
0.6r => false,
|
|
395
|
+
}
|
|
379
396
|
|
|
380
|
-
#
|
|
381
|
-
#
|
|
382
|
-
#
|
|
397
|
+
# **NOTE:** <em>+UIDPlusData+ has been removed since +v0.6.0+, and this
|
|
398
|
+
# config option is ignored.
|
|
399
|
+
# This config option will be **removed** in +v0.7.0+.</em>
|
|
383
400
|
#
|
|
384
|
-
#
|
|
401
|
+
# ResponseParser always returns CopyUIDData for +COPYUID+ response codes,
|
|
402
|
+
# and AppendUIDData for +APPENDUID+ response codes. Previously, this
|
|
403
|
+
# option determined when UIDPlusData would be returned instead.
|
|
385
404
|
#
|
|
386
|
-
#
|
|
387
|
-
# +v0.3.8+, +v0.4.19+, and +v0.5.6+.</em>
|
|
405
|
+
# Parser support for +UIDPLUS+ added in +v0.3.2+.
|
|
388
406
|
#
|
|
389
|
-
#
|
|
407
|
+
# Support for limiting UIDPlusData to a maximum size was added in
|
|
408
|
+
# +v0.3.8+, +v0.4.19+, and +v0.5.6+.
|
|
390
409
|
#
|
|
391
|
-
#
|
|
410
|
+
# <em>UIDPlusData was removed in +v0.6.0+.</em>
|
|
392
411
|
#
|
|
393
|
-
#
|
|
394
|
-
# memory exhaustion, the versioned default (used by #load_defaults) also
|
|
395
|
-
# applies to versions without the feature.
|
|
412
|
+
# ==== Versioned Defaults
|
|
396
413
|
#
|
|
397
414
|
# * +0.3+ and prior: <tt>10,000</tt>
|
|
398
415
|
# * +0.4+: <tt>1,000</tt>
|
|
399
416
|
# * +0.5+: <tt>100</tt>
|
|
400
417
|
# * +0.6+: <tt>0</tt>
|
|
401
418
|
#
|
|
402
|
-
attr_accessor :parser_max_deprecated_uidplus_data_size, type: Integer
|
|
419
|
+
attr_accessor :parser_max_deprecated_uidplus_data_size, type: Integer,
|
|
420
|
+
defaults: {
|
|
421
|
+
0.0r => 10_000,
|
|
422
|
+
0.4r => 1_000,
|
|
423
|
+
0.5r => 100,
|
|
424
|
+
0.6r => 0,
|
|
425
|
+
}
|
|
403
426
|
|
|
404
427
|
# Creates a new config object and initialize its attribute with +attrs+.
|
|
405
428
|
#
|
|
@@ -468,85 +491,150 @@ module Net
|
|
|
468
491
|
# Returns all config attributes in a hash.
|
|
469
492
|
def to_h; data.members.to_h { [_1, send(_1)] } end
|
|
470
493
|
|
|
494
|
+
# Returns a string representation of overriden config attributes and the
|
|
495
|
+
# inheritance chain.
|
|
496
|
+
#
|
|
497
|
+
# Attributes overridden by ancestors are also inspected, recursively.
|
|
498
|
+
# Attributes that are inherited from default configs are not shown (see
|
|
499
|
+
# Config@Versioned+defaults and Config@Named+defaults).
|
|
500
|
+
#
|
|
501
|
+
# # (Line breaks have been added to the example output for legibility.)
|
|
502
|
+
#
|
|
503
|
+
# Net::IMAP::Config.new(0.4)
|
|
504
|
+
# .new(open_timeout: 10, enforce_logindisabled: true)
|
|
505
|
+
# .inspect
|
|
506
|
+
# #=> "#<Net::IMAP::Config:0x0000745871125410 open_timeout=10 enforce_logindisabled=true
|
|
507
|
+
# # inherits from Net::IMAP::Config[0.4]
|
|
508
|
+
# # inherits from Net::IMAP::Config.global
|
|
509
|
+
# # inherits from Net::IMAP::Config.default>"
|
|
510
|
+
#
|
|
511
|
+
# Non-default attributes are listed after the ancestor config from which
|
|
512
|
+
# they are inherited.
|
|
513
|
+
#
|
|
514
|
+
# # (Line breaks have been added to the example output for legibility.)
|
|
515
|
+
#
|
|
516
|
+
# config = Net::IMAP::Config.global
|
|
517
|
+
# .new(open_timeout: 10, idle_response_timeout: 2)
|
|
518
|
+
# .new(enforce_logindisabled: :when_capabilities_cached, sasl_ir: false)
|
|
519
|
+
# config.inspect
|
|
520
|
+
# #=> "#<Net::IMAP::Config:0x00007ce2a1e20e40 sasl_ir=false enforce_logindisabled=:when_capabilities_cached
|
|
521
|
+
# # inherits from Net::IMAP::Config:0x00007ce2a1e20f80 open_timeout=10 idle_response_timeout=2
|
|
522
|
+
# # inherits from Net::IMAP::Config.global
|
|
523
|
+
# # inherits from Net::IMAP::Config.default>"
|
|
524
|
+
#
|
|
525
|
+
# Net::IMAP.debug = true
|
|
526
|
+
# config.inspect
|
|
527
|
+
# #=> "#<Net::IMAP::Config:0x00007ce2a1e20e40 sasl_ir=false enforce_logindisabled=:when_capabilities_cached
|
|
528
|
+
# # inherits from Net::IMAP::Config:0x00007ce2a1e20f80 open_timeout=10 idle_response_timeout=2
|
|
529
|
+
# # inherits from Net::IMAP::Config.global debug=true
|
|
530
|
+
# # inherits from Net::IMAP::Config.default>"
|
|
531
|
+
#
|
|
532
|
+
# Use +pp+ (see #pretty_print) to inspect _all_ config attributes,
|
|
533
|
+
# including default values.
|
|
534
|
+
#
|
|
535
|
+
# Use #to_h to inspect all config attributes ignoring inheritance.
|
|
536
|
+
def inspect;
|
|
537
|
+
"#<#{inspect_recursive}>"
|
|
538
|
+
end
|
|
539
|
+
alias to_s inspect
|
|
540
|
+
|
|
541
|
+
# Used by PP[https://docs.ruby-lang.org/en/master/PP.html] to create a
|
|
542
|
+
# string representation of all config attributes and the inheritance
|
|
543
|
+
# chain. Inherited attributes are listed with the ancestor config from
|
|
544
|
+
# which they are inherited.
|
|
545
|
+
#
|
|
546
|
+
# pp Config.new[0.4].new(open_timeout: 10, idle_response_timeout: 10)
|
|
547
|
+
# # #<Net::IMAP::Config:0x0000745871125410
|
|
548
|
+
# # open_timeout=10
|
|
549
|
+
# # idle_response_timeout=10
|
|
550
|
+
# # inherits from Net::IMAP::Config[0.4]
|
|
551
|
+
# # responses_without_block=:silence_deprecation_warning
|
|
552
|
+
# # max_response_size=nil
|
|
553
|
+
# # sasl_ir=true
|
|
554
|
+
# # enforce_logindisabled=false
|
|
555
|
+
# # parser_use_deprecated_uidplus_data=true
|
|
556
|
+
# # parser_max_deprecated_uidplus_data_size=1000
|
|
557
|
+
# # inherits from Net::IMAP::Config.global
|
|
558
|
+
# # inherits from Net::IMAP::Config.default
|
|
559
|
+
# # debug=false>
|
|
560
|
+
#
|
|
561
|
+
# Related: #inspect, #to_h.
|
|
562
|
+
def pretty_print(pp)
|
|
563
|
+
pp.group(2, "#<", ">") do
|
|
564
|
+
pretty_print_recursive(pp)
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# :stopdoc:
|
|
569
|
+
|
|
471
570
|
protected
|
|
472
571
|
|
|
473
|
-
def
|
|
474
|
-
|
|
572
|
+
def named_default?
|
|
573
|
+
equal?(Config.default) ||
|
|
574
|
+
AttrVersionDefaults::VERSIONS.any? { equal? Config[_1] }
|
|
475
575
|
end
|
|
476
576
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
version_defaults[0.2r] = Config[0r]
|
|
504
|
-
version_defaults[0.3r] = Config[0r]
|
|
505
|
-
|
|
506
|
-
version_defaults[0.4r] = Config[0.3r].dup.update(
|
|
507
|
-
sasl_ir: true,
|
|
508
|
-
parser_max_deprecated_uidplus_data_size: 1000,
|
|
509
|
-
).freeze
|
|
510
|
-
|
|
511
|
-
version_defaults[0.5r] = Config[0.4r].dup.update(
|
|
512
|
-
enforce_logindisabled: true,
|
|
513
|
-
max_response_size: 512 << 20, # 512 MiB
|
|
514
|
-
responses_without_block: :warn,
|
|
515
|
-
parser_use_deprecated_uidplus_data: :up_to_max_size,
|
|
516
|
-
parser_max_deprecated_uidplus_data_size: 100,
|
|
517
|
-
).freeze
|
|
518
|
-
|
|
519
|
-
version_defaults[0.6r] = Config[0.5r].dup.update(
|
|
520
|
-
responses_without_block: :frozen_dup,
|
|
521
|
-
parser_use_deprecated_uidplus_data: false,
|
|
522
|
-
parser_max_deprecated_uidplus_data_size: 0,
|
|
523
|
-
).freeze
|
|
524
|
-
|
|
525
|
-
version_defaults[0.7r] = Config[0.6r].dup.update(
|
|
526
|
-
).freeze
|
|
527
|
-
|
|
528
|
-
# Safe conversions one way only:
|
|
529
|
-
# 0.6r.to_f == 0.6 # => true
|
|
530
|
-
# 0.6 .to_r == 0.6r # => false
|
|
531
|
-
version_defaults.to_a.each do |k, v|
|
|
532
|
-
next unless k in Rational
|
|
533
|
-
version_defaults[k.to_f] = v
|
|
577
|
+
def name
|
|
578
|
+
if equal? Config.default then "#{Config}.default"
|
|
579
|
+
elsif equal? Config.global then "#{Config}.global"
|
|
580
|
+
elsif equal? Config[0.0r] then "#{Config}[:original]"
|
|
581
|
+
elsif equal? Config[:default] then "#{Config}[:default]"
|
|
582
|
+
elsif (v = AttrVersionDefaults::VERSIONS.find { equal? Config[_1] })
|
|
583
|
+
"%s[%0.1f]" % [Config, v]
|
|
584
|
+
else
|
|
585
|
+
Kernel.instance_method(:to_s).bind_call(self).delete("<#>")
|
|
586
|
+
end
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
def inspect_recursive(attrs = AttrAccessors.struct.members)
|
|
590
|
+
strings = [name]
|
|
591
|
+
assigned = assigned_attrs_hash(attrs)
|
|
592
|
+
strings.concat assigned.map { "%s=%p" % _1 }
|
|
593
|
+
if parent
|
|
594
|
+
if parent.equal?(Config.default)
|
|
595
|
+
inherited_overrides = []
|
|
596
|
+
elsif parent
|
|
597
|
+
inherited_overrides = attrs - assigned.keys
|
|
598
|
+
inherited_overrides &= DEFAULT_TO_INHERIT if parent.named_default?
|
|
599
|
+
end
|
|
600
|
+
strings << "inherits from #{parent.inspect_recursive(inherited_overrides)}"
|
|
601
|
+
end
|
|
602
|
+
strings.join " "
|
|
534
603
|
end
|
|
535
604
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
605
|
+
def pretty_print_recursive(pp, attrs = AttrAccessors.struct.members)
|
|
606
|
+
pp.text name
|
|
607
|
+
assigned = assigned_attrs_hash(attrs)
|
|
608
|
+
pp.breakable
|
|
609
|
+
pp.seplist(assigned, ->{pp.breakable}) do |key, val|
|
|
610
|
+
pp.text key.to_s
|
|
611
|
+
pp.text "="
|
|
612
|
+
pp.pp val
|
|
613
|
+
end
|
|
614
|
+
if parent
|
|
615
|
+
pp.breakable if assigned.any?
|
|
616
|
+
pp.nest(2) do
|
|
617
|
+
pp.text "inherits from "
|
|
618
|
+
parent.pretty_print_recursive(pp, attrs - assigned.keys)
|
|
619
|
+
end
|
|
620
|
+
elsif assigned.empty?
|
|
621
|
+
pp.text "(overridden)"
|
|
622
|
+
end
|
|
623
|
+
end
|
|
541
624
|
|
|
542
|
-
|
|
625
|
+
def assigned_attrs_hash(attrs)
|
|
626
|
+
own_attrs = attrs.reject { inherited?(_1) }
|
|
627
|
+
own_attrs.to_h { [_1, data[_1]] }
|
|
628
|
+
end
|
|
543
629
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
" not equal to Net::IMAP::Config[:default] => %p" % [
|
|
547
|
-
self[:current].to_h, self[:default].to_h
|
|
548
|
-
]
|
|
630
|
+
def defaults_hash
|
|
631
|
+
to_h.reject {|k,v| DEFAULT_TO_INHERIT.include?(k) }
|
|
549
632
|
end
|
|
633
|
+
|
|
634
|
+
@default = AttrVersionDefaults.compile_default!
|
|
635
|
+
@global = default.new
|
|
636
|
+
AttrVersionDefaults.compile_version_defaults!
|
|
637
|
+
|
|
550
638
|
end
|
|
551
639
|
end
|
|
552
640
|
end
|