@@ -70,6 +70,15 @@ module Net
70
70
# UIDs have to be reassigned. An \IMAP client thus cannot
71
71
# rearrange message orders.
72
72
#
73
+ # === Server capabilities and protocol extensions
74
+ #
75
+ # Net::IMAP <em>does not modify its behavior</em> according to server
76
+ # #capability. Users of the class must check for required capabilities before
77
+ # issuing commands. Special care should be taken to follow all #capability
78
+ # requirements for #starttls, #login, and #authenticate.
79
+ #
80
+ # See the #capability method for more information.
81
+ #
73
82
# == Examples of Usage
74
83
#
75
84
# === List sender and subject of all recent messages in the default mailbox
@@ -428,16 +437,55 @@ def disconnected?
428
437
# Sends a CAPABILITY command, and returns an array of
429
438
# capabilities that the server supports. Each capability
430
439
# is a string.
431
- # See the {IANA IMAP capabilities registry}[https://www.iana.org/assignments/imap-capabilities/imap-capabilities.xhtml]
432
- # for a list of possible capabilities and their RFCs.
440
+ #
441
+ # See the {IANA IMAP4 capabilities
442
+ # registry}[http://www.iana.org/assignments/imap4-capabilities] for a list
443
+ # of all standard capabilities, and their reference RFCs.
433
444
#
434
445
# >>>
435
- # <em>*Note* that the Net::IMAP class does not modify its
446
+ # <em>*Note* that Net::IMAP does not currently modify its
436
447
# behaviour according to the capabilities of the server;
437
448
# it is up to the user of the class to ensure that
438
449
# a certain capability is supported by a server before
439
450
# using it.</em>
440
451
#
452
+ # Capability requirements—other than +IMAP4rev1+—are listed in the
453
+ # documentation for each command method.
454
+ #
455
+ # ===== Basic IMAP4rev1 capabilities
456
+ #
457
+ # All IMAP4rev1 servers must include +IMAP4rev1+ in their capabilities list.
458
+ # All IMAP4rev1 servers must _implement_ the +STARTTLS+,
459
+ # <tt>AUTH=PLAIN</tt>, and +LOGINDISABLED+ capabilities, and clients must
460
+ # respect their presence or absence. See the capabilites requirements on
461
+ # #starttls, #login, and #authenticate.
462
+ #
463
+ # ===== Using IMAP4rev1 extensions
464
+ #
465
+ # IMAP4rev1 servers must not activate incompatible behavior until an
466
+ # explicit client action invokes a capability, e.g. sending a command or
467
+ # command argument specific to that capability. Extensions with backward
468
+ # compatible behavior, such as response codes or mailbox attributes, may
469
+ # be sent at any time.
470
+ #
471
+ # Invoking capabilities which are unknown to Net::IMAP may cause unexpected
472
+ # behavior and errors, for example ResponseParseError is raised when unknown
473
+ # response syntax is received. Invoking commands or command parameters that
474
+ # are unsupported by the server may raise NoResponseError, BadResponseError,
475
+ # or cause other unexpected behavior.
476
+ #
477
+ # ===== Caching +CAPABILITY+ responses
478
+ #
479
+ # Servers may send their capability list, unsolicited, using the
480
+ # +CAPABILITY+ response code or an untagged +CAPABILITY+ response. These
481
+ # responses can be retrieved and cached using #responses or
482
+ # #add_response_handler.
483
+ #
484
+ # But cached capabilities _must_ be discarded after #starttls, #login, or
485
+ # #authenticate. The OK TaggedResponse to #login and #authenticate may
486
+ # include +CAPABILITY+ response code data, but the TaggedResponse for
487
+ # #starttls is sent clear-text and cannot be trusted.
488
+ #
441
489
def capability
442
490
synchronize do
443
491
send_command ( "CAPABILITY" )
@@ -462,6 +510,11 @@ def capability
462
510
# end
463
511
#
464
512
# See [ID[https://tools.ietf.org/html/rfc2971]] for field definitions.
513
+ #
514
+ # ===== Capabilities
515
+ #
516
+ # The server's capabilities must include +ID+
517
+ # [RFC2971[https://tools.ietf.org/html/rfc2971]]
465
518
def id ( client_id = nil )
466
519
synchronize do
467
520
send_command ( "ID" , ClientID . new ( client_id ) )
@@ -481,6 +534,20 @@ def logout
481
534
end
482
535
483
536
# Sends a STARTTLS command to start TLS session.
537
+ # Sends a STARTTLS command to start a TLS session.
538
+ #
539
+ # ===== Capability
540
+ #
541
+ # The server's capabilities must include +STARTTLS+.
542
+ #
543
+ # Server capabilities may change after #starttls, #login, and #authenticate.
544
+ # Cached capabilities _must_ be invalidated after this method completes.
545
+ #
546
+ # The TaggedResponse to #starttls is sent clear-text, so the server <em>must
547
+ # *not*</em> send capabilities in the #starttls response and clients <em>must
548
+ # not</em> use them if they are sent. Servers will generally send an
549
+ # unsolicited untagged response immeditely _after_ #starttls completes.
550
+ #
484
551
def starttls ( options = { } , verify = true )
485
552
send_command ( "STARTTLS" ) do |resp |
486
553
if resp . kind_of? ( TaggedResponse ) && resp . name == "OK"
@@ -529,6 +596,20 @@ def starttls(options = {}, verify = true)
529
596
#
530
597
# See Net::IMAP::Authenticators for more information on plugging in your
531
598
# own authenticator.
599
+ #
600
+ # ==== Capabilities
601
+ #
602
+ # Clients MUST NOT attempt to #authenticate or #login when +LOGINDISABLED+
603
+ # is listed with the capabilities.
604
+ #
605
+ # Clients MUST NOT attempt to authenticate with a mechanism unless
606
+ # <tt>"AUTH=#{mechanism}"</tt> for that mechanism is a server capability.
607
+ #
608
+ # Server capabilities may change after #starttls, #login, and #authenticate.
609
+ # Cached capabilities _must_ be invalidated after this method completes.
610
+ # The TaggedResponse to #authenticate may include updated capabilities in
611
+ # its ResponseCode.
612
+ #
532
613
def authenticate ( auth_type , *args )
533
614
authenticator = self . class . authenticator ( auth_type , *args )
534
615
send_command ( "AUTHENTICATE" , auth_type ) do |resp |
@@ -547,6 +628,16 @@ def authenticate(auth_type, *args)
547
628
# of "LOGIN", #login does *not* use the login authenticator.
548
629
#
549
630
# A Net::IMAP::NoResponseError is raised if authentication fails.
631
+ #
632
+ # ==== Capabilities
633
+ # Clients MUST NOT attempt to #authenticate or #login when +LOGINDISABLED+
634
+ # is listed with the capabilities.
635
+ #
636
+ # Server capabilities may change after #starttls, #login, and #authenticate.
637
+ # Cached capabilities _must_ be invalidated after this method completes.
638
+ # The TaggedResponse to #login may include updated capabilities in its
639
+ # ResponseCode.
640
+ #
550
641
def login ( user , password )
551
642
send_command ( "LOGIN" , user , password )
552
643
end
@@ -661,6 +752,10 @@ def unsubscribe(mailbox)
661
752
# #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
662
753
# #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
663
754
# #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
755
+ #
756
+ #--
757
+ # TODO: support LIST-EXTENDED extension [RFC5258]. Needed for IMAP4rev2.
758
+ #++
664
759
def list ( refname , mailbox )
665
760
synchronize do
666
761
send_command ( "LIST" , refname , mailbox )
@@ -717,7 +812,10 @@ def list(refname, mailbox)
717
812
# end
718
813
# end
719
814
#
720
- # The NAMESPACE extension is described in [NAMESPACE[https://tools.ietf.org/html/rfc2342]]
815
+ # ===== Capabilities
816
+ #
817
+ # The server's capabilities must include +NAMESPACE+
818
+ # [RFC2342[https://tools.ietf.org/html/rfc2342]]
721
819
def namespace
722
820
synchronize do
723
821
send_command ( "NAMESPACE" )
@@ -750,6 +848,16 @@ def namespace
750
848
# #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
751
849
# #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
752
850
# #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
851
+ #
852
+ # ===== Capabilities
853
+ #
854
+ # The server's capabilities must include +XLIST+,
855
+ # a deprecated Gmail extension (replaced by +SPECIAL-USE+).
856
+ #--
857
+ # TODO: Net::IMAP doesn't yet have full SPECIAL-USE support. Supporting
858
+ # servers MAY return SPECIAL-USE attributes, but are not *required* to
859
+ # unless the SPECIAL-USE return option is supplied.
860
+ #++
753
861
def xlist ( refname , mailbox )
754
862
synchronize do
755
863
send_command ( "XLIST" , refname , mailbox )
@@ -762,7 +870,10 @@ def xlist(refname, mailbox)
762
870
# If this mailbox exists, it returns an array containing objects of type
763
871
# MailboxQuotaRoot and MailboxQuota.
764
872
#
765
- # The QUOTA extension is described in [QUOTA[https://tools.ietf.org/html/rfc2087]]
873
+ # ===== Capabilities
874
+ #
875
+ # The server's capabilities must include +QUOTA+
876
+ # [RFC2087[https://tools.ietf.org/html/rfc2087]].
766
877
def getquotaroot ( mailbox )
767
878
synchronize do
768
879
send_command ( "GETQUOTAROOT" , mailbox )
@@ -778,7 +889,10 @@ def getquotaroot(mailbox)
778
889
# MailboxQuota object is returned. This
779
890
# command is generally only available to server admin.
780
891
#
781
- # The QUOTA extension is described in [QUOTA[https://tools.ietf.org/html/rfc2087]]
892
+ # ===== Capabilities
893
+ #
894
+ # The server's capabilities must include +QUOTA+
895
+ # [RFC2087[https://tools.ietf.org/html/rfc2087]].
782
896
def getquota ( mailbox )
783
897
synchronize do
784
898
send_command ( "GETQUOTA" , mailbox )
@@ -791,7 +905,10 @@ def getquota(mailbox)
791
905
# mailbox. Typically one needs to be logged in as a server admin
792
906
# for this to work.
793
907
#
794
- # The QUOTA extension is described in [QUOTA[https://tools.ietf.org/html/rfc2087]]
908
+ # ===== Capabilities
909
+ #
910
+ # The server's capabilities must include +QUOTA+
911
+ # [RFC2087[https://tools.ietf.org/html/rfc2087]].
795
912
def setquota ( mailbox , quota )
796
913
if quota . nil?
797
914
data = '()'
@@ -805,7 +922,10 @@ def setquota(mailbox, quota)
805
922
# +rights+ that user is to have on that mailbox. If +rights+ is nil,
806
923
# then that user will be stripped of any rights to that mailbox.
807
924
#
808
- # The ACL extension is described in [ACL[https://tools.ietf.org/html/rfc4314]]
925
+ # ===== Capabilities
926
+ #
927
+ # The server's capabilities must include +ACL+
928
+ # [RFC4314[https://tools.ietf.org/html/rfc4314]].
809
929
def setacl ( mailbox , user , rights )
810
930
if rights . nil?
811
931
send_command ( "SETACL" , mailbox , user , "" )
@@ -818,7 +938,10 @@ def setacl(mailbox, user, rights)
818
938
# If this mailbox exists, an array containing objects of
819
939
# MailboxACLItem will be returned.
820
940
#
821
- # The ACL extension is described in [ACL[https://tools.ietf.org/html/rfc4314]]
941
+ # ===== Capabilities
942
+ #
943
+ # The server's capabilities must include +ACL+
944
+ # [RFC4314[https://tools.ietf.org/html/rfc4314]].
822
945
def getacl ( mailbox )
823
946
synchronize do
824
947
send_command ( "GETACL" , mailbox )
@@ -959,10 +1082,10 @@ def expunge
959
1082
# #responses and this method returns them as an array of
960
1083
# <em>sequence number</em> integers.
961
1084
#
962
- # ===== Capability requirement
1085
+ # ===== Capabilities
963
1086
#
964
- # +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] must be
965
- # supported by the server .
1087
+ # The server's capabilities must include +UIDPLUS+
1088
+ # [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] .
966
1089
def uid_expunge ( uid_set )
967
1090
synchronize do
968
1091
send_command ( "UID EXPUNGE" , MessageSet . new ( uid_set ) )
@@ -1121,10 +1244,10 @@ def uid_copy(set, mailbox)
1121
1244
# a number, an array of numbers, or a Range object. The number is
1122
1245
# a message sequence number.
1123
1246
#
1124
- # ===== Capabilities requirements
1247
+ # ===== Capabilities
1125
1248
#
1126
- # +MOVE+ [RFC6851[https://tools.ietf.org/html/rfc6851]] must be supported by
1127
- # the server .
1249
+ # The server's capabilities must include +MOVE+
1250
+ # [RFC6851[https://tools.ietf.org/html/rfc6851]] .
1128
1251
#
1129
1252
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
1130
1253
# also supported, the server's response should include a +COPYUID+ response
@@ -1137,11 +1260,11 @@ def move(set, mailbox)
1137
1260
1138
1261
# Similar to #move, but +set+ contains unique identifiers.
1139
1262
#
1140
- # ===== Capabilities requirements
1263
+ # ===== Capabilities
1141
1264
#
1142
- # Same as #move: +MOVE+ [RFC6851[https://tools.ietf.org/html/rfc6851]] must
1143
- # be supported by the server. +UIDPLUS+ also affects #uid_move the same way
1144
- # it affects #move.
1265
+ # Same as #move: The server's capabilities must include +MOVE+
1266
+ # [RFC6851[https://tools.ietf.org/html/rfc6851]]. +UIDPLUS+ also affects
1267
+ # #uid_move the same way it affects #move.
1145
1268
def uid_move ( set , mailbox )
1146
1269
copy_internal ( "UID MOVE" , set , mailbox )
1147
1270
end
@@ -1154,14 +1277,20 @@ def uid_move(set, mailbox)
1154
1277
# p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII")
1155
1278
# #=> [6, 7, 8, 1]
1156
1279
#
1157
- # The SORT extension is described in [SORT[https://tools.ietf.org/html/rfc5256]].
1280
+ # ===== Capabilities
1281
+ #
1282
+ # The server's capabilities must include +SORT+
1283
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1158
1284
def sort ( sort_keys , search_keys , charset )
1159
1285
return sort_internal ( "SORT" , sort_keys , search_keys , charset )
1160
1286
end
1161
1287
1162
1288
# Similar to #sort, but returns an array of unique identifiers.
1163
1289
#
1164
- # The SORT extension is described in [SORT[https://tools.ietf.org/html/rfc5256]].
1290
+ # ===== Capabilities
1291
+ #
1292
+ # The server's capabilities must include +SORT+
1293
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1165
1294
def uid_sort ( sort_keys , search_keys , charset )
1166
1295
return sort_internal ( "UID SORT" , sort_keys , search_keys , charset )
1167
1296
end
@@ -1199,15 +1328,21 @@ def remove_response_handler(handler)
1199
1328
# Unlike #search, +charset+ is a required argument. US-ASCII
1200
1329
# and UTF-8 are sample values.
1201
1330
#
1202
- # The THREAD extension is described in [THREAD[https://tools.ietf.org/html/rfc5256]].
1331
+ # ===== Capabilities
1332
+ #
1333
+ # The server's capabilities must include +THREAD+
1334
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1203
1335
def thread ( algorithm , search_keys , charset )
1204
1336
return thread_internal ( "THREAD" , algorithm , search_keys , charset )
1205
1337
end
1206
1338
1207
1339
# Similar to #thread, but returns unique identifiers instead of
1208
1340
# message sequence numbers.
1209
1341
#
1210
- # The THREAD extension is described in [THREAD[https://tools.ietf.org/html/rfc5256]].
1342
+ # ===== Capabilities
1343
+ #
1344
+ # The server's capabilities must include +THREAD+
1345
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1211
1346
def uid_thread ( algorithm , search_keys , charset )
1212
1347
return thread_internal ( "UID THREAD" , algorithm , search_keys , charset )
1213
1348
end
@@ -1226,6 +1361,11 @@ def uid_thread(algorithm, search_keys, charset)
1226
1361
# ...
1227
1362
# end
1228
1363
# end
1364
+ #
1365
+ # ===== Capabilities
1366
+ #
1367
+ # The server's capabilities must include +IDLE+
1368
+ # [RFC2177[https://tools.ietf.org/html/rfc2177]].
1229
1369
def idle ( timeout = nil , &response_handler )
1230
1370
raise LocalJumpError , "no block given" unless response_handler
1231
1371
0 commit comments