net-imap 0.4.16 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +7 -1
- data/lib/net/imap/authenticators.rb +2 -2
- data/lib/net/imap/command_data.rb +11 -0
- data/lib/net/imap/config.rb +96 -35
- data/lib/net/imap/data_encoding.rb +3 -3
- data/lib/net/imap/deprecated_client_options.rb +6 -3
- data/lib/net/imap/errors.rb +6 -0
- data/lib/net/imap/response_data.rb +6 -93
- data/lib/net/imap/response_parser.rb +5 -17
- 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 +1 -1
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +213 -51
- data/lib/net/imap/sasl/login_authenticator.rb +2 -1
- data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
- data/lib/net/imap/sasl.rb +6 -3
- data/lib/net/imap/sasl_adapter.rb +0 -1
- data/lib/net/imap/sequence_set.rb +21 -20
- data/lib/net/imap.rb +133 -63
- data/net-imap.gemspec +1 -1
- metadata +4 -4
@@ -14,13 +14,6 @@ module Net
|
|
14
14
|
# receive a SequenceSet as an argument, for example IMAP#search, IMAP#fetch,
|
15
15
|
# and IMAP#store.
|
16
16
|
#
|
17
|
-
# == EXPERIMENTAL API
|
18
|
-
#
|
19
|
-
# SequenceSet is currently experimental. Only two methods, ::[] and
|
20
|
-
# #valid_string, are considered stable. Although the API isn't expected to
|
21
|
-
# change much, any other methods may be removed or changed without
|
22
|
-
# deprecation.
|
23
|
-
#
|
24
17
|
# == Creating sequence sets
|
25
18
|
#
|
26
19
|
# SequenceSet.new with no arguments creates an empty sequence set. Note
|
@@ -37,7 +30,8 @@ module Net
|
|
37
30
|
#
|
38
31
|
# SequenceSet.new may receive a single optional argument: a non-zero 32 bit
|
39
32
|
# unsigned integer, a range, a <tt>sequence-set</tt> formatted string,
|
40
|
-
# another sequence set,
|
33
|
+
# another sequence set, a Set (containing only numbers or <tt>*</tt>), or an
|
34
|
+
# Array containing any of these (array inputs may be nested).
|
41
35
|
#
|
42
36
|
# set = Net::IMAP::SequenceSet.new(1)
|
43
37
|
# set.valid_string #=> "1"
|
@@ -289,8 +283,7 @@ module Net
|
|
289
283
|
private_constant :STAR_INT, :STARS
|
290
284
|
|
291
285
|
COERCIBLE = ->{ _1.respond_to? :to_sequence_set }
|
292
|
-
|
293
|
-
private_constant :COERCIBLE, :ENUMABLE
|
286
|
+
private_constant :COERCIBLE
|
294
287
|
|
295
288
|
class << self
|
296
289
|
|
@@ -304,7 +297,7 @@ module Net
|
|
304
297
|
# Use ::new to create a mutable or empty SequenceSet.
|
305
298
|
def [](first, *rest)
|
306
299
|
if rest.empty?
|
307
|
-
if first.is_a?(SequenceSet) &&
|
300
|
+
if first.is_a?(SequenceSet) && first.frozen? && first.valid?
|
308
301
|
first
|
309
302
|
else
|
310
303
|
new(first).validate.freeze
|
@@ -682,6 +675,7 @@ module Net
|
|
682
675
|
# Unlike #add, #merge, or #union, the new value is appended to #string.
|
683
676
|
# This may result in a #string which has duplicates or is out-of-order.
|
684
677
|
def append(object)
|
678
|
+
modifying!
|
685
679
|
tuple = input_to_tuple object
|
686
680
|
entry = tuple_to_str tuple
|
687
681
|
tuple_add tuple
|
@@ -1271,7 +1265,8 @@ module Net
|
|
1271
1265
|
when *STARS, Integer, Range then [input_to_tuple(obj)]
|
1272
1266
|
when String then str_to_tuples obj
|
1273
1267
|
when SequenceSet then obj.tuples
|
1274
|
-
when
|
1268
|
+
when Set then obj.map { [to_tuple_int(_1)] * 2 }
|
1269
|
+
when Array then obj.flat_map { input_to_tuples _1 }
|
1275
1270
|
when nil then []
|
1276
1271
|
else
|
1277
1272
|
raise DataFormatError,
|
@@ -1284,8 +1279,7 @@ module Net
|
|
1284
1279
|
# String, Set, Array, or... any type of object.
|
1285
1280
|
def input_try_convert(input)
|
1286
1281
|
SequenceSet.try_convert(input) ||
|
1287
|
-
|
1288
|
-
input.respond_to?(:to_int) && Integer(input.to_int) ||
|
1282
|
+
Integer.try_convert(input) ||
|
1289
1283
|
String.try_convert(input) ||
|
1290
1284
|
input
|
1291
1285
|
end
|
@@ -1317,6 +1311,12 @@ module Net
|
|
1317
1311
|
range.include?(min) || range.include?(max) || (min..max).cover?(range)
|
1318
1312
|
end
|
1319
1313
|
|
1314
|
+
def modifying!
|
1315
|
+
if frozen?
|
1316
|
+
raise FrozenError, "can't modify frozen #{self.class}: %p" % [self]
|
1317
|
+
end
|
1318
|
+
end
|
1319
|
+
|
1320
1320
|
def tuples_add(tuples) tuples.each do tuple_add _1 end; self end
|
1321
1321
|
def tuples_subtract(tuples) tuples.each do tuple_subtract _1 end; self end
|
1322
1322
|
|
@@ -1331,6 +1331,7 @@ module Net
|
|
1331
1331
|
# ---------??===lower==|--|==|----|===upper===|-- join until upper
|
1332
1332
|
# ---------??===lower==|--|==|--|=====upper===|-- join to upper
|
1333
1333
|
def tuple_add(tuple)
|
1334
|
+
modifying!
|
1334
1335
|
min, max = tuple
|
1335
1336
|
lower, lower_idx = tuple_gte_with_index(min - 1)
|
1336
1337
|
if lower.nil? then tuples << tuple
|
@@ -1367,6 +1368,7 @@ module Net
|
|
1367
1368
|
# -------??=====lower====|--|====|---|====upper====|-- 7. delete until
|
1368
1369
|
# -------??=====lower====|--|====|--|=====upper====|-- 8. delete and trim
|
1369
1370
|
def tuple_subtract(tuple)
|
1371
|
+
modifying!
|
1370
1372
|
min, max = tuple
|
1371
1373
|
lower, idx = tuple_gte_with_index(min)
|
1372
1374
|
if lower.nil? then nil # case 1.
|
@@ -1407,12 +1409,11 @@ module Net
|
|
1407
1409
|
end
|
1408
1410
|
|
1409
1411
|
def nz_number(num)
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
num
|
1412
|
+
String === num && !/\A[1-9]\d*\z/.match?(num) and
|
1413
|
+
raise DataFormatError, "%p is not a valid nz-number" % [num]
|
1414
|
+
NumValidator.ensure_nz_number Integer num
|
1415
|
+
rescue TypeError # To catch errors from Integer()
|
1416
|
+
raise DataFormatError, $!.message
|
1416
1417
|
end
|
1417
1418
|
|
1418
1419
|
# intentionally defined after the class implementation
|
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.
|
722
|
+
VERSION = "0.5.0"
|
721
723
|
|
722
724
|
# Aliases for supported capabilities, to be used with the #enable command.
|
723
725
|
ENABLE_ALIASES = {
|
@@ -944,9 +946,6 @@ module Net
|
|
944
946
|
@sock = tcp_socket(@host, @port)
|
945
947
|
start_tls_session if ssl_ctx
|
946
948
|
start_imap_connection
|
947
|
-
|
948
|
-
# DEPRECATED: to remove in next version
|
949
|
-
@client_thread = Thread.current
|
950
949
|
end
|
951
950
|
|
952
951
|
# Returns true after the TLS negotiation has completed and the remote
|
@@ -954,11 +953,6 @@ module Net
|
|
954
953
|
# but peer verification was disabled.
|
955
954
|
def tls_verified?; @tls_verified end
|
956
955
|
|
957
|
-
def client_thread # :nodoc:
|
958
|
-
warn "Net::IMAP#client_thread is deprecated and will be removed soon."
|
959
|
-
@client_thread
|
960
|
-
end
|
961
|
-
|
962
956
|
# Disconnects from the server.
|
963
957
|
#
|
964
958
|
# Related: #logout, #logout!
|
@@ -1242,6 +1236,9 @@ module Net
|
|
1242
1236
|
# +SASL-IR+ capability, below). Defaults to the #config value for
|
1243
1237
|
# {sasl_ir}[rdoc-ref:Config#sasl_ir], which defaults to +true+.
|
1244
1238
|
#
|
1239
|
+
# The +registry+ kwarg can be used to select the mechanism implementation
|
1240
|
+
# from a custom registry. See SASL.authenticator and SASL::Authenticators.
|
1241
|
+
#
|
1245
1242
|
# All other arguments are forwarded to the registered SASL authenticator for
|
1246
1243
|
# the requested mechanism. <em>The documentation for each individual
|
1247
1244
|
# mechanism must be consulted for its specific parameters.</em>
|
@@ -1336,29 +1333,9 @@ module Net
|
|
1336
1333
|
# Previously cached #capabilities will be cleared when this method
|
1337
1334
|
# completes. If the TaggedResponse to #authenticate includes updated
|
1338
1335
|
# capabilities, they will be cached.
|
1339
|
-
def authenticate(
|
1340
|
-
|
1341
|
-
|
1342
|
-
mechanism = mechanism.to_s.tr("_", "-").upcase
|
1343
|
-
authenticator = SASL.authenticator(mechanism, *creds, **props, &callback)
|
1344
|
-
cmdargs = ["AUTHENTICATE", mechanism]
|
1345
|
-
if sasl_ir && capable?("SASL-IR") && auth_capable?(mechanism) &&
|
1346
|
-
authenticator.respond_to?(:initial_response?) &&
|
1347
|
-
authenticator.initial_response?
|
1348
|
-
response = authenticator.process(nil)
|
1349
|
-
cmdargs << (response.empty? ? "=" : [response].pack("m0"))
|
1350
|
-
end
|
1351
|
-
result = send_command_with_continuations(*cmdargs) {|data|
|
1352
|
-
challenge = data.unpack1("m")
|
1353
|
-
response = authenticator.process challenge
|
1354
|
-
[response].pack("m0")
|
1355
|
-
}
|
1356
|
-
if authenticator.respond_to?(:done?) && !authenticator.done?
|
1357
|
-
logout!
|
1358
|
-
raise SASL::AuthenticationIncomplete, result
|
1359
|
-
end
|
1360
|
-
@capabilities = capabilities_from_resp_code result
|
1361
|
-
result
|
1336
|
+
def authenticate(*args, sasl_ir: config.sasl_ir, **props, &callback)
|
1337
|
+
sasl_adapter.authenticate(*args, sasl_ir: sasl_ir, **props, &callback)
|
1338
|
+
.tap { @capabilities = capabilities_from_resp_code _1 }
|
1362
1339
|
end
|
1363
1340
|
|
1364
1341
|
# Sends a {LOGIN command [IMAP4rev1 §6.2.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.3]
|
@@ -1378,13 +1355,9 @@ module Net
|
|
1378
1355
|
# ===== Capabilities
|
1379
1356
|
#
|
1380
1357
|
# An IMAP client MUST NOT call #login when the server advertises the
|
1381
|
-
# +LOGINDISABLED+ capability.
|
1382
|
-
#
|
1383
|
-
#
|
1384
|
-
# raise "Remote server has disabled the login command"
|
1385
|
-
# else
|
1386
|
-
# imap.login username, password
|
1387
|
-
# end
|
1358
|
+
# +LOGINDISABLED+ capability. By default, Net::IMAP will raise a
|
1359
|
+
# LoginDisabledError when that capability is present. See
|
1360
|
+
# Config#enforce_logindisabled.
|
1388
1361
|
#
|
1389
1362
|
# Server capabilities may change after #starttls, #login, and #authenticate.
|
1390
1363
|
# Cached capabilities _must_ be invalidated after this method completes.
|
@@ -1392,6 +1365,9 @@ module Net
|
|
1392
1365
|
# ResponseCode.
|
1393
1366
|
#
|
1394
1367
|
def login(user, password)
|
1368
|
+
if enforce_logindisabled? && capability?("LOGINDISABLED")
|
1369
|
+
raise LoginDisabledError
|
1370
|
+
end
|
1395
1371
|
send_command("LOGIN", user, password)
|
1396
1372
|
.tap { @capabilities = capabilities_from_resp_code _1 }
|
1397
1373
|
end
|
@@ -1948,7 +1924,7 @@ module Net
|
|
1948
1924
|
# [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]].
|
1949
1925
|
def uid_expunge(uid_set)
|
1950
1926
|
synchronize do
|
1951
|
-
send_command("UID EXPUNGE",
|
1927
|
+
send_command("UID EXPUNGE", SequenceSet.new(uid_set))
|
1952
1928
|
clear_responses("EXPUNGE")
|
1953
1929
|
end
|
1954
1930
|
end
|
@@ -2494,41 +2470,98 @@ module Net
|
|
2494
2470
|
end
|
2495
2471
|
end
|
2496
2472
|
|
2473
|
+
RESPONSES_DEPRECATION_MSG =
|
2474
|
+
"Pass a type or block to #responses, " \
|
2475
|
+
"set config.responses_without_block to :frozen_dup " \
|
2476
|
+
"or :silence_deprecation_warning, " \
|
2477
|
+
"or use #extract_responses or #clear_responses."
|
2478
|
+
private_constant :RESPONSES_DEPRECATION_MSG
|
2479
|
+
|
2497
2480
|
# :call-seq:
|
2481
|
+
# responses -> hash of {String => Array} (see config.responses_without_block)
|
2482
|
+
# responses(type) -> frozen array
|
2498
2483
|
# responses {|hash| ...} -> block result
|
2499
2484
|
# responses(type) {|array| ...} -> block result
|
2500
2485
|
#
|
2501
|
-
# Yields
|
2486
|
+
# Yields or returns unhandled server responses. Unhandled responses are
|
2487
|
+
# stored in a hash, with arrays of UntaggedResponse#data keyed by
|
2488
|
+
# UntaggedResponse#name and <em>non-+nil+</em> untagged ResponseCode#data
|
2489
|
+
# keyed by ResponseCode#name.
|
2490
|
+
#
|
2491
|
+
# When a block is given, yields unhandled responses and returns the block's
|
2492
|
+
# result. Without a block, returns the unhandled responses.
|
2493
|
+
#
|
2494
|
+
# [With +type+]
|
2495
|
+
# Yield or return only the array of responses for that +type+.
|
2496
|
+
# When no block is given, the returned array is a frozen copy.
|
2497
|
+
# [Without +type+]
|
2498
|
+
# Yield or return the entire responses hash.
|
2499
|
+
#
|
2500
|
+
# When no block is given, the behavior is determined by
|
2501
|
+
# Config#responses_without_block:
|
2502
|
+
# >>>
|
2503
|
+
# [+:silence_deprecation_warning+ <em>(original behavior)</em>]
|
2504
|
+
# Returns the mutable responses hash (without any warnings).
|
2505
|
+
# <em>This is not thread-safe.</em>
|
2506
|
+
#
|
2507
|
+
# [+:warn+ <em>(default since +v0.5+)</em>]
|
2508
|
+
# Prints a warning and returns the mutable responses hash.
|
2509
|
+
# <em>This is not thread-safe.</em>
|
2502
2510
|
#
|
2503
|
-
#
|
2504
|
-
#
|
2505
|
-
#
|
2506
|
-
#
|
2507
|
-
#
|
2511
|
+
# [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
|
2512
|
+
# Returns a frozen copy of the unhandled responses hash, with frozen
|
2513
|
+
# array values.
|
2514
|
+
#
|
2515
|
+
# [+:raise+]
|
2516
|
+
# Raise an +ArgumentError+ with the deprecation warning.
|
2508
2517
|
#
|
2509
2518
|
# For example:
|
2510
2519
|
#
|
2511
2520
|
# imap.select("inbox")
|
2512
|
-
# p imap.responses("EXISTS"
|
2521
|
+
# p imap.responses("EXISTS").last
|
2513
2522
|
# #=> 2
|
2523
|
+
# p imap.responses("UIDNEXT", &:last)
|
2524
|
+
# #=> 123456
|
2514
2525
|
# p imap.responses("UIDVALIDITY", &:last)
|
2515
2526
|
# #=> 968263756
|
2527
|
+
# p imap.responses {|responses|
|
2528
|
+
# {
|
2529
|
+
# exists: responses.delete("EXISTS").last,
|
2530
|
+
# uidnext: responses.delete("UIDNEXT").last,
|
2531
|
+
# uidvalidity: responses.delete("UIDVALIDITY").last,
|
2532
|
+
# }
|
2533
|
+
# }
|
2534
|
+
# #=> {:exists=>2, :uidnext=>123456, :uidvalidity=>968263756}
|
2535
|
+
# # "EXISTS", "UIDNEXT", and "UIDVALIDITY" have been removed:
|
2536
|
+
# p imap.responses(&:keys)
|
2537
|
+
# #=> ["FLAGS", "OK", "PERMANENTFLAGS", "RECENT", "HIGHESTMODSEQ"]
|
2538
|
+
#
|
2539
|
+
# Related: #extract_responses, #clear_responses, #response_handlers, #greeting
|
2516
2540
|
#
|
2541
|
+
# ===== Thread safety
|
2517
2542
|
# >>>
|
2518
2543
|
# *Note:* Access to the responses hash is synchronized for thread-safety.
|
2519
2544
|
# The receiver thread and response_handlers cannot process new responses
|
2520
2545
|
# until the block completes. Accessing either the response hash or its
|
2521
|
-
# response type arrays outside of the block is unsafe.
|
2546
|
+
# response type arrays outside of the block is unsafe. They can be safely
|
2547
|
+
# updated inside the block. Consider using #clear_responses or
|
2548
|
+
# #extract_responses instead.
|
2522
2549
|
#
|
2523
|
-
#
|
2524
|
-
#
|
2525
|
-
#
|
2550
|
+
# Net::IMAP will add and remove responses from the responses hash and its
|
2551
|
+
# array values, in the calling threads for commands and in the receiver
|
2552
|
+
# thread, but will not modify any responses after adding them to the
|
2553
|
+
# responses hash.
|
2554
|
+
#
|
2555
|
+
# ===== Clearing responses
|
2526
2556
|
#
|
2527
2557
|
# Previously unhandled responses are automatically cleared before entering a
|
2528
2558
|
# mailbox with #select or #examine. Long-lived connections can receive many
|
2529
2559
|
# unhandled server responses, which must be pruned or they will continually
|
2530
2560
|
# consume more memory. Update or clear the responses hash or arrays inside
|
2531
|
-
# the block, or
|
2561
|
+
# the block, or remove responses with #extract_responses, #clear_responses,
|
2562
|
+
# or #add_response_handler.
|
2563
|
+
#
|
2564
|
+
# ===== Missing responses
|
2532
2565
|
#
|
2533
2566
|
# Only non-+nil+ data is stored. Many important response codes have no data
|
2534
2567
|
# of their own, but are used as "tags" on the ResponseText object they are
|
@@ -2539,19 +2572,24 @@ module Net
|
|
2539
2572
|
# ResponseCode#data on tagged responses. Although some command methods do
|
2540
2573
|
# return the TaggedResponse directly, #add_response_handler must be used to
|
2541
2574
|
# handle all response codes.
|
2542
|
-
#
|
2543
|
-
# Related: #clear_responses, #response_handlers, #greeting
|
2544
2575
|
def responses(type = nil)
|
2545
2576
|
if block_given?
|
2546
2577
|
synchronize { yield(type ? @responses[type.to_s.upcase] : @responses) }
|
2547
2578
|
elsif type
|
2548
|
-
|
2579
|
+
synchronize { @responses[type.to_s.upcase].dup.freeze }
|
2549
2580
|
else
|
2550
2581
|
case config.responses_without_block
|
2551
2582
|
when :raise
|
2552
|
-
raise ArgumentError,
|
2583
|
+
raise ArgumentError, RESPONSES_DEPRECATION_MSG
|
2553
2584
|
when :warn
|
2554
|
-
warn(
|
2585
|
+
warn(RESPONSES_DEPRECATION_MSG, uplevel: 1, category: :deprecated)
|
2586
|
+
when :frozen_dup
|
2587
|
+
synchronize {
|
2588
|
+
responses = @responses.transform_values(&:freeze)
|
2589
|
+
responses.default_proc = nil
|
2590
|
+
responses.default = [].freeze
|
2591
|
+
return responses.freeze
|
2592
|
+
}
|
2555
2593
|
end
|
2556
2594
|
@responses
|
2557
2595
|
end
|
@@ -2567,7 +2605,7 @@ module Net
|
|
2567
2605
|
# Clearing responses is synchronized with other threads. The lock is
|
2568
2606
|
# released before returning.
|
2569
2607
|
#
|
2570
|
-
# Related: #responses, #response_handlers
|
2608
|
+
# Related: #extract_responses, #responses, #response_handlers
|
2571
2609
|
def clear_responses(type = nil)
|
2572
2610
|
synchronize {
|
2573
2611
|
if type
|
@@ -2581,6 +2619,30 @@ module Net
|
|
2581
2619
|
.freeze
|
2582
2620
|
end
|
2583
2621
|
|
2622
|
+
# :call-seq:
|
2623
|
+
# extract_responses(type) {|response| ... } -> array
|
2624
|
+
#
|
2625
|
+
# Yields all of the unhandled #responses for a single response +type+.
|
2626
|
+
# Removes and returns the responses for which the block returns a true
|
2627
|
+
# value.
|
2628
|
+
#
|
2629
|
+
# Extracting responses is synchronized with other threads. The lock is
|
2630
|
+
# released before returning.
|
2631
|
+
#
|
2632
|
+
# Related: #responses, #clear_responses
|
2633
|
+
def extract_responses(type)
|
2634
|
+
type = String.try_convert(type) or
|
2635
|
+
raise ArgumentError, "type must be a string"
|
2636
|
+
raise ArgumentError, "must provide a block" unless block_given?
|
2637
|
+
extracted = []
|
2638
|
+
responses(type) do |all|
|
2639
|
+
all.reject! do |response|
|
2640
|
+
extracted << response if yield response
|
2641
|
+
end
|
2642
|
+
end
|
2643
|
+
extracted
|
2644
|
+
end
|
2645
|
+
|
2584
2646
|
# Returns all response handlers, including those that are added internally
|
2585
2647
|
# by commands. Each response handler will be called with every new
|
2586
2648
|
# UntaggedResponse, TaggedResponse, and ContinuationRequest.
|
@@ -2869,6 +2931,14 @@ module Net
|
|
2869
2931
|
end
|
2870
2932
|
end
|
2871
2933
|
|
2934
|
+
def enforce_logindisabled?
|
2935
|
+
if config.enforce_logindisabled == :when_capabilities_cached
|
2936
|
+
capabilities_cached?
|
2937
|
+
else
|
2938
|
+
config.enforce_logindisabled
|
2939
|
+
end
|
2940
|
+
end
|
2941
|
+
|
2872
2942
|
def search_internal(cmd, keys, charset)
|
2873
2943
|
if keys.instance_of?(String)
|
2874
2944
|
keys = [RawData.new(keys)]
|
@@ -2902,9 +2972,9 @@ module Net
|
|
2902
2972
|
synchronize do
|
2903
2973
|
clear_responses("FETCH")
|
2904
2974
|
if mod
|
2905
|
-
send_command(cmd,
|
2975
|
+
send_command(cmd, SequenceSet.new(set), attr, mod)
|
2906
2976
|
else
|
2907
|
-
send_command(cmd,
|
2977
|
+
send_command(cmd, SequenceSet.new(set), attr)
|
2908
2978
|
end
|
2909
2979
|
clear_responses("FETCH")
|
2910
2980
|
end
|
@@ -2912,7 +2982,7 @@ module Net
|
|
2912
2982
|
|
2913
2983
|
def store_internal(cmd, set, attr, flags, unchangedsince: nil)
|
2914
2984
|
attr = RawData.new(attr) if attr.instance_of?(String)
|
2915
|
-
args = [
|
2985
|
+
args = [SequenceSet.new(set)]
|
2916
2986
|
args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
|
2917
2987
|
args << attr << flags
|
2918
2988
|
synchronize do
|
@@ -2923,7 +2993,7 @@ module Net
|
|
2923
2993
|
end
|
2924
2994
|
|
2925
2995
|
def copy_internal(cmd, set, mailbox)
|
2926
|
-
send_command(cmd,
|
2996
|
+
send_command(cmd, SequenceSet.new(set), mailbox)
|
2927
2997
|
end
|
2928
2998
|
|
2929
2999
|
def sort_internal(cmd, sort_keys, search_keys, charset)
|
@@ -2954,7 +3024,7 @@ module Net
|
|
2954
3024
|
keys.collect! do |i|
|
2955
3025
|
case i
|
2956
3026
|
when -1, Range, Array
|
2957
|
-
|
3027
|
+
SequenceSet.new(i)
|
2958
3028
|
else
|
2959
3029
|
i
|
2960
3030
|
end
|
data/net-imap.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.summary = %q{Ruby client api for Internet Message Access Protocol}
|
17
17
|
spec.description = %q{Ruby client api for Internet Message Access Protocol}
|
18
18
|
spec.homepage = "https://github.com/ruby/net-imap"
|
19
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0")
|
20
20
|
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
21
21
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-imap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-protocol
|
@@ -118,14 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
118
|
requirements:
|
119
119
|
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
version:
|
121
|
+
version: 3.1.0
|
122
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
124
|
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: '0'
|
127
127
|
requirements: []
|
128
|
-
rubygems_version: 3.5.
|
128
|
+
rubygems_version: 3.5.16
|
129
129
|
signing_key:
|
130
130
|
specification_version: 4
|
131
131
|
summary: Ruby client api for Internet Message Access Protocol
|