net-imap 0.5.15 → 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 +1 -0
- data/lib/net/imap/command_data.rb +22 -277
- data/lib/net/imap/config/attr_inheritance.rb +14 -1
- data/lib/net/imap/config/attr_version_defaults.rb +1 -1
- data/lib/net/imap/config.rb +175 -35
- 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 +5 -23
- data/lib/net/imap/response_parser.rb +20 -33
- data/lib/net/imap/response_reader.rb +5 -24
- data/lib/net/imap/sasl/scram_authenticator.rb +0 -74
- data/lib/net/imap/search_result.rb +6 -0
- data/lib/net/imap/sequence_set.rb +622 -327
- data/lib/net/imap/uidplus_data.rb +2 -63
- data/lib/net/imap.rb +63 -161
- data/net-imap.gemspec +1 -1
- metadata +3 -4
- data/lib/net/imap/data_lite.rb +0 -226
|
@@ -3,69 +3,8 @@
|
|
|
3
3
|
module Net
|
|
4
4
|
class IMAP < Protocol
|
|
5
5
|
|
|
6
|
-
# *NOTE:* <em>UIDPlusData is deprecated and will be removed in the +0.6.0+
|
|
7
|
-
# release.</em> To use AppendUIDData and CopyUIDData before +0.6.0+, set
|
|
8
|
-
# Config#parser_use_deprecated_uidplus_data to +false+.
|
|
9
|
-
#
|
|
10
|
-
# UIDPlusData represents the ResponseCode#data that accompanies the
|
|
11
|
-
# +APPENDUID+ and +COPYUID+ {response codes}[rdoc-ref:ResponseCode].
|
|
12
|
-
#
|
|
13
|
-
# A server that supports +UIDPLUS+ should send UIDPlusData in response to
|
|
14
|
-
# the append[rdoc-ref:Net::IMAP#append], copy[rdoc-ref:Net::IMAP#copy],
|
|
15
|
-
# move[rdoc-ref:Net::IMAP#move], {uid copy}[rdoc-ref:Net::IMAP#uid_copy],
|
|
16
|
-
# and {uid move}[rdoc-ref:Net::IMAP#uid_move] commands---unless the
|
|
17
|
-
# destination mailbox reports +UIDNOTSTICKY+.
|
|
18
|
-
#
|
|
19
|
-
# Note that append[rdoc-ref:Net::IMAP#append], copy[rdoc-ref:Net::IMAP#copy]
|
|
20
|
-
# and {uid_copy}[rdoc-ref:Net::IMAP#uid_copy] return UIDPlusData in their
|
|
21
|
-
# TaggedResponse. But move[rdoc-ref:Net::IMAP#copy] and
|
|
22
|
-
# {uid_move}[rdoc-ref:Net::IMAP#uid_move] _should_ send UIDPlusData in an
|
|
23
|
-
# UntaggedResponse response before sending their TaggedResponse. However
|
|
24
|
-
# some servers do send UIDPlusData in the TaggedResponse for +MOVE+
|
|
25
|
-
# commands---this complies with the older +UIDPLUS+ specification but is
|
|
26
|
-
# discouraged by the +MOVE+ extension and disallowed by +IMAP4rev2+.
|
|
27
|
-
#
|
|
28
|
-
# == Required capability
|
|
29
|
-
# Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
|
|
30
|
-
# or +IMAP4rev2+ capability.
|
|
31
|
-
#
|
|
32
|
-
class UIDPlusData < Struct.new(:uidvalidity, :source_uids, :assigned_uids)
|
|
33
|
-
##
|
|
34
|
-
# method: uidvalidity
|
|
35
|
-
# :call-seq: uidvalidity -> nonzero uint32
|
|
36
|
-
#
|
|
37
|
-
# The UIDVALIDITY of the destination mailbox.
|
|
38
|
-
|
|
39
|
-
##
|
|
40
|
-
# method: source_uids
|
|
41
|
-
# :call-seq: source_uids -> nil or an array of nonzero uint32
|
|
42
|
-
#
|
|
43
|
-
# The UIDs of the copied or moved messages.
|
|
44
|
-
#
|
|
45
|
-
# Note:: Returns +nil+ for Net::IMAP#append.
|
|
46
|
-
|
|
47
|
-
##
|
|
48
|
-
# method: assigned_uids
|
|
49
|
-
# :call-seq: assigned_uids -> an array of nonzero uint32
|
|
50
|
-
#
|
|
51
|
-
# The newly assigned UIDs of the copied, moved, or appended messages.
|
|
52
|
-
#
|
|
53
|
-
# Note:: This always returns an array, even when it contains only one UID.
|
|
54
|
-
|
|
55
|
-
##
|
|
56
|
-
# :call-seq: uid_mapping -> nil or a hash
|
|
57
|
-
#
|
|
58
|
-
# Returns a hash mapping each source UID to the newly assigned destination
|
|
59
|
-
# UID.
|
|
60
|
-
#
|
|
61
|
-
# Note:: Returns +nil+ for Net::IMAP#append.
|
|
62
|
-
def uid_mapping
|
|
63
|
-
source_uids&.zip(assigned_uids)&.to_h
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
6
|
# >>>
|
|
68
|
-
# *NOTE:* <em>AppendUIDData
|
|
7
|
+
# *NOTE:* <em>AppendUIDData replaced UIDPlusData for +APPENDUID+ in the
|
|
69
8
|
# +0.6.0+ release.</em> To use AppendUIDData before +0.6.0+, set
|
|
70
9
|
# Config#parser_use_deprecated_uidplus_data to +false+.
|
|
71
10
|
#
|
|
@@ -109,7 +48,7 @@ module Net
|
|
|
109
48
|
end
|
|
110
49
|
|
|
111
50
|
# >>>
|
|
112
|
-
# *NOTE:* <em>CopyUIDData
|
|
51
|
+
# *NOTE:* <em>CopyUIDData replaced UIDPlusData for +COPYUID+ in the
|
|
113
52
|
# +0.6.0+ release.</em> To use CopyUIDData before +0.6.0+, set
|
|
114
53
|
# Config#parser_use_deprecated_uidplus_data to +false+.
|
|
115
54
|
#
|
data/lib/net/imap.rb
CHANGED
|
@@ -359,8 +359,8 @@ module Net
|
|
|
359
359
|
#
|
|
360
360
|
# - #capability: Returns the server's capabilities as an array of strings.
|
|
361
361
|
#
|
|
362
|
-
# <em>In general
|
|
363
|
-
# +CAPABILITY+ command to the server.</em>
|
|
362
|
+
# <em>In general,</em> #capable? <em>should be used rather than explicitly
|
|
363
|
+
# sending a +CAPABILITY+ command to the server.</em>
|
|
364
364
|
# - #noop: Allows the server to send unsolicited untagged #responses.
|
|
365
365
|
# - #logout: Tells the server to end the session. Enters the +logout+ state.
|
|
366
366
|
#
|
|
@@ -462,9 +462,6 @@ module Net
|
|
|
462
462
|
# +LITERAL-+, and +SPECIAL-USE+.</em>
|
|
463
463
|
#
|
|
464
464
|
# ==== RFC2087: +QUOTA+
|
|
465
|
-
# +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
|
|
466
|
-
# - Obsoleted by <tt>QUOTA=RES-*</tt> [RFC9208[https://www.rfc-editor.org/rfc/rfc9208]],
|
|
467
|
-
# although the commands are backward compatible.
|
|
468
465
|
# - #getquota: returns the resource usage and limits for a quota root
|
|
469
466
|
# - #getquotaroot: returns the list of quota roots for a mailbox, as well as
|
|
470
467
|
# their resource usage and limits.
|
|
@@ -581,16 +578,6 @@ module Net
|
|
|
581
578
|
# See FetchData#emailid and FetchData#emailid.
|
|
582
579
|
# - Updates #status with support for the +MAILBOXID+ status attribute.
|
|
583
580
|
#
|
|
584
|
-
# ==== RFC9208: <tt>QUOTA=RES-*</tt>
|
|
585
|
-
# +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
|
|
586
|
-
# - Obsoletes the +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
|
|
587
|
-
# extension and provides strict semantics for different resource types.
|
|
588
|
-
# - #getquota: returns the resource usage and limits for a quota root
|
|
589
|
-
# - #getquotaroot: returns the list of quota roots for a mailbox, as well as
|
|
590
|
-
# their resource usage and limits.
|
|
591
|
-
# - #setquota: sets the resource limits for a given quota root.
|
|
592
|
-
# - Updates #status with <tt>"DELETED"</tt> and +DELETED-STORAGE+ attributes.
|
|
593
|
-
#
|
|
594
581
|
# ==== RFC9394: +PARTIAL+
|
|
595
582
|
# - Updates #search, #uid_search with the +PARTIAL+ return option which adds
|
|
596
583
|
# ESearchResult#partial return data.
|
|
@@ -711,12 +698,13 @@ module Net
|
|
|
711
698
|
#
|
|
712
699
|
# === \IMAP Extensions
|
|
713
700
|
#
|
|
714
|
-
# [QUOTA[https://www.rfc-editor.org/rfc/
|
|
715
|
-
#
|
|
716
|
-
#
|
|
701
|
+
# [QUOTA[https://www.rfc-editor.org/rfc/rfc9208]]::
|
|
702
|
+
# Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
|
|
703
|
+
# March 2022, <https://www.rfc-editor.org/info/rfc9208>.
|
|
717
704
|
#
|
|
718
|
-
#
|
|
719
|
-
# (
|
|
705
|
+
# <em>Note: obsoletes</em>
|
|
706
|
+
# RFC-2087[https://www.rfc-editor.org/rfc/rfc2087]<em> (January 1997)</em>.
|
|
707
|
+
# <em>Net::IMAP does not fully support the RFC9208 updates yet.</em>
|
|
720
708
|
# [IDLE[https://www.rfc-editor.org/rfc/rfc2177]]::
|
|
721
709
|
# Leiba, B., "IMAP4 IDLE command", RFC 2177, DOI 10.17487/RFC2177,
|
|
722
710
|
# June 1997, <https://www.rfc-editor.org/info/rfc2177>.
|
|
@@ -768,11 +756,6 @@ module Net
|
|
|
768
756
|
# Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
|
|
769
757
|
# RFC 8474, DOI 10.17487/RFC8474, September 2018,
|
|
770
758
|
# <https://www.rfc-editor.org/info/rfc8474>.
|
|
771
|
-
# [{QUOTA=RES-*}[https://www.rfc-editor.org/rfc/rfc9208]]::
|
|
772
|
-
# Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
|
|
773
|
-
# March 2022, <https://www.rfc-editor.org/info/rfc9208>.
|
|
774
|
-
#
|
|
775
|
-
# Obsoletes RFC2087[https://www.rfc-editor.org/rfc/rfc2087].
|
|
776
759
|
# [PARTIAL[https://www.rfc-editor.org/info/rfc9394]]::
|
|
777
760
|
# Melnikov, A., Achuthan, A., Nagulakonda, V., and L. Alves,
|
|
778
761
|
# "IMAP PARTIAL Extension for Paged SEARCH and FETCH", RFC 9394,
|
|
@@ -786,7 +769,6 @@ module Net
|
|
|
786
769
|
#
|
|
787
770
|
# === IANA registries
|
|
788
771
|
# * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
|
|
789
|
-
# * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
|
|
790
772
|
# * {IMAP Response Codes}[https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml]
|
|
791
773
|
# * {IMAP Mailbox Name Attributes}[https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml]
|
|
792
774
|
# * {IMAP and JMAP Keywords}[https://www.iana.org/assignments/imap-jmap-keywords/imap-jmap-keywords.xhtml]
|
|
@@ -797,8 +779,8 @@ module Net
|
|
|
797
779
|
# * {GSSAPI/Kerberos/SASL Service Names}[https://www.iana.org/assignments/gssapi-service-names/gssapi-service-names.xhtml]:
|
|
798
780
|
# +imap+
|
|
799
781
|
# * {Character sets}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
|
|
800
|
-
#
|
|
801
782
|
# ==== For currently unsupported features:
|
|
783
|
+
# * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
|
|
802
784
|
# * {LIST-EXTENDED options and responses}[https://www.iana.org/assignments/imap-list-extended/imap-list-extended.xhtml]
|
|
803
785
|
# * {IMAP METADATA Server Entry and Mailbox Entry Registries}[https://www.iana.org/assignments/imap-metadata/imap-metadata.xhtml]
|
|
804
786
|
# * {IMAP ANNOTATE Extension Entries and Attributes}[https://www.iana.org/assignments/imap-annotate-extension/imap-annotate-extension.xhtml]
|
|
@@ -806,7 +788,7 @@ module Net
|
|
|
806
788
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
|
807
789
|
#
|
|
808
790
|
class IMAP < Protocol
|
|
809
|
-
VERSION = "0.
|
|
791
|
+
VERSION = "0.6.0"
|
|
810
792
|
|
|
811
793
|
# Aliases for supported capabilities, to be used with the #enable command.
|
|
812
794
|
ENABLE_ALIASES = {
|
|
@@ -823,10 +805,6 @@ module Net
|
|
|
823
805
|
autoload :StringPrep, "#{dir}/stringprep"
|
|
824
806
|
|
|
825
807
|
include MonitorMixin
|
|
826
|
-
if defined?(OpenSSL::SSL)
|
|
827
|
-
include OpenSSL
|
|
828
|
-
include SSL
|
|
829
|
-
end
|
|
830
808
|
|
|
831
809
|
# :call-seq:
|
|
832
810
|
# Net::IMAP::SequenceSet(set = nil) -> SequenceSet
|
|
@@ -1149,24 +1127,22 @@ module Net
|
|
|
1149
1127
|
|
|
1150
1128
|
# Disconnects from the server.
|
|
1151
1129
|
#
|
|
1152
|
-
# Waits for receiver thread to close before returning
|
|
1153
|
-
#
|
|
1154
|
-
# stuck response handlers can cause #disconnect to hang until they complete.
|
|
1130
|
+
# Waits for receiver thread to close before returning. Slow or stuck
|
|
1131
|
+
# response handlers can cause #disconnect to hang until they complete.
|
|
1155
1132
|
#
|
|
1156
1133
|
# Related: #logout, #logout!
|
|
1157
1134
|
def disconnect
|
|
1158
1135
|
in_logout_state = try_state_logout?
|
|
1159
1136
|
return if disconnected?
|
|
1160
|
-
in_receiver_thread = Thread.current == @receiver_thread
|
|
1161
1137
|
begin
|
|
1162
1138
|
@sock.to_io.shutdown
|
|
1163
1139
|
rescue Errno::ENOTCONN
|
|
1164
1140
|
# ignore `Errno::ENOTCONN: Socket is not connected' on some platforms.
|
|
1165
1141
|
rescue Exception => e
|
|
1166
|
-
@receiver_thread.raise(e)
|
|
1142
|
+
@receiver_thread.raise(e)
|
|
1167
1143
|
end
|
|
1168
1144
|
@sock.close
|
|
1169
|
-
@receiver_thread.join
|
|
1145
|
+
@receiver_thread.join
|
|
1170
1146
|
raise e if e
|
|
1171
1147
|
ensure
|
|
1172
1148
|
# Try again after shutting down the receiver thread. With no reciever
|
|
@@ -1414,11 +1390,9 @@ module Net
|
|
|
1414
1390
|
#
|
|
1415
1391
|
def starttls(**options)
|
|
1416
1392
|
@ssl_ctx_params, @ssl_ctx = build_ssl_ctx(options)
|
|
1417
|
-
handled = false
|
|
1418
1393
|
error = nil
|
|
1419
1394
|
ok = send_command("STARTTLS") do |resp|
|
|
1420
1395
|
if resp.kind_of?(TaggedResponse) && resp.name == "OK"
|
|
1421
|
-
handled = true
|
|
1422
1396
|
clear_cached_capabilities
|
|
1423
1397
|
clear_responses
|
|
1424
1398
|
start_tls_session
|
|
@@ -1430,13 +1404,6 @@ module Net
|
|
|
1430
1404
|
disconnect
|
|
1431
1405
|
raise error
|
|
1432
1406
|
end
|
|
1433
|
-
unless handled
|
|
1434
|
-
disconnect
|
|
1435
|
-
raise InvalidResponseError,
|
|
1436
|
-
"STARTTLS handler was bypassed, although server responded %p" % [
|
|
1437
|
-
ok.raw_data.chomp
|
|
1438
|
-
]
|
|
1439
|
-
end
|
|
1440
1407
|
ok
|
|
1441
1408
|
end
|
|
1442
1409
|
|
|
@@ -1551,6 +1518,7 @@ module Net
|
|
|
1551
1518
|
# completes. If the TaggedResponse to #authenticate includes updated
|
|
1552
1519
|
# capabilities, they will be cached.
|
|
1553
1520
|
def authenticate(*args, sasl_ir: config.sasl_ir, **props, &callback)
|
|
1521
|
+
sasl_ir = may_depend_on_capabilities_cached?(sasl_ir)
|
|
1554
1522
|
sasl_adapter.authenticate(*args, sasl_ir: sasl_ir, **props, &callback)
|
|
1555
1523
|
.tap do state_authenticated! _1 end
|
|
1556
1524
|
end
|
|
@@ -1602,7 +1570,7 @@ module Net
|
|
|
1602
1570
|
# When the +condstore+ keyword argument is true, the server is told to
|
|
1603
1571
|
# enable the extension. If +mailbox+ supports persistence of mod-sequences,
|
|
1604
1572
|
# the +HIGHESTMODSEQ+ ResponseCode will be sent as an untagged response to
|
|
1605
|
-
# #select and all
|
|
1573
|
+
# #select and all +FETCH+ responses will include FetchData#modseq.
|
|
1606
1574
|
# Otherwise, the +NOMODSEQ+ ResponseCode will be sent.
|
|
1607
1575
|
#
|
|
1608
1576
|
# A Net::IMAP::NoResponseError is raised if the mailbox does not
|
|
@@ -1857,18 +1825,12 @@ module Net
|
|
|
1857
1825
|
# to both admin and user. If this mailbox exists, it returns an array
|
|
1858
1826
|
# containing objects of type MailboxQuotaRoot and MailboxQuota.
|
|
1859
1827
|
#
|
|
1860
|
-
# *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
|
|
1861
|
-
# resource type. This is usually +STORAGE+, but you may need to verify this
|
|
1862
|
-
# with UntaggedResponse#raw_data.
|
|
1863
|
-
#
|
|
1864
1828
|
# Related: #getquota, #setquota, MailboxQuotaRoot, MailboxQuota
|
|
1865
1829
|
#
|
|
1866
1830
|
# ==== Capabilities
|
|
1867
1831
|
#
|
|
1868
|
-
#
|
|
1869
|
-
#
|
|
1870
|
-
# {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
|
|
1871
|
-
# resource type.
|
|
1832
|
+
# The server's capabilities must include +QUOTA+
|
|
1833
|
+
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
|
|
1872
1834
|
def getquotaroot(mailbox)
|
|
1873
1835
|
synchronize do
|
|
1874
1836
|
send_command("GETQUOTAROOT", mailbox)
|
|
@@ -1880,59 +1842,41 @@ module Net
|
|
|
1880
1842
|
end
|
|
1881
1843
|
|
|
1882
1844
|
# Sends a {GETQUOTA command [RFC2087 §4.2]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.2]
|
|
1883
|
-
#
|
|
1884
|
-
# containing a MailboxQuota object is returned.
|
|
1885
|
-
#
|
|
1886
|
-
# The names of quota roots that are applicable to a particular mailbox can
|
|
1887
|
-
# be discovered with #getquotaroot.
|
|
1888
|
-
#
|
|
1889
|
-
# *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
|
|
1890
|
-
# resource type. This is usually +STORAGE+, but you may need to verify this
|
|
1891
|
-
# with UntaggedResponse#raw_data.
|
|
1845
|
+
# along with specified +mailbox+. If this mailbox exists, then an array
|
|
1846
|
+
# containing a MailboxQuota object is returned. This command is generally
|
|
1847
|
+
# only available to server admin.
|
|
1892
1848
|
#
|
|
1893
1849
|
# Related: #getquotaroot, #setquota, MailboxQuota
|
|
1894
1850
|
#
|
|
1895
1851
|
# ==== Capabilities
|
|
1896
1852
|
#
|
|
1897
|
-
#
|
|
1898
|
-
#
|
|
1899
|
-
|
|
1900
|
-
# resource type.
|
|
1901
|
-
def getquota(quota_root)
|
|
1853
|
+
# The server's capabilities must include +QUOTA+
|
|
1854
|
+
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
|
|
1855
|
+
def getquota(mailbox)
|
|
1902
1856
|
synchronize do
|
|
1903
|
-
send_command("GETQUOTA",
|
|
1857
|
+
send_command("GETQUOTA", mailbox)
|
|
1904
1858
|
clear_responses("QUOTA")
|
|
1905
1859
|
end
|
|
1906
1860
|
end
|
|
1907
1861
|
|
|
1908
1862
|
# Sends a {SETQUOTA command [RFC2087 §4.1]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.1]
|
|
1909
|
-
# along with the specified +
|
|
1910
|
-
# +
|
|
1911
|
-
#
|
|
1912
|
-
#
|
|
1913
|
-
# imap.setquota "#user/alice", 100
|
|
1914
|
-
# imap.getquota "#user/alice"
|
|
1915
|
-
# # => [#<struct Net::IMAP::MailboxQuota mailbox="#user/alice" usage=54 quota=100>]
|
|
1916
|
-
#
|
|
1917
|
-
# Typically one needs to be logged in as a server admin for this to work.
|
|
1918
|
-
#
|
|
1919
|
-
# *NOTE:* Currently, Net::IMAP only supports setting +STORAGE+ quota limits.
|
|
1863
|
+
# along with the specified +mailbox+ and +quota+. If +quota+ is nil, then
|
|
1864
|
+
# +quota+ will be unset for that mailbox. Typically one needs to be logged
|
|
1865
|
+
# in as a server admin for this to work.
|
|
1920
1866
|
#
|
|
1921
1867
|
# Related: #getquota, #getquotaroot
|
|
1922
1868
|
#
|
|
1923
1869
|
# ==== Capabilities
|
|
1924
1870
|
#
|
|
1925
|
-
#
|
|
1926
|
-
#
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
if storage_limit.nil?
|
|
1931
|
-
list = []
|
|
1871
|
+
# The server's capabilities must include +QUOTA+
|
|
1872
|
+
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
|
|
1873
|
+
def setquota(mailbox, quota)
|
|
1874
|
+
if quota.nil?
|
|
1875
|
+
data = '()'
|
|
1932
1876
|
else
|
|
1933
|
-
|
|
1877
|
+
data = '(STORAGE ' + quota.to_s + ')'
|
|
1934
1878
|
end
|
|
1935
|
-
send_command("SETQUOTA",
|
|
1879
|
+
send_command("SETQUOTA", mailbox, RawData.new(data))
|
|
1936
1880
|
end
|
|
1937
1881
|
|
|
1938
1882
|
# Sends a {SETACL command [RFC4314 §3.1]}[https://www.rfc-editor.org/rfc/rfc4314#section-3.1]
|
|
@@ -2039,10 +1983,7 @@ module Net
|
|
|
2039
1983
|
# <tt>STATUS=SIZE</tt>
|
|
2040
1984
|
# {[RFC8483]}[https://www.rfc-editor.org/rfc/rfc8483.html].
|
|
2041
1985
|
#
|
|
2042
|
-
# +DELETED+
|
|
2043
|
-
# +IMAP4rev2+.
|
|
2044
|
-
# or <tt>QUOTA=RES-MESSAGES</tt>
|
|
2045
|
-
# {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208.html].
|
|
1986
|
+
# +DELETED+ requires the server's capabilities to include +IMAP4rev2+.
|
|
2046
1987
|
#
|
|
2047
1988
|
# +HIGHESTMODSEQ+ requires the server's capabilities to include +CONDSTORE+
|
|
2048
1989
|
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
|
@@ -2080,7 +2021,7 @@ module Net
|
|
|
2080
2021
|
#
|
|
2081
2022
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
|
2082
2023
|
# supported and the destination supports persistent UIDs, the server's
|
|
2083
|
-
# response should include an +APPENDUID+ response code with
|
|
2024
|
+
# response should include an +APPENDUID+ response code with AppendUIDData.
|
|
2084
2025
|
# This will report the UIDVALIDITY of the destination mailbox and the
|
|
2085
2026
|
# assigned UID of the appended message.
|
|
2086
2027
|
#
|
|
@@ -2211,7 +2152,6 @@ module Net
|
|
|
2211
2152
|
# provided as an array or a string.
|
|
2212
2153
|
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation]
|
|
2213
2154
|
# and {"Search criteria"}[rdoc-ref:#search@Search+criteria], below.
|
|
2214
|
-
# <em>Please note</em> the warning for when +criteria+ is a String.
|
|
2215
2155
|
#
|
|
2216
2156
|
# +return+ options control what kind of information is returned about
|
|
2217
2157
|
# messages matching the search +criteria+. Specifying +return+ should force
|
|
@@ -2324,11 +2264,11 @@ module Net
|
|
|
2324
2264
|
# Encoded as an \IMAP date (see ::encode_date).
|
|
2325
2265
|
#
|
|
2326
2266
|
# [When +criteria+ is a String]
|
|
2327
|
-
# +criteria+ will be sent to the server <em>
|
|
2328
|
-
#
|
|
2267
|
+
# +criteria+ will be sent directly to the server <em>without any
|
|
2268
|
+
# validation or encoding</em>.
|
|
2329
2269
|
#
|
|
2330
|
-
# <em>*WARNING:*
|
|
2331
|
-
#
|
|
2270
|
+
# <em>*WARNING:* This is vulnerable to injection attacks when external
|
|
2271
|
+
# inputs are used.</em>
|
|
2332
2272
|
#
|
|
2333
2273
|
# ==== Supported return options
|
|
2334
2274
|
#
|
|
@@ -2622,8 +2562,7 @@ module Net
|
|
|
2622
2562
|
# backward compatibility) but adds SearchResult#modseq when the +CONDSTORE+
|
|
2623
2563
|
# capability has been enabled.
|
|
2624
2564
|
#
|
|
2625
|
-
# See #search for documentation of parameters.
|
|
2626
|
-
# warning for when +criteria+ is a String.
|
|
2565
|
+
# See #search for documentation of parameters.
|
|
2627
2566
|
#
|
|
2628
2567
|
# ==== Capabilities
|
|
2629
2568
|
#
|
|
@@ -2650,13 +2589,6 @@ module Net
|
|
|
2650
2589
|
#
|
|
2651
2590
|
# +attr+ is a list of attributes to fetch; see FetchStruct documentation for
|
|
2652
2591
|
# a list of supported attributes.
|
|
2653
|
-
# >>>
|
|
2654
|
-
# When +attr+ is a String, it will be sent <em>with minimal validation and
|
|
2655
|
-
# no encoding or formatting</em>. When +attr+ is an Array, each String in
|
|
2656
|
-
# +attr+ will be sent this way.
|
|
2657
|
-
#
|
|
2658
|
-
# <em>*WARNING:* Although CRLF is prohibited, this is vulnerable to other
|
|
2659
|
-
# types of attribute injection attack if unvetted user input is used.</em>
|
|
2660
2592
|
#
|
|
2661
2593
|
# +changedsince+ is an optional integer mod-sequence. It limits results to
|
|
2662
2594
|
# messages with a mod-sequence greater than +changedsince+.
|
|
@@ -2709,8 +2641,7 @@ module Net
|
|
|
2709
2641
|
# {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
|
|
2710
2642
|
# (For message sequence numbers, use #fetch instead.)
|
|
2711
2643
|
#
|
|
2712
|
-
# +attr+ behaves the same as with #fetch.
|
|
2713
|
-
# warning on the +attr+ argument.
|
|
2644
|
+
# +attr+ behaves the same as with #fetch.
|
|
2714
2645
|
# >>>
|
|
2715
2646
|
# *Note:* Servers _MUST_ implicitly include the +UID+ message data item as
|
|
2716
2647
|
# part of any +FETCH+ response caused by a +UID+ command, regardless of
|
|
@@ -2847,7 +2778,7 @@ module Net
|
|
|
2847
2778
|
#
|
|
2848
2779
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
|
2849
2780
|
# supported, the server's response should include a +COPYUID+ response code
|
|
2850
|
-
# with
|
|
2781
|
+
# with CopyUIDData. This will report the UIDVALIDITY of the destination
|
|
2851
2782
|
# mailbox, the UID set of the source messages, and the assigned UID set of
|
|
2852
2783
|
# the moved messages.
|
|
2853
2784
|
#
|
|
@@ -2888,7 +2819,7 @@ module Net
|
|
|
2888
2819
|
#
|
|
2889
2820
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
|
2890
2821
|
# supported, the server's response should include a +COPYUID+ response code
|
|
2891
|
-
# with
|
|
2822
|
+
# with CopyUIDData. This will report the UIDVALIDITY of the destination
|
|
2892
2823
|
# mailbox, the UID set of the source messages, and the assigned UID set of
|
|
2893
2824
|
# the moved messages.
|
|
2894
2825
|
#
|
|
@@ -2922,10 +2853,8 @@ module Net
|
|
|
2922
2853
|
|
|
2923
2854
|
# Sends a {SORT command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
|
|
2924
2855
|
# to search a mailbox for messages that match +search_keys+ and return an
|
|
2925
|
-
# array of message sequence numbers, sorted by +sort_keys+.
|
|
2926
|
-
#
|
|
2927
|
-
# +search_keys+ are interpreted the same as the +criteria+ argument for
|
|
2928
|
-
# #search. <em>Please note</em> the #search warning for String +criteria+.
|
|
2856
|
+
# array of message sequence numbers, sorted by +sort_keys+. +search_keys+
|
|
2857
|
+
# are interpreted the same as for #search.
|
|
2929
2858
|
#
|
|
2930
2859
|
#--
|
|
2931
2860
|
# TODO: describe +sort_keys+
|
|
@@ -2950,10 +2879,8 @@ module Net
|
|
|
2950
2879
|
|
|
2951
2880
|
# Sends a {UID SORT command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
|
|
2952
2881
|
# to search a mailbox for messages that match +search_keys+ and return an
|
|
2953
|
-
# array of unique identifiers, sorted by +sort_keys+.
|
|
2954
|
-
#
|
|
2955
|
-
# +search_keys+ are interpreted the same as the +criteria+ argument for
|
|
2956
|
-
# #search. <em>Please note</em> the #search warning for String +criteria+.
|
|
2882
|
+
# array of unique identifiers, sorted by +sort_keys+. +search_keys+ are
|
|
2883
|
+
# interpreted the same as for #search.
|
|
2957
2884
|
#
|
|
2958
2885
|
# Related: #sort, #search, #uid_search, #thread, #uid_thread
|
|
2959
2886
|
#
|
|
@@ -2967,10 +2894,8 @@ module Net
|
|
|
2967
2894
|
|
|
2968
2895
|
# Sends a {THREAD command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
|
|
2969
2896
|
# to search a mailbox and return message sequence numbers in threaded
|
|
2970
|
-
# format, as a ThreadMember tree.
|
|
2971
|
-
#
|
|
2972
|
-
# +search_keys+ are interpreted the same as the +criteria+ argument for
|
|
2973
|
-
# #search. <em>Please note</em> the #search warning for String +criteria+.
|
|
2897
|
+
# format, as a ThreadMember tree. +search_keys+ are interpreted the same as
|
|
2898
|
+
# for #search.
|
|
2974
2899
|
#
|
|
2975
2900
|
# The supported algorithms are:
|
|
2976
2901
|
#
|
|
@@ -2996,9 +2921,6 @@ module Net
|
|
|
2996
2921
|
# Similar to #thread, but returns unique identifiers instead of
|
|
2997
2922
|
# message sequence numbers.
|
|
2998
2923
|
#
|
|
2999
|
-
# +search_keys+ are interpreted the same as the +criteria+ argument for
|
|
3000
|
-
# #search. <em>Please note</em> the #search warning for String +criteria+.
|
|
3001
|
-
#
|
|
3002
2924
|
# Related: #thread, #search, #uid_search, #sort, #uid_sort
|
|
3003
2925
|
#
|
|
3004
2926
|
# ==== Capabilities
|
|
@@ -3108,11 +3030,10 @@ module Net
|
|
|
3108
3030
|
capabilities = capabilities
|
|
3109
3031
|
.flatten
|
|
3110
3032
|
.map {|e| ENABLE_ALIASES[e] || e }
|
|
3111
|
-
.flat_map { _1.is_a?(String) && !_1.empty? ? _1.split(/ /, -1) : [_1] }
|
|
3112
3033
|
.uniq
|
|
3113
|
-
.
|
|
3034
|
+
.join(' ')
|
|
3114
3035
|
synchronize do
|
|
3115
|
-
send_command("ENABLE
|
|
3036
|
+
send_command("ENABLE #{capabilities}")
|
|
3116
3037
|
result = clear_responses("ENABLED").last || []
|
|
3117
3038
|
@utf8_strings ||= result.include? "UTF8=ACCEPT"
|
|
3118
3039
|
@utf8_strings ||= result.include? "IMAP4REV2"
|
|
@@ -3156,7 +3077,6 @@ module Net
|
|
|
3156
3077
|
|
|
3157
3078
|
synchronize do
|
|
3158
3079
|
tag = Thread.current[:net_imap_tag] = generate_tag
|
|
3159
|
-
guard_against_tagged_response_skipping_handler!(tag, "IDLE")
|
|
3160
3080
|
put_string("#{tag} IDLE#{CRLF}")
|
|
3161
3081
|
|
|
3162
3082
|
begin
|
|
@@ -3310,7 +3230,7 @@ module Net
|
|
|
3310
3230
|
warn(RESPONSES_DEPRECATION_MSG, uplevel: 1, category: :deprecated)
|
|
3311
3231
|
when :frozen_dup
|
|
3312
3232
|
synchronize {
|
|
3313
|
-
responses = @responses.transform_values
|
|
3233
|
+
responses = @responses.transform_values(&:freeze)
|
|
3314
3234
|
responses.default_proc = nil
|
|
3315
3235
|
responses.default = [].freeze
|
|
3316
3236
|
return responses.freeze
|
|
@@ -3621,7 +3541,6 @@ module Net
|
|
|
3621
3541
|
put_string(" ")
|
|
3622
3542
|
send_data(i, tag)
|
|
3623
3543
|
end
|
|
3624
|
-
guard_against_tagged_response_skipping_handler!(tag, cmd)
|
|
3625
3544
|
put_string(CRLF)
|
|
3626
3545
|
if cmd == "LOGOUT"
|
|
3627
3546
|
@logout_command_tag = tag
|
|
@@ -3637,19 +3556,6 @@ module Net
|
|
|
3637
3556
|
end
|
|
3638
3557
|
end
|
|
3639
3558
|
end
|
|
3640
|
-
rescue InvalidResponseError
|
|
3641
|
-
disconnect
|
|
3642
|
-
raise
|
|
3643
|
-
end
|
|
3644
|
-
|
|
3645
|
-
def guard_against_tagged_response_skipping_handler!(tag, cmd)
|
|
3646
|
-
return unless (resp = @tagged_responses[tag])&.name&.upcase == "OK"
|
|
3647
|
-
raise InvalidResponseError, format(
|
|
3648
|
-
"Received tagged 'OK' to incomplete %s command (tag=%s). " \
|
|
3649
|
-
"This could indicate a malicious server, a man-in-the-middle, or " \
|
|
3650
|
-
"client-side command injection. Disconnecting.",
|
|
3651
|
-
cmd, tag
|
|
3652
|
-
)
|
|
3653
3559
|
end
|
|
3654
3560
|
|
|
3655
3561
|
def generate_tag
|
|
@@ -3673,11 +3579,11 @@ module Net
|
|
|
3673
3579
|
end
|
|
3674
3580
|
|
|
3675
3581
|
def enforce_logindisabled?
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3582
|
+
may_depend_on_capabilities_cached?(config.enforce_logindisabled)
|
|
3583
|
+
end
|
|
3584
|
+
|
|
3585
|
+
def may_depend_on_capabilities_cached?(value)
|
|
3586
|
+
value == :when_capabilities_cached ? capabilities_cached? : value
|
|
3681
3587
|
end
|
|
3682
3588
|
|
|
3683
3589
|
def expunge_internal(...)
|
|
@@ -3803,7 +3709,7 @@ module Net
|
|
|
3803
3709
|
end
|
|
3804
3710
|
|
|
3805
3711
|
def store_internal(cmd, set, attr, flags, unchangedsince: nil)
|
|
3806
|
-
attr =
|
|
3712
|
+
attr = RawData.new(attr) if attr.instance_of?(String)
|
|
3807
3713
|
args = [SequenceSet.new(set)]
|
|
3808
3714
|
args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
|
|
3809
3715
|
args << attr << flags
|
|
@@ -3873,11 +3779,8 @@ module Net
|
|
|
3873
3779
|
def build_ssl_ctx(ssl)
|
|
3874
3780
|
if ssl
|
|
3875
3781
|
params = (Hash.try_convert(ssl) || {}).freeze
|
|
3876
|
-
context = SSLContext.new
|
|
3782
|
+
context = OpenSSL::SSL::SSLContext.new
|
|
3877
3783
|
context.set_params(params)
|
|
3878
|
-
if defined?(VerifyCallbackProc)
|
|
3879
|
-
context.verify_callback = VerifyCallbackProc
|
|
3880
|
-
end
|
|
3881
3784
|
context.freeze
|
|
3882
3785
|
[params, context]
|
|
3883
3786
|
else
|
|
@@ -3889,12 +3792,12 @@ module Net
|
|
|
3889
3792
|
raise "SSL extension not installed" unless defined?(OpenSSL::SSL)
|
|
3890
3793
|
raise "already using SSL" if @sock.kind_of?(OpenSSL::SSL::SSLSocket)
|
|
3891
3794
|
raise "cannot start TLS without SSLContext" unless ssl_ctx
|
|
3892
|
-
@sock = SSLSocket.new(@sock, ssl_ctx)
|
|
3795
|
+
@sock = OpenSSL::SSL::SSLSocket.new(@sock, ssl_ctx)
|
|
3893
3796
|
@reader = ResponseReader.new(self, @sock)
|
|
3894
3797
|
@sock.sync_close = true
|
|
3895
3798
|
@sock.hostname = @host if @sock.respond_to? :hostname=
|
|
3896
3799
|
ssl_socket_connect(@sock, open_timeout)
|
|
3897
|
-
if ssl_ctx.verify_mode != VERIFY_NONE
|
|
3800
|
+
if ssl_ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
|
3898
3801
|
@sock.post_connection_check(@host)
|
|
3899
3802
|
@tls_verified = true
|
|
3900
3803
|
end
|
|
@@ -3958,7 +3861,6 @@ require_relative "imap/errors"
|
|
|
3958
3861
|
require_relative "imap/config"
|
|
3959
3862
|
require_relative "imap/command_data"
|
|
3960
3863
|
require_relative "imap/data_encoding"
|
|
3961
|
-
require_relative "imap/data_lite"
|
|
3962
3864
|
require_relative "imap/flags"
|
|
3963
3865
|
require_relative "imap/response_data"
|
|
3964
3866
|
require_relative "imap/response_parser"
|
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(">= 3.
|
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.2.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.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shugo Maeda
|
|
@@ -63,7 +63,6 @@ files:
|
|
|
63
63
|
- lib/net/imap/config/attr_version_defaults.rb
|
|
64
64
|
- lib/net/imap/connection_state.rb
|
|
65
65
|
- lib/net/imap/data_encoding.rb
|
|
66
|
-
- lib/net/imap/data_lite.rb
|
|
67
66
|
- lib/net/imap/deprecated_client_options.rb
|
|
68
67
|
- lib/net/imap/errors.rb
|
|
69
68
|
- lib/net/imap/esearch_result.rb
|
|
@@ -123,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
123
122
|
requirements:
|
|
124
123
|
- - ">="
|
|
125
124
|
- !ruby/object:Gem::Version
|
|
126
|
-
version: 3.
|
|
125
|
+
version: 3.2.0
|
|
127
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
127
|
requirements:
|
|
129
128
|
- - ">="
|
|
130
129
|
- !ruby/object:Gem::Version
|
|
131
130
|
version: '0'
|
|
132
131
|
requirements: []
|
|
133
|
-
rubygems_version: 4.0.
|
|
132
|
+
rubygems_version: 4.0.1
|
|
134
133
|
specification_version: 4
|
|
135
134
|
summary: Ruby client api for Internet Message Access Protocol
|
|
136
135
|
test_files: []
|