net-imap 0.4.16 → 0.4.17

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.

Potentially problematic release.


This version of net-imap might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb20811050c485f7fcde01bb24dbe455026b45cc463efe39353a3f186312a5d5
4
- data.tar.gz: 1290933be2c606cb299c75acc7ba59aa3ecdbcad245e776981eb2eb49d3289f3
3
+ metadata.gz: aceea6e339f24fafdd1920f2b25d863b47823c5654528441e4c7d173e414f3c2
4
+ data.tar.gz: 6258659759ae4c6b7ea63f7dddf0fb4a7231c3242ebad72188ba43bb7a2f3165
5
5
  SHA512:
6
- metadata.gz: 857dfd2863abedf53c6adf874a8d6883ea93de91cb01bd0c3ec60ca2279f86e1ae41ddedaccd1329490dddb6dabdce59cddf22699c0792085a5fba2a76184647
7
- data.tar.gz: 0766bbf7514aa1c293b18575c47bf02f5eff1c62b69c8cda432aba35d72572607d60588e45ab78a25e5df7f8d7df2fe5c90d965f580c8178171554151ab0c4a0
6
+ metadata.gz: 003561bf18250b9237f10d5ba5ce20ea285dea1d0380f4612d08429fe31ceea14d84fef76dc4e6c5ba47ff2e798b20a7767d85f6cdeb79f7abfcdb25df39093f
7
+ data.tar.gz: 42702bd43a0f9e778c88017e1553a5ddd058c0b702f1c39843c845ef0fba935b2f3ee636dc10a700e23b89c3e9a9e5b9c80b8bff836e65985bc59ca73c2a6255
@@ -7,10 +7,10 @@ require_relative "config/attr_type_coercion"
7
7
  module Net
8
8
  class IMAP
9
9
 
10
- # Net::IMAP::Config stores configuration options for Net::IMAP clients.
11
- # The global configuration can be seen at either Net::IMAP.config or
12
- # Net::IMAP::Config.global, and the client-specific configuration can be
13
- # seen at Net::IMAP#config.
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
14
  #
15
15
  # When creating a new client, all unhandled keyword arguments to
16
16
  # Net::IMAP.new are delegated to Config.new. Every client has its own
@@ -128,7 +128,7 @@ module Net
128
128
  # The global config object. Also available from Net::IMAP.config.
129
129
  def self.global; @global if defined?(@global) end
130
130
 
131
- # A hash of hard-coded configurations, indexed by version number.
131
+ # A hash of hard-coded configurations, indexed by version number or name.
132
132
  def self.version_defaults; @version_defaults end
133
133
  @version_defaults = {}
134
134
 
@@ -172,9 +172,16 @@ module Net
172
172
  include AttrInheritance
173
173
  include AttrTypeCoercion
174
174
 
175
- # The debug mode (boolean)
175
+ # The debug mode (boolean). The default value is +false+.
176
176
  #
177
- # The default value is +false+.
177
+ # When #debug is +true+:
178
+ # * Data sent to and received from the server will be logged.
179
+ # * ResponseParser will print warnings with extra detail for parse
180
+ # errors. _This may include recoverable errors._
181
+ # * ResponseParser makes extra assertions.
182
+ #
183
+ # *NOTE:* Versioned default configs inherit #debug from Config.global, and
184
+ # #load_defaults will not override #debug.
178
185
  attr_accessor :debug, type: :boolean
179
186
 
180
187
  # method: debug?
@@ -200,34 +207,61 @@ module Net
200
207
  # The default value is +5+ seconds.
201
208
  attr_accessor :idle_response_timeout, type: Integer
202
209
 
203
- # :markup: markdown
204
- #
205
210
  # Whether to use the +SASL-IR+ extension when the server and \SASL
206
- # mechanism both support it.
211
+ # mechanism both support it. Can be overridden by the +sasl_ir+ keyword
212
+ # parameter to Net::IMAP#authenticate.
213
+ #
214
+ # <em>(Support for +SASL-IR+ was added in +v0.4.0+.)</em>
215
+ #
216
+ # ==== Valid options
207
217
  #
208
- # See Net::IMAP#authenticate.
218
+ # [+false+ <em>(original behavior, before support was added)</em>]
219
+ # Do not use +SASL-IR+, even when it is supported by the server and the
220
+ # mechanism.
209
221
  #
210
- # | Starting with version | The default value is |
211
- # |-----------------------|------------------------------------------|
212
- # | _original_ | +false+ <em>(extension unsupported)</em> |
213
- # | v0.4 | +true+ <em>(support added)</em> |
222
+ # [+true+ <em>(default since +v0.4+)</em>]
223
+ # Use +SASL-IR+ when it is supported by the server and the mechanism.
214
224
  attr_accessor :sasl_ir, type: :boolean
215
225
 
216
- # :markup: markdown
226
+
227
+ # Controls the behavior of Net::IMAP#responses when called without any
228
+ # arguments (+type+ or +block+).
229
+ #
230
+ # ==== Valid options
231
+ #
232
+ # [+:silence_deprecation_warning+ <em>(original behavior)</em>]
233
+ # Returns the mutable responses hash (without any warnings).
234
+ # <em>This is not thread-safe.</em>
217
235
  #
218
- # Controls the behavior of Net::IMAP#responses when called without a
219
- # block. Valid options are `:warn`, `:raise`, or
220
- # `:silence_deprecation_warning`.
236
+ # [+:warn+ <em>(default since +v0.5+)</em>]
237
+ # Prints a warning and returns the mutable responses hash.
238
+ # <em>This is not thread-safe.</em>
221
239
  #
222
- # | Starting with version | The default value is |
223
- # |-------------------------|--------------------------------|
224
- # | v0.4.13 | +:silence_deprecation_warning+ |
225
- # | v0.5 <em>(planned)</em> | +:warn+ |
226
- # | _eventually_ | +:raise+ |
240
+ # [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
241
+ # Returns a frozen copy of the unhandled responses hash, with frozen
242
+ # array values.
243
+ #
244
+ # Note that calling IMAP#responses with a +type+ and without a block is
245
+ # not configurable and always behaves like +:frozen_dup+.
246
+ #
247
+ # <em>(+:frozen_dup+ config option was added in +v0.4.17+)</em>
248
+ #
249
+ # [+:raise+]
250
+ # Raise an ArgumentError with the deprecation warning.
251
+ #
252
+ # Note: #responses_without_args is an alias for #responses_without_block.
227
253
  attr_accessor :responses_without_block, type: [
228
- :silence_deprecation_warning, :warn, :raise,
254
+ :silence_deprecation_warning, :warn, :frozen_dup, :raise,
229
255
  ]
230
256
 
257
+ alias responses_without_args responses_without_block # :nodoc:
258
+ alias responses_without_args= responses_without_block= # :nodoc:
259
+
260
+ ##
261
+ # :attr_accessor: responses_without_args
262
+ #
263
+ # Alias for responses_without_block
264
+
231
265
  # Creates a new config object and initialize its attribute with +attrs+.
232
266
  #
233
267
  # If +parent+ is not given, the global config is used by default.
@@ -329,9 +363,10 @@ module Net
329
363
  version_defaults[:current] = Config[0.4]
330
364
  version_defaults[:next] = Config[0.5]
331
365
 
332
- version_defaults[:future] = Config[0.5].dup.update(
333
- responses_without_block: :raise,
366
+ version_defaults[0.6] = Config[0.5].dup.update(
367
+ responses_without_block: :frozen_dup,
334
368
  ).freeze
369
+ version_defaults[:future] = Config[0.6]
335
370
 
336
371
  version_defaults.freeze
337
372
  end
@@ -304,7 +304,7 @@ module Net
304
304
  # Use ::new to create a mutable or empty SequenceSet.
305
305
  def [](first, *rest)
306
306
  if rest.empty?
307
- if first.is_a?(SequenceSet) && set.frozen? && set.valid?
307
+ if first.is_a?(SequenceSet) && first.frozen? && first.valid?
308
308
  first
309
309
  else
310
310
  new(first).validate.freeze
@@ -682,6 +682,7 @@ module Net
682
682
  # Unlike #add, #merge, or #union, the new value is appended to #string.
683
683
  # This may result in a #string which has duplicates or is out-of-order.
684
684
  def append(object)
685
+ modifying!
685
686
  tuple = input_to_tuple object
686
687
  entry = tuple_to_str tuple
687
688
  tuple_add tuple
@@ -1317,6 +1318,12 @@ module Net
1317
1318
  range.include?(min) || range.include?(max) || (min..max).cover?(range)
1318
1319
  end
1319
1320
 
1321
+ def modifying!
1322
+ if frozen?
1323
+ raise FrozenError, "can't modify frozen #{self.class}: %p" % [self]
1324
+ end
1325
+ end
1326
+
1320
1327
  def tuples_add(tuples) tuples.each do tuple_add _1 end; self end
1321
1328
  def tuples_subtract(tuples) tuples.each do tuple_subtract _1 end; self end
1322
1329
 
@@ -1331,6 +1338,7 @@ module Net
1331
1338
  # ---------??===lower==|--|==|----|===upper===|-- join until upper
1332
1339
  # ---------??===lower==|--|==|--|=====upper===|-- join to upper
1333
1340
  def tuple_add(tuple)
1341
+ modifying!
1334
1342
  min, max = tuple
1335
1343
  lower, lower_idx = tuple_gte_with_index(min - 1)
1336
1344
  if lower.nil? then tuples << tuple
@@ -1367,6 +1375,7 @@ module Net
1367
1375
  # -------??=====lower====|--|====|---|====upper====|-- 7. delete until
1368
1376
  # -------??=====lower====|--|====|--|=====upper====|-- 8. delete and trim
1369
1377
  def tuple_subtract(tuple)
1378
+ modifying!
1370
1379
  min, max = tuple
1371
1380
  lower, idx = tuple_gte_with_index(min)
1372
1381
  if lower.nil? then nil # case 1.
data/lib/net/imap.rb CHANGED
@@ -288,6 +288,8 @@ module Net
288
288
  # pre-authenticated connection.
289
289
  # - #responses: Yields unhandled UntaggedResponse#data and <em>non-+nil+</em>
290
290
  # ResponseCode#data.
291
+ # - #extract_responses: Removes and returns the responses for which the block
292
+ # returns a true value.
291
293
  # - #clear_responses: Deletes unhandled data from #responses and returns it.
292
294
  # - #add_response_handler: Add a block to be called inside the receiver thread
293
295
  # with every server response.
@@ -717,7 +719,7 @@ module Net
717
719
  # * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
718
720
  #
719
721
  class IMAP < Protocol
720
- VERSION = "0.4.16"
722
+ VERSION = "0.4.17"
721
723
 
722
724
  # Aliases for supported capabilities, to be used with the #enable command.
723
725
  ENABLE_ALIASES = {
@@ -2494,41 +2496,98 @@ module Net
2494
2496
  end
2495
2497
  end
2496
2498
 
2499
+ RESPONSES_DEPRECATION_MSG =
2500
+ "Pass a type or block to #responses, " \
2501
+ "set config.responses_without_block to :frozen_dup " \
2502
+ "or :silence_deprecation_warning, " \
2503
+ "or use #extract_responses or #clear_responses."
2504
+ private_constant :RESPONSES_DEPRECATION_MSG
2505
+
2497
2506
  # :call-seq:
2507
+ # responses -> hash of {String => Array} (see config.responses_without_block)
2508
+ # responses(type) -> frozen array
2498
2509
  # responses {|hash| ...} -> block result
2499
2510
  # responses(type) {|array| ...} -> block result
2500
2511
  #
2501
- # Yields unhandled responses and returns the result of the block.
2512
+ # Yields or returns unhandled server responses. Unhandled responses are
2513
+ # stored in a hash, with arrays of UntaggedResponse#data keyed by
2514
+ # UntaggedResponse#name and <em>non-+nil+</em> untagged ResponseCode#data
2515
+ # keyed by ResponseCode#name.
2516
+ #
2517
+ # When a block is given, yields unhandled responses and returns the block's
2518
+ # result. Without a block, returns the unhandled responses.
2519
+ #
2520
+ # [With +type+]
2521
+ # Yield or return only the array of responses for that +type+.
2522
+ # When no block is given, the returned array is a frozen copy.
2523
+ # [Without +type+]
2524
+ # Yield or return the entire responses hash.
2525
+ #
2526
+ # When no block is given, the behavior is determined by
2527
+ # Config#responses_without_block:
2528
+ # >>>
2529
+ # [+:silence_deprecation_warning+ <em>(original behavior)</em>]
2530
+ # Returns the mutable responses hash (without any warnings).
2531
+ # <em>This is not thread-safe.</em>
2532
+ #
2533
+ # [+:warn+ <em>(default since +v0.5+)</em>]
2534
+ # Prints a warning and returns the mutable responses hash.
2535
+ # <em>This is not thread-safe.</em>
2502
2536
  #
2503
- # Unhandled responses are stored in a hash, with arrays of
2504
- # <em>non-+nil+</em> UntaggedResponse#data keyed by UntaggedResponse#name
2505
- # and ResponseCode#data keyed by ResponseCode#name. Call without +type+ to
2506
- # yield the entire responses hash. Call with +type+ to yield only the array
2507
- # of responses for that type.
2537
+ # [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
2538
+ # Returns a frozen copy of the unhandled responses hash, with frozen
2539
+ # array values.
2540
+ #
2541
+ # [+:raise+]
2542
+ # Raise an +ArgumentError+ with the deprecation warning.
2508
2543
  #
2509
2544
  # For example:
2510
2545
  #
2511
2546
  # imap.select("inbox")
2512
- # p imap.responses("EXISTS", &:last)
2547
+ # p imap.responses("EXISTS").last
2513
2548
  # #=> 2
2549
+ # p imap.responses("UIDNEXT", &:last)
2550
+ # #=> 123456
2514
2551
  # p imap.responses("UIDVALIDITY", &:last)
2515
2552
  # #=> 968263756
2553
+ # p imap.responses {|responses|
2554
+ # {
2555
+ # exists: responses.delete("EXISTS").last,
2556
+ # uidnext: responses.delete("UIDNEXT").last,
2557
+ # uidvalidity: responses.delete("UIDVALIDITY").last,
2558
+ # }
2559
+ # }
2560
+ # #=> {:exists=>2, :uidnext=>123456, :uidvalidity=>968263756}
2561
+ # # "EXISTS", "UIDNEXT", and "UIDVALIDITY" have been removed:
2562
+ # p imap.responses(&:keys)
2563
+ # #=> ["FLAGS", "OK", "PERMANENTFLAGS", "RECENT", "HIGHESTMODSEQ"]
2564
+ #
2565
+ # Related: #extract_responses, #clear_responses, #response_handlers, #greeting
2516
2566
  #
2567
+ # ===== Thread safety
2517
2568
  # >>>
2518
2569
  # *Note:* Access to the responses hash is synchronized for thread-safety.
2519
2570
  # The receiver thread and response_handlers cannot process new responses
2520
2571
  # until the block completes. Accessing either the response hash or its
2521
- # response type arrays outside of the block is unsafe.
2572
+ # response type arrays outside of the block is unsafe. They can be safely
2573
+ # updated inside the block. Consider using #clear_responses or
2574
+ # #extract_responses instead.
2522
2575
  #
2523
- # Calling without a block is unsafe and deprecated. Future releases will
2524
- # raise ArgumentError unless a block is given.
2525
- # See Config#responses_without_block.
2576
+ # Net::IMAP will add and remove responses from the responses hash and its
2577
+ # array values, in the calling threads for commands and in the receiver
2578
+ # thread, but will not modify any responses after adding them to the
2579
+ # responses hash.
2580
+ #
2581
+ # ===== Clearing responses
2526
2582
  #
2527
2583
  # Previously unhandled responses are automatically cleared before entering a
2528
2584
  # mailbox with #select or #examine. Long-lived connections can receive many
2529
2585
  # unhandled server responses, which must be pruned or they will continually
2530
2586
  # consume more memory. Update or clear the responses hash or arrays inside
2531
- # the block, or use #clear_responses.
2587
+ # the block, or remove responses with #extract_responses, #clear_responses,
2588
+ # or #add_response_handler.
2589
+ #
2590
+ # ===== Missing responses
2532
2591
  #
2533
2592
  # Only non-+nil+ data is stored. Many important response codes have no data
2534
2593
  # of their own, but are used as "tags" on the ResponseText object they are
@@ -2539,19 +2598,24 @@ module Net
2539
2598
  # ResponseCode#data on tagged responses. Although some command methods do
2540
2599
  # return the TaggedResponse directly, #add_response_handler must be used to
2541
2600
  # handle all response codes.
2542
- #
2543
- # Related: #clear_responses, #response_handlers, #greeting
2544
2601
  def responses(type = nil)
2545
2602
  if block_given?
2546
2603
  synchronize { yield(type ? @responses[type.to_s.upcase] : @responses) }
2547
2604
  elsif type
2548
- raise ArgumentError, "Pass a block or use #clear_responses"
2605
+ synchronize { @responses[type.to_s.upcase].dup.freeze }
2549
2606
  else
2550
2607
  case config.responses_without_block
2551
2608
  when :raise
2552
- raise ArgumentError, "Pass a block or use #clear_responses"
2609
+ raise ArgumentError, RESPONSES_DEPRECATION_MSG
2553
2610
  when :warn
2554
- warn("DEPRECATED: pass a block or use #clear_responses", uplevel: 1)
2611
+ warn(RESPONSES_DEPRECATION_MSG, uplevel: 1)
2612
+ when :frozen_dup
2613
+ synchronize {
2614
+ responses = @responses.transform_values(&:freeze)
2615
+ responses.default_proc = nil
2616
+ responses.default = [].freeze
2617
+ return responses.freeze
2618
+ }
2555
2619
  end
2556
2620
  @responses
2557
2621
  end
@@ -2567,7 +2631,7 @@ module Net
2567
2631
  # Clearing responses is synchronized with other threads. The lock is
2568
2632
  # released before returning.
2569
2633
  #
2570
- # Related: #responses, #response_handlers
2634
+ # Related: #extract_responses, #responses, #response_handlers
2571
2635
  def clear_responses(type = nil)
2572
2636
  synchronize {
2573
2637
  if type
@@ -2581,6 +2645,30 @@ module Net
2581
2645
  .freeze
2582
2646
  end
2583
2647
 
2648
+ # :call-seq:
2649
+ # extract_responses(type) {|response| ... } -> array
2650
+ #
2651
+ # Yields all of the unhandled #responses for a single response +type+.
2652
+ # Removes and returns the responses for which the block returns a true
2653
+ # value.
2654
+ #
2655
+ # Extracting responses is synchronized with other threads. The lock is
2656
+ # released before returning.
2657
+ #
2658
+ # Related: #responses, #clear_responses
2659
+ def extract_responses(type)
2660
+ type = String.try_convert(type) or
2661
+ raise ArgumentError, "type must be a string"
2662
+ raise ArgumentError, "must provide a block" unless block_given?
2663
+ extracted = []
2664
+ responses(type) do |all|
2665
+ all.reject! do |response|
2666
+ extracted << response if yield response
2667
+ end
2668
+ end
2669
+ extracted
2670
+ end
2671
+
2584
2672
  # Returns all response handlers, including those that are added internally
2585
2673
  # by commands. Each response handler will be called with every new
2586
2674
  # UntaggedResponse, TaggedResponse, and ContinuationRequest.
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-imap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.16
4
+ version: 0.4.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
8
  - nicholas a. evans
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-09-04 00:00:00.000000000 Z
12
+ date: 2024-10-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-protocol
@@ -110,7 +110,7 @@ metadata:
110
110
  homepage_uri: https://github.com/ruby/net-imap
111
111
  source_code_uri: https://github.com/ruby/net-imap
112
112
  changelog_uri: https://github.com/ruby/net-imap/releases
113
- post_install_message:
113
+ post_install_message:
114
114
  rdoc_options: []
115
115
  require_paths:
116
116
  - lib
@@ -125,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.5.9
129
- signing_key:
128
+ rubygems_version: 3.5.16
129
+ signing_key:
130
130
  specification_version: 4
131
131
  summary: Ruby client api for Internet Message Access Protocol
132
132
  test_files: []