net-imap 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/net/imap.rb CHANGED
@@ -23,12 +23,14 @@ end
23
23
 
24
24
  module Net
25
25
 
26
- #
27
- # Net::IMAP implements Internet Message Access Protocol (IMAP) client
26
+ # Net::IMAP implements Internet Message Access Protocol (\IMAP) client
28
27
  # functionality. The protocol is described in
29
- # [IMAP[https://tools.ietf.org/html/rfc3501]].
28
+ # [IMAP4rev1[https://tools.ietf.org/html/rfc3501]].
29
+ #--
30
+ # TODO: and [IMAP4rev2[https://tools.ietf.org/html/rfc9051]].
31
+ #++
30
32
  #
31
- # == IMAP Overview
33
+ # == \IMAP Overview
32
34
  #
33
35
  # An \IMAP client connects to a server, and then authenticates
34
36
  # itself using either #authenticate or #login. Having
@@ -41,12 +43,14 @@ module Net
41
43
  # within a hierarchy of directories.
42
44
  #
43
45
  # To work on the messages within a mailbox, the client must
44
- # first select that mailbox, using either #select or (for
45
- # read-only access) #examine. Once the client has successfully
46
- # selected a mailbox, they enter _selected_ state, and that
46
+ # first select that mailbox, using either #select or #examine
47
+ # (for read-only access). Once the client has successfully
48
+ # selected a mailbox, they enter the "_selected_" state, and that
47
49
  # mailbox becomes the _current_ mailbox, on which mail-item
48
50
  # related commands implicitly operate.
49
51
  #
52
+ # === Sequence numbers and UIDs
53
+ #
50
54
  # Messages have two sorts of identifiers: message sequence
51
55
  # numbers and UIDs.
52
56
  #
@@ -57,15 +61,31 @@ module Net
57
61
  # are expunged from the mailbox, remaining messages have their
58
62
  # sequence numbers "shuffled down" to fill the gaps.
59
63
  #
64
+ # To avoid sequence number race conditions, servers must not expunge messages
65
+ # when no command is in progress, nor when responding to #fetch, #store, or
66
+ # #search. Expunges _may_ be sent during any other command, including
67
+ # #uid_fetch, #uid_store, and #uid_search. The #noop and #idle commands are
68
+ # both useful for this side-effect: they allow the server to send all mailbox
69
+ # updates, including expunges.
70
+ #
60
71
  # UIDs, on the other hand, are permanently guaranteed not to
61
72
  # identify another message within the same mailbox, even if
62
73
  # the existing message is deleted. UIDs are required to
63
74
  # be assigned in ascending (but not necessarily sequential)
64
75
  # order within a mailbox; this means that if a non-IMAP client
65
- # rearranges the order of mailitems within a mailbox, the
76
+ # rearranges the order of mail items within a mailbox, the
66
77
  # UIDs have to be reassigned. An \IMAP client thus cannot
67
78
  # rearrange message orders.
68
79
  #
80
+ # === Server capabilities and protocol extensions
81
+ #
82
+ # Net::IMAP <em>does not modify its behavior</em> according to server
83
+ # #capability. Users of the class must check for required capabilities before
84
+ # issuing commands. Special care should be taken to follow all #capability
85
+ # requirements for #starttls, #login, and #authenticate.
86
+ #
87
+ # See the #capability method for more information.
88
+ #
69
89
  # == Examples of Usage
70
90
  #
71
91
  # === List sender and subject of all recent messages in the default mailbox
@@ -108,7 +128,7 @@ module Net
108
128
  #
109
129
  # == Errors
110
130
  #
111
- # An IMAP server can send three different types of responses to indicate
131
+ # An \IMAP server can send three different types of responses to indicate
112
132
  # failure:
113
133
  #
114
134
  # NO:: the attempted command could not be successfully completed. For
@@ -116,7 +136,7 @@ module Net
116
136
  # the selected mailbox does not exist; etc.
117
137
  #
118
138
  # BAD:: the request from the client does not follow the server's
119
- # understanding of the IMAP protocol. This includes attempting
139
+ # understanding of the \IMAP protocol. This includes attempting
120
140
  # commands from the wrong client state; for instance, attempting
121
141
  # to perform a SEARCH command without having SELECTed a current
122
142
  # mailbox. It can also signal an internal server
@@ -150,6 +170,355 @@ module Net
150
170
  # between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is
151
171
  # thrown if a server response is non-parseable.
152
172
  #
173
+ # == What's here?
174
+ #
175
+ # * {Connection control}[rdoc-ref:Net::IMAP@Connection+control+methods]
176
+ # * {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands]
177
+ # * {...for any state}[rdoc-ref:Net::IMAP@IMAP+commands+for+any+state]
178
+ # * {...for the "not authenticated" state}[rdoc-ref:Net::IMAP@IMAP+commands+for+the+-22Not+Authenticated-22+state]
179
+ # * {...for the "authenticated" state}[rdoc-ref:Net::IMAP@IMAP+commands+for+the+-22Authenticated-22+state]
180
+ # * {...for the "selected" state}[rdoc-ref:Net::IMAP@IMAP+commands+for+the+-22Selected-22+state]
181
+ # * {...for the "logout" state}[rdoc-ref:Net::IMAP@IMAP+commands+for+the+-22Logout-22+state]
182
+ # * {Supported IMAP extensions}[rdoc-ref:Net::IMAP@Supported+IMAP+extensions]
183
+ # * {Handling server responses}[rdoc-ref:Net::IMAP@Handling+server+responses]
184
+ #
185
+ # === Connection control methods
186
+ #
187
+ # - Net::IMAP.new: A new client connects immediately and waits for a
188
+ # successful server greeting before returning the new client object.
189
+ # - #starttls: Asks the server to upgrade a clear-text connection to use TLS.
190
+ # - #logout: Tells the server to end the session. Enters the "_logout_" state.
191
+ # - #disconnect: Disconnects the connection (without sending #logout first).
192
+ # - #disconnected?: True if the connection has been closed.
193
+ #
194
+ # === Core \IMAP commands
195
+ #
196
+ # The following commands are defined either by
197
+ # the [IMAP4rev1[https://tools.ietf.org/html/rfc3501]] base specification, or
198
+ # by one of the following extensions:
199
+ # [IDLE[https://tools.ietf.org/html/rfc2177]],
200
+ # [NAMESPACE[https://tools.ietf.org/html/rfc2342]],
201
+ # [UNSELECT[https://tools.ietf.org/html/rfc3691]],
202
+ #--
203
+ # TODO: [ENABLE[https://tools.ietf.org/html/rfc5161]],
204
+ # TODO: [LIST-EXTENDED[https://tools.ietf.org/html/rfc5258]],
205
+ # TODO: [LIST-STATUS[https://tools.ietf.org/html/rfc5819]],
206
+ #++
207
+ # [MOVE[https://tools.ietf.org/html/rfc6851]].
208
+ # These extensions are widely supported by modern IMAP4rev1 servers and have
209
+ # all been integrated into [IMAP4rev2[https://tools.ietf.org/html/rfc9051]].
210
+ # <em>Note: Net::IMAP doesn't fully support IMAP4rev2 yet.</em>
211
+ #
212
+ #--
213
+ # TODO: When IMAP4rev2 is supported, add the following to the each of the
214
+ # appropriate commands below.
215
+ # Note:: CHECK has been removed from IMAP4rev2.
216
+ # Note:: LSUB is obsoleted by +LIST-EXTENDED and has been removed from IMAP4rev2.
217
+ # <em>Some arguments require the +LIST-EXTENDED+ or +IMAP4rev2+ capability.</em>
218
+ # <em>Requires either the +ENABLE+ or +IMAP4rev2+ capability.</em>
219
+ # <em>Requires either the +NAMESPACE+ or +IMAP4rev2+ capability.</em>
220
+ # <em>Requires either the +IDLE+ or +IMAP4rev2+ capability.</em>
221
+ # <em>Requires either the +UNSELECT+ or +IMAP4rev2+ capability.</em>
222
+ # <em>Requires either the +UIDPLUS+ or +IMAP4rev2+ capability.</em>
223
+ # <em>Requires either the +MOVE+ or +IMAP4rev2+ capability.</em>
224
+ #++
225
+ #
226
+ # ==== \IMAP commands for any state
227
+ #
228
+ # - #capability: Returns the server's capabilities as an array of strings.
229
+ #
230
+ # <em>Capabilities may change after</em> #starttls, #authenticate, or #login
231
+ # <em>and cached capabilities must be reloaded.</em>
232
+ # - #noop: Allows the server to send unsolicited untagged #responses.
233
+ # - #logout: Tells the server to end the session. Enters the "_logout_" state.
234
+ #
235
+ # ==== \IMAP commands for the "Not Authenticated" state
236
+ #
237
+ # In addition to the universal commands, the following commands are valid in
238
+ # the "<em>not authenticated</em>" state:
239
+ #
240
+ # - #starttls: Upgrades a clear-text connection to use TLS.
241
+ #
242
+ # <em>Requires the +STARTTLS+ capability.</em>
243
+ # - #authenticate: Identifies the client to the server using a {SASL
244
+ # mechanism}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml].
245
+ # Enters the "_authenticated_" state.
246
+ #
247
+ # <em>Requires the <tt>AUTH=#{mechanism}</tt> capability for the chosen
248
+ # mechanism.</em>
249
+ # - #login: Identifies the client to the server using a plain text password.
250
+ # Using #authenticate is generally preferred. Enters the "_authenticated_"
251
+ # state.
252
+ #
253
+ # <em>The +LOGINDISABLED+ capability</em> <b>must NOT</b> <em>be listed.</em>
254
+ #
255
+ # ==== \IMAP commands for the "Authenticated" state
256
+ #
257
+ # In addition to the universal commands, the following commands are valid in
258
+ # the "_authenticated_" state:
259
+ #
260
+ #--
261
+ # - #enable: <em>Not implemented by Net::IMAP, yet.</em>
262
+ #
263
+ # <em>Requires the +ENABLE+ capability.</em>
264
+ #++
265
+ # - #select: Open a mailbox and enter the "_selected_" state.
266
+ # - #examine: Open a mailbox read-only, and enter the "_selected_" state.
267
+ # - #create: Creates a new mailbox.
268
+ # - #delete: Permanently remove a mailbox.
269
+ # - #rename: Change the name of a mailbox.
270
+ # - #subscribe: Adds a mailbox to the "subscribed" set.
271
+ # - #unsubscribe: Removes a mailbox from the "subscribed" set.
272
+ # - #list: Returns names and attributes of mailboxes matching a given pattern.
273
+ # - #namespace: Returns mailbox namespaces, with path prefixes and delimiters.
274
+ #
275
+ # <em>Requires the +NAMESPACE+ capability.</em>
276
+ # - #status: Returns mailbox information, e.g. message count, unseen message
277
+ # count, +UIDVALIDITY+ and +UIDNEXT+.
278
+ # - #append: Appends a message to the end of a mailbox.
279
+ # - #idle: Allows the server to send updates to the client, without the client
280
+ # needing to poll using #noop.
281
+ #
282
+ # <em>Requires the +IDLE+ capability.</em>
283
+ # - #lsub: Lists mailboxes the user has declared "active" or "subscribed".
284
+ #--
285
+ # <em>Replaced by</em> <tt>LIST-EXTENDED</tt> <em>and removed from</em>
286
+ # +IMAP4rev2+. <em>However, Net::IMAP hasn't implemented</em>
287
+ # <tt>LIST-EXTENDED</tt> _yet_.
288
+ #++
289
+ #
290
+ # ==== \IMAP commands for the "Selected" state
291
+ #
292
+ # In addition to the universal commands and the "authenticated" commands, the
293
+ # following commands are valid in the "_selected_" state:
294
+ #
295
+ # - #close: Closes the mailbox and returns to the "_authenticated_" state,
296
+ # expunging deleted messages, unless the mailbox was opened as read-only.
297
+ # - #unselect: Closes the mailbox and returns to the "_authenticated_" state,
298
+ # without expunging any messages.
299
+ #
300
+ # <em>Requires the +UNSELECT+ capability.</em>
301
+ # - #expunge: Permanently removes messages which have the Deleted flag set.
302
+ # - #uid_expunge: Restricts #expunge to only remove the specified UIDs.
303
+ #
304
+ # <em>Requires the +UIDPLUS+ capability.</em>
305
+ # - #search, #uid_search: Returns sequence numbers or UIDs of messages that
306
+ # match the given searching criteria.
307
+ # - #fetch, #uid_fetch: Returns data associated with a set of messages,
308
+ # specified by sequence number or UID.
309
+ # - #store, #uid_store: Alters a message's flags.
310
+ # - #copy, #uid_copy: Copies the specified messages to the end of the
311
+ # specified destination mailbox.
312
+ # - #move, #uid_move: Moves the specified messages to the end of the
313
+ # specified destination mailbox, expunging them from the current mailbox.
314
+ #
315
+ # <em>Requires the +MOVE+ capability.</em>
316
+ # - #check: Mostly obsolete. Can be replaced with #noop or #idle.
317
+ #--
318
+ # <em>Removed from IMAP4rev2.</em>
319
+ #++
320
+ #
321
+ # ==== \IMAP commands for the "Logout" state
322
+ #
323
+ # No \IMAP commands are valid in the +logout+ state. If the socket is still
324
+ # open, Net::IMAP will close it after receiving server confirmation.
325
+ # Exceptions will be raised by \IMAP commands that have already started and
326
+ # are waiting for a response, as well as any that are called after logout.
327
+ #
328
+ # === Supported \IMAP extensions
329
+ #
330
+ # ==== RFC9051: +IMAP4rev2+
331
+ #
332
+ # Although IMAP4rev2[https://tools.ietf.org/html/rfc9051] is <em>not supported
333
+ # yet</em>, Net::IMAP supports several extensions that have been folded into
334
+ # it: +IDLE+, +MOVE+, +NAMESPACE+, +UIDPLUS+, and +UNSELECT+.
335
+ #--
336
+ # TODO: RFC4466, ABNF extensions (automatic support for other extensions)
337
+ # TODO: +ESEARCH+, ExtendedSearchData
338
+ # TODO: +SEARCHRES+,
339
+ # TODO: +ENABLE+,
340
+ # TODO: +SASL-IR+,
341
+ # TODO: +LIST-EXTENDED+,
342
+ # TODO: +LIST-STATUS+,
343
+ # TODO: +LITERAL-+,
344
+ # TODO: +BINARY+ (only the FETCH side)
345
+ # TODO: +SPECIAL-USE+
346
+ # implicitly supported, but we can do better: Response codes: RFC5530, etc
347
+ # implicitly supported, but we can do better: <tt>STATUS=SIZE</tt>
348
+ # implicitly supported, but we can do better: <tt>STATUS DELETED</tt>
349
+ #++
350
+ # Commands for these extensions are included with the {Core IMAP
351
+ # commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands], above. Other supported
352
+ # extensons are listed below.
353
+ #
354
+ # ==== RFC2087: +QUOTA+
355
+ # - #getquota: returns the resource usage and limits for a quota root
356
+ # - #getquotaroot: returns the list of quota roots for a mailbox, as well as
357
+ # their resource usage and limits.
358
+ # - #setquota: sets the resource limits for a given quota root.
359
+ #
360
+ # ==== RFC2177: +IDLE+
361
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], so it is also
362
+ # listed with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
363
+ # - #idle: Allows the server to send updates to the client, without the client
364
+ # needing to poll using #noop.
365
+ #
366
+ # ==== RFC2342: +NAMESPACE+
367
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], so it is also
368
+ # listed with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
369
+ # - #namespace: Returns mailbox namespaces, with path prefixes and delimiters.
370
+ #
371
+ # ==== RFC2971: +ID+
372
+ # - #id: exchanges client and server implementation information.
373
+ #
374
+ #--
375
+ # ==== RFC3502: +MULTIAPPEND+
376
+ # TODO...
377
+ #++
378
+ #
379
+ #--
380
+ # ==== RFC3516: +BINARY+
381
+ # TODO...
382
+ #++
383
+ #
384
+ # ==== RFC3691: +UNSELECT+
385
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], so it is also
386
+ # listed with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
387
+ # - #unselect: Closes the mailbox and returns to the "_authenticated_" state,
388
+ # without expunging any messages.
389
+ #
390
+ # ==== RFC4314: +ACL+
391
+ # - #getacl: lists the authenticated user's access rights to a mailbox.
392
+ # - #setacl: sets the access rights for a user on a mailbox
393
+ #--
394
+ # TODO: #deleteacl, #listrights, #myrights
395
+ #++
396
+ # - *_Note:_* +DELETEACL+, +LISTRIGHTS+, and +MYRIGHTS+ are not supported yet.
397
+ #
398
+ # ==== RFC4315: +UIDPLUS+
399
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], so it is also
400
+ # listed with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
401
+ # - #uid_expunge: Restricts #expunge to only remove the specified UIDs.
402
+ # - Updates #select, #examine with the +UIDNOTSTICKY+ ResponseCode
403
+ # - Updates #append with the +APPENDUID+ ResponseCode
404
+ # - Updates #copy, #move with the +COPYUID+ ResponseCode
405
+ #
406
+ #--
407
+ # ==== RFC4466: Collected Extensions to IMAP4 ABNF
408
+ # TODO...
409
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], this RFC updates
410
+ # the protocol to enable new optional parameters to many commands: #select,
411
+ # #examine, #create, #rename, #fetch, #uid_fetch, #store, #uid_store, #search,
412
+ # #uid_search, and #append. However, specific parameters are not defined.
413
+ # Extensions to these commands use this syntax whenever possible. Net::IMAP
414
+ # may be partially compatible with extensions to these commands, even without
415
+ # any explicit support.
416
+ #++
417
+ #
418
+ #--
419
+ # ==== RFC4731 +ESEARCH+
420
+ # TODO...
421
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
422
+ # - Updates #search, #uid_search to accept result options: +MIN+, +MAX+,
423
+ # +ALL+, +COUNT+, and to return ExtendedSearchData.
424
+ #++
425
+ #
426
+ #--
427
+ # ==== RFC4959: +SASL-IR+
428
+ # TODO...
429
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
430
+ # - Updates #authenticate to reduce round-trips for supporting mechanisms.
431
+ #++
432
+ #
433
+ #--
434
+ # ==== RFC4978: COMPRESS=DEFLATE
435
+ # TODO...
436
+ #++
437
+ #
438
+ #--
439
+ # ==== RFC5182 +SEARCHRES+
440
+ # TODO...
441
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
442
+ # - Updates #search, #uid_search with the +SAVE+ result option.
443
+ # - Updates #copy, #uid_copy, #fetch, #uid_fetch, #move, #uid_move, #search,
444
+ # #uid_search, #store, #uid_store, and #uid_expunge with ability to
445
+ # reference the saved result of a previous #search or #uid_search command.
446
+ #++
447
+ #
448
+ # ==== RFC5256: +SORT+
449
+ # - #sort, #uid_sort: An alternate version of #search or #uid_search which
450
+ # sorts the results by specified keys.
451
+ # ==== RFC5256: +THREAD+
452
+ # - #thread, #uid_thread: An alternate version of #search or #uid_search,
453
+ # which arranges the results into ordered groups or threads according to a
454
+ # chosen algorithm.
455
+ #
456
+ #--
457
+ # ==== RFC5258 +LIST-EXTENDED+
458
+ # TODO...
459
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], this updates the
460
+ # protocol with new optional parameters to the #list command, adding a few of
461
+ # its own. Net::IMAP may be forward-compatible with future #list extensions,
462
+ # even without any explicit support.
463
+ # - Updates #list to accept selection options: +SUBSCRIBED+, +REMOTE+, and
464
+ # +RECURSIVEMATCH+, and return options: +SUBSCRIBED+ and +CHILDREN+.
465
+ #++
466
+ #
467
+ #--
468
+ # ==== RFC5819 +LIST-STATUS+
469
+ # TODO...
470
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
471
+ # - Updates #list with +STATUS+ return option.
472
+ #++
473
+ #
474
+ # ==== +XLIST+ (non-standard, deprecated)
475
+ # - #xlist: replaced by +SPECIAL-USE+ attributes in #list responses.
476
+ #
477
+ #--
478
+ # ==== RFC6154 +SPECIAL-USE+
479
+ # TODO...
480
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
481
+ # - Updates #list with the +SPECIAL-USE+ selection and return options.
482
+ #++
483
+ #
484
+ # ==== RFC6851: +MOVE+
485
+ # Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051], so it is also
486
+ # listed with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
487
+ # - #move, #uid_move: Moves the specified messages to the end of the
488
+ # specified destination mailbox, expunging them from the current mailbox.
489
+ #
490
+ #--
491
+ # ==== RFC6855: UTF8=ACCEPT
492
+ # TODO...
493
+ # ==== RFC6855: UTF8=ONLY
494
+ # TODO...
495
+ #++
496
+ #
497
+ #--
498
+ # ==== RFC7888: <tt>LITERAL+</tt>, +LITERAL-+
499
+ # TODO...
500
+ # ==== RFC7162: +QRESYNC+
501
+ # TODO...
502
+ # ==== RFC7162: +CONDSTORE+
503
+ # TODO...
504
+ # ==== RFC8474: +OBJECTID+
505
+ # TODO...
506
+ # ==== RFC9208: +QUOTA+
507
+ # TODO...
508
+ #++
509
+ #
510
+ # === Handling server responses
511
+ #
512
+ # - #greeting: The server's initial untagged response, which can indicate a
513
+ # pre-authenticated connection.
514
+ # - #responses: The untagged responses, as a hash. Keys are the untagged
515
+ # response type (e.g. "OK", "FETCH", "FLAGS") and response code (e.g.
516
+ # "ALERT", "UIDVALIDITY", "UIDNEXT", "TRYCREATE", etc). Values are arrays
517
+ # of UntaggedResponse or ResponseCode.
518
+ # - #add_response_handler: Add a block to be called inside the receiver thread
519
+ # with every server response.
520
+ # - #remove_response_handler: Remove a previously added response handler.
521
+ #
153
522
  #
154
523
  # == References
155
524
  #--
@@ -332,7 +701,7 @@ module Net
332
701
  # * {Character sets}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
333
702
  #
334
703
  class IMAP < Protocol
335
- VERSION = "0.3.3"
704
+ VERSION = "0.3.4"
336
705
 
337
706
  include MonitorMixin
338
707
  if defined?(OpenSSL::SSL)
@@ -340,10 +709,12 @@ module Net
340
709
  include SSL
341
710
  end
342
711
 
343
- # Returns an initial greeting response from the server.
712
+ # Returns the initial greeting the server, an UntaggedResponse.
344
713
  attr_reader :greeting
345
714
 
346
- # Returns recorded untagged responses. For example:
715
+ # Returns recorded untagged responses.
716
+ #
717
+ # For example:
347
718
  #
348
719
  # imap.select("inbox")
349
720
  # p imap.responses["EXISTS"][-1]
@@ -392,6 +763,8 @@ module Net
392
763
  end
393
764
 
394
765
  # Disconnects from the server.
766
+ #
767
+ # Related: #logout
395
768
  def disconnect
396
769
  return if disconnected?
397
770
  begin
@@ -415,20 +788,64 @@ module Net
415
788
  end
416
789
 
417
790
  # Returns true if disconnected from the server.
791
+ #
792
+ # Related: #logout, #disconnect
418
793
  def disconnected?
419
794
  return @sock.closed?
420
795
  end
421
796
 
422
- # Sends a CAPABILITY command, and returns an array of
423
- # capabilities that the server supports. Each capability
424
- # is a string. See [IMAP] for a list of possible
425
- # capabilities.
797
+ # Sends a {CAPABILITY command [IMAP4rev1 §6.1.1]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.1.1]
798
+ # and returns an array of capabilities that the server supports. Each
799
+ # capability is a string.
800
+ #
801
+ # See the {IANA IMAP4 capabilities
802
+ # registry}[http://www.iana.org/assignments/imap4-capabilities] for a list
803
+ # of all standard capabilities, and their reference RFCs.
804
+ #
805
+ # >>>
806
+ # <em>*Note* that Net::IMAP does not currently modify its
807
+ # behaviour according to the capabilities of the server;
808
+ # it is up to the user of the class to ensure that
809
+ # a certain capability is supported by a server before
810
+ # using it.</em>
811
+ #
812
+ # Capability requirements—other than +IMAP4rev1+—are listed in the
813
+ # documentation for each command method.
814
+ #
815
+ # ===== Basic IMAP4rev1 capabilities
816
+ #
817
+ # All IMAP4rev1 servers must include +IMAP4rev1+ in their capabilities list.
818
+ # All IMAP4rev1 servers must _implement_ the +STARTTLS+,
819
+ # <tt>AUTH=PLAIN</tt>, and +LOGINDISABLED+ capabilities, and clients must
820
+ # respect their presence or absence. See the capabilites requirements on
821
+ # #starttls, #login, and #authenticate.
822
+ #
823
+ # ===== Using IMAP4rev1 extensions
824
+ #
825
+ # IMAP4rev1 servers must not activate incompatible behavior until an
826
+ # explicit client action invokes a capability, e.g. sending a command or
827
+ # command argument specific to that capability. Extensions with backward
828
+ # compatible behavior, such as response codes or mailbox attributes, may
829
+ # be sent at any time.
830
+ #
831
+ # Invoking capabilities which are unknown to Net::IMAP may cause unexpected
832
+ # behavior and errors, for example ResponseParseError is raised when unknown
833
+ # response syntax is received. Invoking commands or command parameters that
834
+ # are unsupported by the server may raise NoResponseError, BadResponseError,
835
+ # or cause other unexpected behavior.
836
+ #
837
+ # ===== Caching +CAPABILITY+ responses
838
+ #
839
+ # Servers may send their capability list, unsolicited, using the
840
+ # +CAPABILITY+ response code or an untagged +CAPABILITY+ response. These
841
+ # responses can be retrieved and cached using #responses or
842
+ # #add_response_handler.
843
+ #
844
+ # But cached capabilities _must_ be discarded after #starttls, #login, or
845
+ # #authenticate. The OK TaggedResponse to #login and #authenticate may
846
+ # include +CAPABILITY+ response code data, but the TaggedResponse for
847
+ # #starttls is sent clear-text and cannot be trusted.
426
848
  #
427
- # Note that the Net::IMAP class does not modify its
428
- # behaviour according to the capabilities of the server;
429
- # it is up to the user of the class to ensure that
430
- # a certain capability is supported by a server before
431
- # using it.
432
849
  def capability
433
850
  synchronize do
434
851
  send_command("CAPABILITY")
@@ -436,8 +853,9 @@ module Net
436
853
  end
437
854
  end
438
855
 
439
- # Sends an ID command, and returns a hash of the server's
440
- # response, or nil if the server does not identify itself.
856
+ # Sends an {ID command [RFC2971 §3.1]}[https://www.rfc-editor.org/rfc/rfc2971#section-3.1]
857
+ # and returns a hash of the server's response, or nil if the server does not
858
+ # identify itself.
441
859
  #
442
860
  # Note that the user should first check if the server supports the ID
443
861
  # capability. For example:
@@ -453,6 +871,11 @@ module Net
453
871
  # end
454
872
  #
455
873
  # See [ID[https://tools.ietf.org/html/rfc2971]] for field definitions.
874
+ #
875
+ # ===== Capabilities
876
+ #
877
+ # The server's capabilities must include +ID+
878
+ # [RFC2971[https://tools.ietf.org/html/rfc2971]]
456
879
  def id(client_id=nil)
457
880
  synchronize do
458
881
  send_command("ID", ClientID.new(client_id))
@@ -460,18 +883,60 @@ module Net
460
883
  end
461
884
  end
462
885
 
463
- # Sends a NOOP command to the server. It does nothing.
886
+ # Sends a {NOOP command [IMAP4rev1 §6.1.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.1.2]
887
+ # to the server.
888
+ #
889
+ # This allows the server to send unsolicited untagged EXPUNGE #responses,
890
+ # but does not execute any client request. \IMAP servers are permitted to
891
+ # send unsolicited untagged responses at any time, except for `EXPUNGE`.
892
+ #
893
+ # * +EXPUNGE+ can only be sent while a command is in progress.
894
+ # * +EXPUNGE+ must _not_ be sent during #fetch, #store, or #search.
895
+ # * +EXPUNGE+ may be sent during #uid_fetch, #uid_store, or #uid_search.
896
+ #
897
+ # Related: #idle, #check
464
898
  def noop
465
899
  send_command("NOOP")
466
900
  end
467
901
 
468
- # Sends a LOGOUT command to inform the server that the client is
469
- # done with the connection.
902
+ # Sends a {LOGOUT command [IMAP4rev1 §6.1.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.1.3]
903
+ # to inform the command to inform the server that the client is done with
904
+ # the connection.
905
+ #
906
+ # Related: #disconnect
470
907
  def logout
471
908
  send_command("LOGOUT")
472
909
  end
473
910
 
474
- # Sends a STARTTLS command to start TLS session.
911
+ # Sends a {STARTTLS command [IMAP4rev1 §6.2.1]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.1]
912
+ # to start a TLS session.
913
+ #
914
+ # Any +options+ are forwarded to OpenSSL::SSL::SSLContext#set_params.
915
+ #
916
+ # This method returns after TLS negotiation and hostname verification are
917
+ # both successful. Any error indicates that the connection has not been
918
+ # secured.
919
+ #
920
+ # *Note:*
921
+ # >>>
922
+ # Any #response_handlers added before STARTTLS should be aware that the
923
+ # TaggedResponse to STARTTLS is sent clear-text, _before_ TLS negotiation.
924
+ # TLS negotiation starts immediately after that response.
925
+ #
926
+ # Related: Net::IMAP.new, #login, #authenticate
927
+ #
928
+ # ===== Capability
929
+ #
930
+ # The server's capabilities must include +STARTTLS+.
931
+ #
932
+ # Server capabilities may change after #starttls, #login, and #authenticate.
933
+ # Cached capabilities _must_ be invalidated after this method completes.
934
+ #
935
+ # The TaggedResponse to #starttls is sent clear-text, so the server <em>must
936
+ # *not*</em> send capabilities in the #starttls response and clients <em>must
937
+ # not</em> use them if they are sent. Servers will generally send an
938
+ # unsolicited untagged response immeditely _after_ #starttls completes.
939
+ #
475
940
  def starttls(options = {}, verify = true)
476
941
  send_command("STARTTLS") do |resp|
477
942
  if resp.kind_of?(TaggedResponse) && resp.name == "OK"
@@ -486,43 +951,95 @@ module Net
486
951
  end
487
952
  end
488
953
 
489
- # Sends an AUTHENTICATE command to authenticate the client.
490
- # The +auth_type+ parameter is a string that represents
491
- # the authentication mechanism to be used. Currently Net::IMAP
492
- # supports the following mechanisms:
493
- #
494
- # PLAIN:: Login using cleartext user and password. Secure with TLS.
495
- # See Net::IMAP::PlainAuthenticator.
496
- # CRAM-MD5:: DEPRECATED: Use PLAIN (or DIGEST-MD5) with TLS.
497
- # DIGEST-MD5:: DEPRECATED by RFC6331. Must be secured using TLS.
498
- # See Net::IMAP::DigestMD5Authenticator.
499
- # LOGIN:: DEPRECATED: Use PLAIN.
500
- #
501
- # Most mechanisms require two args: authentication identity (e.g. username)
502
- # and credentials (e.g. a password). But each mechanism requires and allows
503
- # different arguments; please consult the documentation for the specific
504
- # mechanisms you are using. <em>Several obsolete mechanisms are available
505
- # for backwards compatibility. Using deprecated mechanisms will issue
506
- # warnings.</em>
507
- #
508
- # Servers do not support all mechanisms and clients must not attempt to use
509
- # a mechanism unless "AUTH=#{mechanism}" is listed as a #capability.
510
- # Clients must not attempt to authenticate or #login when +LOGINDISABLED+ is
511
- # listed with the capabilities. Server capabilities, especially auth
512
- # mechanisms, do change after calling #starttls so they need to be checked
513
- # again.
954
+ # :call-seq:
955
+ # authenticate(mechanism, ...) -> ok_resp
956
+ # authenticate(mech, *creds, **props) {|prop, auth| val } -> ok_resp
957
+ # authenticate(mechanism, authnid, credentials, authzid=nil) -> ok_resp
958
+ # authenticate(mechanism, **properties) -> ok_resp
959
+ # authenticate(mechanism) {|propname, authctx| prop_value } -> ok_resp
514
960
  #
515
- # For example:
961
+ # Sends an {AUTHENTICATE command [IMAP4rev1 §6.2.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.2]
962
+ # to authenticate the client. If successful, the connection enters the
963
+ # "_authenticated_" state.
516
964
  #
517
- # imap.authenticate('PLAIN', user, password)
965
+ # +mechanism+ is the name of the \SASL authentication mechanism to be used.
966
+ # All other arguments are forwarded to the authenticator for the requested
967
+ # mechanism. The listed call signatures are suggestions. <em>The
968
+ # documentation for each individual mechanism must be consulted for its
969
+ # specific parameters.</em>
518
970
  #
519
- # A Net::IMAP::NoResponseError is raised if authentication fails.
971
+ # An exception Net::IMAP::NoResponseError is raised if authentication fails.
972
+ #
973
+ # Related: #login, #starttls
974
+ #
975
+ # ==== Supported SASL Mechanisms
976
+ #
977
+ # +PLAIN+:: See PlainAuthenticator.
978
+ # Login using clear-text username and password.
979
+ #
980
+ # +XOAUTH2+:: See XOauth2Authenticator.
981
+ # Login using a username and OAuth2 access token.
982
+ # Non-standard and obsoleted by +OAUTHBEARER+, but widely
983
+ # supported.
984
+ #
985
+ # >>>
986
+ # *Deprecated:* <em>Obsolete mechanisms are available for backwards
987
+ # compatibility.</em>
988
+ #
989
+ # For +DIGEST-MD5+ see DigestMD5Authenticator.
990
+ #
991
+ # For +LOGIN+, see LoginAuthenticator.
520
992
  #
521
- # See +Net::IMAP::Authenticators+ for more information on plugging in your
522
- # own authenticator.
523
- def authenticate(auth_type, *args)
524
- authenticator = self.class.authenticator(auth_type, *args)
525
- send_command("AUTHENTICATE", auth_type) do |resp|
993
+ # For +CRAM-MD5+, see CramMD5Authenticator.
994
+ #
995
+ # <em>Using a deprecated mechanism will print a warning.</em>
996
+ #
997
+ # See Net::IMAP::Authenticators for information on plugging in
998
+ # authenticators for other mechanisms. See the {SASL mechanism
999
+ # registry}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml]
1000
+ # for information on these and other SASL mechanisms.
1001
+ #
1002
+ # ===== Capabilities
1003
+ #
1004
+ # Clients MUST NOT attempt to authenticate with a mechanism unless
1005
+ # <tt>"AUTH=#{mechanism}"</tt> for that mechanism is a server capability.
1006
+ #
1007
+ # Server capabilities may change after #starttls, #login, and #authenticate.
1008
+ # Cached capabilities _must_ be invalidated after this method completes.
1009
+ # The TaggedResponse to #authenticate may include updated capabilities in
1010
+ # its ResponseCode.
1011
+ #
1012
+ # ===== Example
1013
+ # If the authenticators ignore unhandled keyword arguments, the same config
1014
+ # can be used for multiple mechanisms:
1015
+ #
1016
+ # password = nil # saved locally, so we don't ask more than once
1017
+ # accesstok = nil # saved locally...
1018
+ # creds = {
1019
+ # authcid: username,
1020
+ # password: proc { password ||= ui.prompt_for_password },
1021
+ # oauth2_token: proc { accesstok ||= kms.fresh_access_token },
1022
+ # }
1023
+ # capa = imap.capability
1024
+ # if capa.include? "AUTH=OAUTHBEARER"
1025
+ # imap.authenticate "OAUTHBEARER", **creds # authcid, oauth2_token
1026
+ # elsif capa.include? "AUTH=XOAUTH2"
1027
+ # imap.authenticate "XOAUTH2", **creds # authcid, oauth2_token
1028
+ # elsif capa.include? "AUTH=SCRAM-SHA-256"
1029
+ # imap.authenticate "SCRAM-SHA-256", **creds # authcid, password
1030
+ # elsif capa.include? "AUTH=PLAIN"
1031
+ # imap.authenticate "PLAIN", **creds # authcid, password
1032
+ # elsif capa.include? "AUTH=DIGEST-MD5"
1033
+ # imap.authenticate "DIGEST-MD5", **creds # authcid, password
1034
+ # elsif capa.include? "LOGINDISABLED"
1035
+ # raise "the server has disabled login"
1036
+ # else
1037
+ # imap.login username, password
1038
+ # end
1039
+ #
1040
+ def authenticate(mechanism, *args, **props, &cb)
1041
+ authenticator = self.class.authenticator(mechanism, *args, **props, &cb)
1042
+ send_command("AUTHENTICATE", mechanism) do |resp|
526
1043
  if resp.instance_of?(ContinuationRequest)
527
1044
  data = authenticator.process(resp.data.text.unpack("m")[0])
528
1045
  s = [data].pack("m0")
@@ -532,18 +1049,33 @@ module Net
532
1049
  end
533
1050
  end
534
1051
 
535
- # Sends a LOGIN command to identify the client and carries
536
- # the plaintext +password+ authenticating this +user+. Note
537
- # that, unlike calling #authenticate with an +auth_type+
538
- # of "LOGIN", #login does *not* use the login authenticator.
1052
+ # Sends a {LOGIN command [IMAP4rev1 §6.2.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.3]
1053
+ # to identify the client and carries the plaintext +password+ authenticating
1054
+ # this +user+. If successful, the connection enters the "_authenticated_"
1055
+ # state.
1056
+ #
1057
+ # Using #authenticate is generally preferred over #login. The LOGIN command
1058
+ # is not the same as #authenticate with the "LOGIN" +mechanism+.
539
1059
  #
540
1060
  # A Net::IMAP::NoResponseError is raised if authentication fails.
1061
+ #
1062
+ # Related: #authenticate, #starttls
1063
+ #
1064
+ # ==== Capabilities
1065
+ # Clients MUST NOT call #login if +LOGINDISABLED+ is listed with the
1066
+ # capabilities.
1067
+ #
1068
+ # Server capabilities may change after #starttls, #login, and #authenticate.
1069
+ # Cached capabilities _must_ be invalidated after this method completes.
1070
+ # The TaggedResponse to #login may include updated capabilities in its
1071
+ # ResponseCode.
1072
+ #
541
1073
  def login(user, password)
542
1074
  send_command("LOGIN", user, password)
543
1075
  end
544
1076
 
545
- # Sends a SELECT command to select a +mailbox+ so that messages
546
- # in the +mailbox+ can be accessed.
1077
+ # Sends a {SELECT command [IMAP4rev1 §6.3.1]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.1]
1078
+ # to select a +mailbox+ so that messages in the +mailbox+ can be accessed.
547
1079
  #
548
1080
  # After you have selected a mailbox, you may retrieve the number of items in
549
1081
  # that mailbox from <tt>imap.responses["EXISTS"][-1]</tt>, and the number of
@@ -555,7 +1087,9 @@ module Net
555
1087
  # A Net::IMAP::NoResponseError is raised if the mailbox does not
556
1088
  # exist or is for some reason non-selectable.
557
1089
  #
558
- # ==== Capabilities
1090
+ # Related: #examine
1091
+ #
1092
+ # ===== Capabilities
559
1093
  #
560
1094
  # If [UIDPLUS[https://www.rfc-editor.org/rfc/rfc4315.html]] is supported,
561
1095
  # the server may return an untagged "NO" response with a "UIDNOTSTICKY"
@@ -569,12 +1103,15 @@ module Net
569
1103
  end
570
1104
  end
571
1105
 
572
- # Sends a EXAMINE command to select a +mailbox+ so that messages
573
- # in the +mailbox+ can be accessed. Behaves the same as #select,
574
- # except that the selected +mailbox+ is identified as read-only.
1106
+ # Sends a {EXAMINE command [IMAP4rev1 §6.3.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.2]
1107
+ # to select a +mailbox+ so that messages in the +mailbox+ can be accessed.
1108
+ # Behaves the same as #select, except that the selected +mailbox+ is
1109
+ # identified as read-only.
575
1110
  #
576
1111
  # A Net::IMAP::NoResponseError is raised if the mailbox does not
577
1112
  # exist or is for some reason non-examinable.
1113
+ #
1114
+ # Related: #select
578
1115
  def examine(mailbox)
579
1116
  synchronize do
580
1117
  @responses.clear
@@ -582,69 +1119,86 @@ module Net
582
1119
  end
583
1120
  end
584
1121
 
585
- # Sends a CREATE command to create a new +mailbox+.
1122
+ # Sends a {CREATE command [IMAP4rev1 §6.3.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.3]
1123
+ # to create a new +mailbox+.
586
1124
  #
587
1125
  # A Net::IMAP::NoResponseError is raised if a mailbox with that name
588
1126
  # cannot be created.
1127
+ #
1128
+ # Related: #rename, #delete
589
1129
  def create(mailbox)
590
1130
  send_command("CREATE", mailbox)
591
1131
  end
592
1132
 
593
- # Sends a DELETE command to remove the +mailbox+.
1133
+ # Sends a {DELETE command [IMAP4rev1 §6.3.4]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.4]
1134
+ # to remove the +mailbox+.
594
1135
  #
595
1136
  # A Net::IMAP::NoResponseError is raised if a mailbox with that name
596
1137
  # cannot be deleted, either because it does not exist or because the
597
1138
  # client does not have permission to delete it.
1139
+ #
1140
+ # Related: #create, #rename
598
1141
  def delete(mailbox)
599
1142
  send_command("DELETE", mailbox)
600
1143
  end
601
1144
 
602
- # Sends a RENAME command to change the name of the +mailbox+ to
603
- # +newname+.
1145
+ # Sends a {RENAME command [IMAP4rev1 §6.3.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.5]
1146
+ # to change the name of the +mailbox+ to +newname+.
604
1147
  #
605
1148
  # A Net::IMAP::NoResponseError is raised if a mailbox with the
606
1149
  # name +mailbox+ cannot be renamed to +newname+ for whatever
607
1150
  # reason; for instance, because +mailbox+ does not exist, or
608
1151
  # because there is already a mailbox with the name +newname+.
1152
+ #
1153
+ # Related: #create, #delete
609
1154
  def rename(mailbox, newname)
610
1155
  send_command("RENAME", mailbox, newname)
611
1156
  end
612
1157
 
613
- # Sends a SUBSCRIBE command to add the specified +mailbox+ name to
614
- # the server's set of "active" or "subscribed" mailboxes as returned
615
- # by #lsub.
1158
+ # Sends a {SUBSCRIBE command [IMAP4rev1 §6.3.6]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.6]
1159
+ # to add the specified +mailbox+ name to the server's set of "active" or
1160
+ # "subscribed" mailboxes as returned by #lsub.
616
1161
  #
617
1162
  # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be
618
1163
  # subscribed to; for instance, because it does not exist.
1164
+ #
1165
+ # Related: #unsubscribe, #lsub, #list
619
1166
  def subscribe(mailbox)
620
1167
  send_command("SUBSCRIBE", mailbox)
621
1168
  end
622
1169
 
623
- # Sends a UNSUBSCRIBE command to remove the specified +mailbox+ name
624
- # from the server's set of "active" or "subscribed" mailboxes.
1170
+ # Sends an {UNSUBSCRIBE command [IMAP4rev1 §6.3.7]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.7]
1171
+ # to remove the specified +mailbox+ name from the server's set of "active"
1172
+ # or "subscribed" mailboxes.
625
1173
  #
626
1174
  # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be
627
1175
  # unsubscribed from; for instance, because the client is not currently
628
1176
  # subscribed to it.
1177
+ #
1178
+ # Related: #subscribe, #lsub, #list
629
1179
  def unsubscribe(mailbox)
630
1180
  send_command("UNSUBSCRIBE", mailbox)
631
1181
  end
632
1182
 
633
- # Sends a LIST command, and returns a subset of names from
634
- # the complete set of all names available to the client.
635
- # +refname+ provides a context (for instance, a base directory
636
- # in a directory-based mailbox hierarchy). +mailbox+ specifies
637
- # a mailbox or (via wildcards) mailboxes under that context.
638
- # Two wildcards may be used in +mailbox+: '*', which matches
639
- # all characters *including* the hierarchy delimiter (for instance,
640
- # '/' on a UNIX-hosted directory-based mailbox hierarchy); and '%',
641
- # which matches all characters *except* the hierarchy delimiter.
1183
+ # Sends a {LIST command [IMAP4rev1 §6.3.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.8]
1184
+ # and returns a subset of names from the complete set of all names available
1185
+ # to the client. +refname+ provides a context (for instance, a base
1186
+ # directory in a directory-based mailbox hierarchy). +mailbox+ specifies a
1187
+ # mailbox or (via wildcards) mailboxes under that context. Two wildcards
1188
+ # may be used in +mailbox+: '*', which matches all characters *including*
1189
+ # the hierarchy delimiter (for instance, '/' on a UNIX-hosted
1190
+ # directory-based mailbox hierarchy); and '%', which matches all characters
1191
+ # *except* the hierarchy delimiter.
642
1192
  #
643
1193
  # If +refname+ is empty, +mailbox+ is used directly to determine
644
1194
  # which mailboxes to match. If +mailbox+ is empty, the root
645
1195
  # name of +refname+ and the hierarchy delimiter are returned.
646
1196
  #
647
- # The return value is an array of +Net::IMAP::MailboxList+. For example:
1197
+ # The return value is an array of MailboxList.
1198
+ #
1199
+ # Related: #lsub, MailboxList
1200
+ #
1201
+ # ===== For example:
648
1202
  #
649
1203
  # imap.create("foo/bar")
650
1204
  # imap.create("foo/baz")
@@ -652,6 +1206,10 @@ module Net
652
1206
  # #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
653
1207
  # #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
654
1208
  # #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
1209
+ #
1210
+ #--
1211
+ # TODO: support LIST-EXTENDED extension [RFC5258]. Needed for IMAP4rev2.
1212
+ #++
655
1213
  def list(refname, mailbox)
656
1214
  synchronize do
657
1215
  send_command("LIST", refname, mailbox)
@@ -659,41 +1217,39 @@ module Net
659
1217
  end
660
1218
  end
661
1219
 
662
- # Sends a NAMESPACE command and returns the namespaces that are available.
663
- # The NAMESPACE command allows a client to discover the prefixes of
664
- # namespaces used by a server for personal mailboxes, other users'
665
- # mailboxes, and shared mailboxes.
1220
+ # Sends a {NAMESPACE command [RFC2342 §5]}[https://www.rfc-editor.org/rfc/rfc2342#section-5]
1221
+ # and returns the namespaces that are available. The NAMESPACE command
1222
+ # allows a client to discover the prefixes of namespaces used by a server
1223
+ # for personal mailboxes, other users' mailboxes, and shared mailboxes.
666
1224
  #
667
- # The NAMESPACE extension predates [IMAP4rev1[https://tools.ietf.org/html/rfc2501]],
668
- # so most IMAP servers support it. Many popular IMAP servers are configured
669
- # with the default personal namespaces as `("" "/")`: no prefix and "/"
670
- # hierarchy delimiter. In that common case, the naive client may not have
671
- # any trouble naming mailboxes.
1225
+ # The return value is a Namespaces object which has +personal+, +other+, and
1226
+ # +shared+ fields, each an array of Namespace objects. These arrays will be
1227
+ # empty when the server responds with +nil+.
672
1228
  #
1229
+ # Many \IMAP servers are configured with the default personal namespaces as
1230
+ # <tt>("" "/")</tt>: no prefix and the "+/+" hierarchy delimiter. In that
1231
+ # common case, the naive client may not have any trouble naming mailboxes.
673
1232
  # But many servers are configured with the default personal namespace as
674
- # e.g. `("INBOX." ".")`, placing all personal folders under INBOX, with "."
675
- # as the hierarchy delimiter. If the client does not check for this, but
676
- # naively assumes it can use the same folder names for all servers, then
677
- # folder creation (and listing, moving, etc) can lead to errors.
1233
+ # e.g. <tt>("INBOX." ".")</tt>, placing all personal folders under INBOX,
1234
+ # with "+.+" as the hierarchy delimiter. If the client does not check for
1235
+ # this, but naively assumes it can use the same folder names for all
1236
+ # servers, then folder creation (and listing, moving, etc) can lead to
1237
+ # errors.
678
1238
  #
679
1239
  # From RFC2342:
680
1240
  #
681
1241
  # Although typically a server will support only a single Personal
682
1242
  # Namespace, and a single Other User's Namespace, circumstances exist
683
1243
  # where there MAY be multiples of these, and a client MUST be prepared
684
- # for them. If a client is configured such that it is required to create
1244
+ # for them. If a client is configured such that it is required to create
685
1245
  # a certain mailbox, there can be circumstances where it is unclear which
686
- # Personal Namespaces it should create the mailbox in. In these
1246
+ # Personal Namespaces it should create the mailbox in. In these
687
1247
  # situations a client SHOULD let the user select which namespaces to
688
1248
  # create the mailbox in.
689
1249
  #
690
- # The user of this method should first check if the server supports the
691
- # NAMESPACE capability. The return value is a +Net::IMAP::Namespaces+
692
- # object which has +personal+, +other+, and +shared+ fields, each an array
693
- # of +Net::IMAP::Namespace+ objects. These arrays will be empty when the
694
- # server responds with nil.
1250
+ # Related: #list, Namespaces, Namespace
695
1251
  #
696
- # For example:
1252
+ # ===== For example:
697
1253
  #
698
1254
  # capabilities = imap.capability
699
1255
  # if capabilities.include?("NAMESPACE")
@@ -708,7 +1264,10 @@ module Net
708
1264
  # end
709
1265
  # end
710
1266
  #
711
- # The NAMESPACE extension is described in [NAMESPACE[https://tools.ietf.org/html/rfc2342]]
1267
+ # ===== Capabilities
1268
+ #
1269
+ # The server's capabilities must include +NAMESPACE+
1270
+ # [RFC2342[https://tools.ietf.org/html/rfc2342]].
712
1271
  def namespace
713
1272
  synchronize do
714
1273
  send_command("NAMESPACE")
@@ -733,7 +1292,7 @@ module Net
733
1292
  # The XLIST command is like the LIST command except that the flags
734
1293
  # returned refer to the function of the folder/mailbox, e.g. :Sent
735
1294
  #
736
- # The return value is an array of +Net::IMAP::MailboxList+. For example:
1295
+ # The return value is an array of MailboxList objects. For example:
737
1296
  #
738
1297
  # imap.create("foo/bar")
739
1298
  # imap.create("foo/baz")
@@ -741,6 +1300,18 @@ module Net
741
1300
  # #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\
742
1301
  # #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\
743
1302
  # #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
1303
+ #
1304
+ # Related: #list, MailboxList
1305
+ #
1306
+ # ===== Capabilities
1307
+ #
1308
+ # The server's capabilities must include +XLIST+,
1309
+ # a deprecated Gmail extension (replaced by +SPECIAL-USE+).
1310
+ #--
1311
+ # TODO: Net::IMAP doesn't yet have full SPECIAL-USE support. Supporting
1312
+ # servers MAY return SPECIAL-USE attributes, but are not *required* to
1313
+ # unless the SPECIAL-USE return option is supplied.
1314
+ #++
744
1315
  def xlist(refname, mailbox)
745
1316
  synchronize do
746
1317
  send_command("XLIST", refname, mailbox)
@@ -748,12 +1319,17 @@ module Net
748
1319
  end
749
1320
  end
750
1321
 
751
- # Sends the GETQUOTAROOT command along with the specified +mailbox+.
752
- # This command is generally available to both admin and user.
753
- # If this mailbox exists, it returns an array containing objects of type
754
- # Net::IMAP::MailboxQuotaRoot and Net::IMAP::MailboxQuota.
1322
+ # Sends a {GETQUOTAROOT command [RFC2087 §4.3]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.3]
1323
+ # along with the specified +mailbox+. This command is generally available
1324
+ # to both admin and user. If this mailbox exists, it returns an array
1325
+ # containing objects of type MailboxQuotaRoot and MailboxQuota.
1326
+ #
1327
+ # Related: #getquota, #setquota, MailboxQuotaRoot, MailboxQuota
1328
+ #
1329
+ # ===== Capabilities
755
1330
  #
756
- # The QUOTA extension is described in [QUOTA[https://tools.ietf.org/html/rfc2087]]
1331
+ # The server's capabilities must include +QUOTA+
1332
+ # [RFC2087[https://tools.ietf.org/html/rfc2087]].
757
1333
  def getquotaroot(mailbox)
758
1334
  synchronize do
759
1335
  send_command("GETQUOTAROOT", mailbox)
@@ -764,12 +1340,17 @@ module Net
764
1340
  end
765
1341
  end
766
1342
 
767
- # Sends the GETQUOTA command along with specified +mailbox+.
768
- # If this mailbox exists, then an array containing a
769
- # Net::IMAP::MailboxQuota object is returned. This
770
- # command is generally only available to server admin.
1343
+ # Sends a {GETQUOTA command [RFC2087 §4.2]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.2]
1344
+ # along with specified +mailbox+. If this mailbox exists, then an array
1345
+ # containing a MailboxQuota object is returned. This command is generally
1346
+ # only available to server admin.
771
1347
  #
772
- # The QUOTA extension is described in [QUOTA[https://tools.ietf.org/html/rfc2087]]
1348
+ # Related: #getquotaroot, #setquota, MailboxQuota
1349
+ #
1350
+ # ===== Capabilities
1351
+ #
1352
+ # The server's capabilities must include +QUOTA+
1353
+ # [RFC2087[https://tools.ietf.org/html/rfc2087]].
773
1354
  def getquota(mailbox)
774
1355
  synchronize do
775
1356
  send_command("GETQUOTA", mailbox)
@@ -777,12 +1358,17 @@ module Net
777
1358
  end
778
1359
  end
779
1360
 
780
- # Sends a SETQUOTA command along with the specified +mailbox+ and
781
- # +quota+. If +quota+ is nil, then +quota+ will be unset for that
782
- # mailbox. Typically one needs to be logged in as a server admin
783
- # for this to work.
1361
+ # Sends a {SETQUOTA command [RFC2087 §4.1]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.1]
1362
+ # along with the specified +mailbox+ and +quota+. If +quota+ is nil, then
1363
+ # +quota+ will be unset for that mailbox. Typically one needs to be logged
1364
+ # in as a server admin for this to work.
1365
+ #
1366
+ # Related: #getquota, #getquotaroot
1367
+ #
1368
+ # ===== Capabilities
784
1369
  #
785
- # The QUOTA extension is described in [QUOTA[https://tools.ietf.org/html/rfc2087]]
1370
+ # The server's capabilities must include +QUOTA+
1371
+ # [RFC2087[https://tools.ietf.org/html/rfc2087]].
786
1372
  def setquota(mailbox, quota)
787
1373
  if quota.nil?
788
1374
  data = '()'
@@ -792,11 +1378,17 @@ module Net
792
1378
  send_command("SETQUOTA", mailbox, RawData.new(data))
793
1379
  end
794
1380
 
795
- # Sends the SETACL command along with +mailbox+, +user+ and the
796
- # +rights+ that user is to have on that mailbox. If +rights+ is nil,
797
- # then that user will be stripped of any rights to that mailbox.
1381
+ # Sends a {SETACL command [RFC4314 §3.1]}[https://www.rfc-editor.org/rfc/rfc4314#section-3.1]
1382
+ # along with +mailbox+, +user+ and the +rights+ that user is to have on that
1383
+ # mailbox. If +rights+ is nil, then that user will be stripped of any
1384
+ # rights to that mailbox.
1385
+ #
1386
+ # Related: #getacl
798
1387
  #
799
- # The ACL extension is described in [ACL[https://tools.ietf.org/html/rfc4314]]
1388
+ # ===== Capabilities
1389
+ #
1390
+ # The server's capabilities must include +ACL+
1391
+ # [RFC4314[https://tools.ietf.org/html/rfc4314]].
800
1392
  def setacl(mailbox, user, rights)
801
1393
  if rights.nil?
802
1394
  send_command("SETACL", mailbox, user, "")
@@ -805,11 +1397,16 @@ module Net
805
1397
  end
806
1398
  end
807
1399
 
808
- # Send the GETACL command along with a specified +mailbox+.
809
- # If this mailbox exists, an array containing objects of
810
- # Net::IMAP::MailboxACLItem will be returned.
1400
+ # Sends a {GETACL command [RFC4314 §3.3]}[https://www.rfc-editor.org/rfc/rfc4314#section-3.3]
1401
+ # along with a specified +mailbox+. If this mailbox exists, an array
1402
+ # containing objects of MailboxACLItem will be returned.
1403
+ #
1404
+ # Related: #setacl, MailboxACLItem
811
1405
  #
812
- # The ACL extension is described in [ACL[https://tools.ietf.org/html/rfc4314]]
1406
+ # ===== Capabilities
1407
+ #
1408
+ # The server's capabilities must include +ACL+
1409
+ # [RFC4314[https://tools.ietf.org/html/rfc4314]].
813
1410
  def getacl(mailbox)
814
1411
  synchronize do
815
1412
  send_command("GETACL", mailbox)
@@ -817,12 +1414,14 @@ module Net
817
1414
  end
818
1415
  end
819
1416
 
820
- # Sends a LSUB command, and returns a subset of names from the set
821
- # of names that the user has declared as being "active" or
822
- # "subscribed." +refname+ and +mailbox+ are interpreted as
823
- # for #list.
1417
+ # Sends a {LSUB command [IMAP4rev1 §6.3.9]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.9]
1418
+ # and returns a subset of names from the set of names that the user has
1419
+ # declared as being "active" or "subscribed." +refname+ and +mailbox+ are
1420
+ # interpreted as for #list.
1421
+ #
1422
+ # The return value is an array of MailboxList objects.
824
1423
  #
825
- # The return value is an array of +Net::IMAP::MailboxList+.
1424
+ # Related: #subscribe, #unsubscribe, #list, MailboxList
826
1425
  def lsub(refname, mailbox)
827
1426
  synchronize do
828
1427
  send_command("LSUB", refname, mailbox)
@@ -830,9 +1429,10 @@ module Net
830
1429
  end
831
1430
  end
832
1431
 
833
- # Sends a STATUS command, and returns the status of the indicated
834
- # +mailbox+. +attr+ is a list of one or more attributes whose
835
- # statuses are to be requested. Supported attributes include:
1432
+ # Sends a {STATUS commands [IMAP4rev1 §6.3.10]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.10]
1433
+ # and returns the status of the indicated +mailbox+. +attr+ is a list of one
1434
+ # or more attributes whose statuses are to be requested. Supported
1435
+ # attributes include:
836
1436
  #
837
1437
  # MESSAGES:: the number of messages in the mailbox.
838
1438
  # RECENT:: the number of recent messages in the mailbox.
@@ -853,11 +1453,12 @@ module Net
853
1453
  end
854
1454
  end
855
1455
 
856
- # Sends a APPEND command to append the +message+ to the end of
857
- # the +mailbox+. The optional +flags+ argument is an array of
858
- # flags initially passed to the new message. The optional
859
- # +date_time+ argument specifies the creation time to assign to the
1456
+ # Sends an {APPEND command [IMAP4rev1 §6.3.11]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.11]
1457
+ # to append the +message+ to the end of the +mailbox+. The optional +flags+
1458
+ # argument is an array of flags initially passed to the new message. The
1459
+ # optional +date_time+ argument specifies the creation time to assign to the
860
1460
  # new message; it defaults to the current time.
1461
+ #
861
1462
  # For example:
862
1463
  #
863
1464
  # imap.append("inbox", <<EOF.gsub(/\n/, "\r\n"), [:Seen], Time.now)
@@ -872,12 +1473,13 @@ module Net
872
1473
  # not exist (it is not created automatically), or if the flags,
873
1474
  # date_time, or message arguments contain errors.
874
1475
  #
875
- # ==== Capabilities
1476
+ # ===== Capabilities
876
1477
  #
877
1478
  # If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
878
- # supported, the server's response should include a +APPENDUID+ response
879
- # code with the UIDVALIDITY of the destination mailbox and the assigned UID
880
- # of the appended message.
1479
+ # supported and the destination supports persistent UIDs, the server's
1480
+ # response should include an +APPENDUID+ response code with UIDPlusData.
1481
+ # This will report the UIDVALIDITY of the destination mailbox and the
1482
+ # assigned UID of the appended message.
881
1483
  #
882
1484
  #--
883
1485
  # TODO: add MULTIAPPEND support
@@ -892,26 +1494,33 @@ module Net
892
1494
  send_command("APPEND", mailbox, *args)
893
1495
  end
894
1496
 
895
- # Sends a CHECK command to request a checkpoint of the currently
896
- # selected mailbox. This performs implementation-specific
897
- # housekeeping; for instance, reconciling the mailbox's
898
- # in-memory and on-disk state.
1497
+ # Sends a {CHECK command [IMAP4rev1 §6.4.1]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.1]
1498
+ # to request a checkpoint of the currently selected mailbox. This performs
1499
+ # implementation-specific housekeeping; for instance, reconciling the
1500
+ # mailbox's in-memory and on-disk state.
1501
+ #
1502
+ # Related: #idle, #noop
899
1503
  def check
900
1504
  send_command("CHECK")
901
1505
  end
902
1506
 
903
- # Sends a CLOSE command to close the currently selected mailbox.
904
- # The CLOSE command permanently removes from the mailbox all
905
- # messages that have the \Deleted flag set.
1507
+ # Sends a {CLOSE command [IMAP4rev1 §6.4.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.2]
1508
+ # to close the currently selected mailbox. The CLOSE command permanently
1509
+ # removes from the mailbox all messages that have the <tt>\\Deleted</tt>
1510
+ # flag set.
1511
+ #
1512
+ # Related: #unselect
906
1513
  def close
907
1514
  send_command("CLOSE")
908
1515
  end
909
1516
 
910
- # Sends an {UNSELECT command [IMAP4rev2
911
- # §6.4.2]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.2] to free the
912
- # session resources for a mailbox and return to the "_authenticated_" state.
913
- # This is the same as #close, except that <tt>\\Deleted</tt> messages are
914
- # not removed from the mailbox.
1517
+ # Sends an {UNSELECT command [RFC3691 §2]}[https://www.rfc-editor.org/rfc/rfc3691#section-3]
1518
+ # {[IMAP4rev2 §6.4.2]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.2]
1519
+ # to free the session resources for a mailbox and return to the
1520
+ # "_authenticated_" state. This is the same as #close, except that
1521
+ # <tt>\\Deleted</tt> messages are not removed from the mailbox.
1522
+ #
1523
+ # Related: #close
915
1524
  #
916
1525
  # ===== Capabilities
917
1526
  #
@@ -921,8 +1530,11 @@ module Net
921
1530
  send_command("UNSELECT")
922
1531
  end
923
1532
 
1533
+ # Sends an {EXPUNGE command [IMAP4rev1 §6.4.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.3]
924
1534
  # Sends a EXPUNGE command to permanently remove from the currently
925
1535
  # selected mailbox all messages that have the \Deleted flag set.
1536
+ #
1537
+ # Related: #uid_expunge
926
1538
  def expunge
927
1539
  synchronize do
928
1540
  send_command("EXPUNGE")
@@ -930,27 +1542,31 @@ module Net
930
1542
  end
931
1543
  end
932
1544
 
933
- # Similar to #expunge, but takes a set of unique identifiers as
934
- # argument. Sends a UID EXPUNGE command to permanently remove all
935
- # messages that have both the \\Deleted flag set and a UID that is
936
- # included in +uid_set+.
1545
+ # Sends a {UID EXPUNGE command [RFC4315 §2.1]}[https://www.rfc-editor.org/rfc/rfc4315#section-2.1]
1546
+ # {[IMAP4rev2 §6.4.9]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.9]
1547
+ # to permanently remove all messages that have both the <tt>\\Deleted</tt>
1548
+ # flag set and a UID that is included in +uid_set+.
937
1549
  #
938
- # By using UID EXPUNGE instead of EXPUNGE when resynchronizing with
1550
+ # By using #uid_expunge instead of #expunge when resynchronizing with
939
1551
  # the server, the client can ensure that it does not inadvertantly
940
- # remove any messages that have been marked as \\Deleted by other
1552
+ # remove any messages that have been marked as <tt>\\Deleted</tt> by other
941
1553
  # clients between the time that the client was last connected and
942
1554
  # the time the client resynchronizes.
943
1555
  #
944
- # Note:: Although the command takes a +uid_set+ for its argument, the
1556
+ # *Note:*
1557
+ # >>>
1558
+ # Although the command takes a set of UIDs for its argument, the
945
1559
  # server still returns regular EXPUNGE responses, which contain
946
1560
  # a <em>sequence number</em>. These will be deleted from
947
1561
  # #responses and this method returns them as an array of
948
1562
  # <em>sequence number</em> integers.
949
1563
  #
950
- # ==== Capability requirement
1564
+ # Related: #expunge
1565
+ #
1566
+ # ===== Capabilities
951
1567
  #
952
- # +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] must be
953
- # supported by the server.
1568
+ # The server's capabilities must include +UIDPLUS+
1569
+ # [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]].
954
1570
  def uid_expunge(uid_set)
955
1571
  synchronize do
956
1572
  send_command("UID EXPUNGE", MessageSet.new(uid_set))
@@ -958,20 +1574,33 @@ module Net
958
1574
  end
959
1575
  end
960
1576
 
961
- # Sends a SEARCH command to search the mailbox for messages that
962
- # match the given searching criteria, and returns message sequence
963
- # numbers. +keys+ can either be a string holding the entire
964
- # search string, or a single-dimension array of search keywords and
965
- # arguments. The following are some common search criteria;
966
- # see [IMAP] section 6.4.4 for a full list.
1577
+ # Sends a {SEARCH command [IMAP4rev1 §6.4.4]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.4]
1578
+ # to search the mailbox for messages that match the given searching
1579
+ # criteria, and returns message sequence numbers. +keys+ can either be a
1580
+ # string holding the entire search string, or a single-dimension array of
1581
+ # search keywords and arguments.
1582
+ #
1583
+ # Related: #uid_search
1584
+ #
1585
+ # ===== Search criteria
967
1586
  #
968
- # <message set>:: a set of message sequence numbers. ',' indicates
969
- # an interval, ':' indicates a range. For instance,
970
- # '2,10:12,15' means "2,10,11,12,15".
1587
+ # For a full list of search criteria,
1588
+ # see [{IMAP4rev1 §6.4.4}[https://www.rfc-editor.org/rfc/rfc3501.html#section-6.4.4]],
1589
+ # or [{IMAP4rev2 §6.4.4}[https://www.rfc-editor.org/rfc/rfc9051.html#section-6.4.4]],
1590
+ # in addition to documentation for
1591
+ # any [CAPABILITIES[https://www.iana.org/assignments/imap-capabilities/imap-capabilities.xhtml]]
1592
+ # reported by #capability which may define additional search filters, e.g:
1593
+ # +CONDSTORE+, +WITHIN+, +FILTERS+, <tt>SEARCH=FUZZY</tt>, +OBJECTID+, or
1594
+ # +SAVEDATE+. The following are some common search criteria:
1595
+ #
1596
+ # <message set>:: a set of message sequence numbers. "<tt>,</tt>" indicates
1597
+ # an interval, "+:+" indicates a range. For instance,
1598
+ # "<tt>2,10:12,15</tt>" means "<tt>2,10,11,12,15</tt>".
971
1599
  #
972
1600
  # BEFORE <date>:: messages with an internal date strictly before
973
- # <date>. The date argument has a format similar
974
- # to 8-Aug-2002.
1601
+ # <b><date></b>. The date argument has a format similar
1602
+ # to <tt>8-Aug-2002</tt>, and can be formatted using
1603
+ # Net::IMAP.format_date.
975
1604
  #
976
1605
  # BODY <string>:: messages that contain <string> within their body.
977
1606
  #
@@ -994,21 +1623,26 @@ module Net
994
1623
  #
995
1624
  # TO <string>:: messages with <string> in their TO field.
996
1625
  #
997
- # For example:
1626
+ # ===== For example:
998
1627
  #
999
1628
  # p imap.search(["SUBJECT", "hello", "NOT", "NEW"])
1000
1629
  # #=> [1, 6, 7, 8]
1630
+ #
1001
1631
  def search(keys, charset = nil)
1002
1632
  return search_internal("SEARCH", keys, charset)
1003
1633
  end
1004
1634
 
1005
- # Similar to #search, but returns unique identifiers.
1635
+ # Sends a {UID SEARCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
1636
+ # to search the mailbox for messages that match the given searching
1637
+ # criteria, and returns unique identifiers (<tt>UID</tt>s).
1638
+ #
1639
+ # See #search for documentation of search criteria.
1006
1640
  def uid_search(keys, charset = nil)
1007
1641
  return search_internal("UID SEARCH", keys, charset)
1008
1642
  end
1009
1643
 
1010
- # Sends a FETCH command to retrieve data associated with a message
1011
- # in the mailbox.
1644
+ # Sends a {FETCH command [IMAP4rev1 §6.4.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5]
1645
+ # to retrieve data associated with a message in the mailbox.
1012
1646
  #
1013
1647
  # The +set+ parameter is a number or a range between two numbers,
1014
1648
  # or an array of those. The number is a message sequence number,
@@ -1020,12 +1654,14 @@ module Net
1020
1654
  # equivalent to 1..5.
1021
1655
  #
1022
1656
  # +attr+ is a list of attributes to fetch; see the documentation
1023
- # for Net::IMAP::FetchData for a list of valid attributes.
1657
+ # for FetchData for a list of valid attributes.
1024
1658
  #
1025
- # The return value is an array of Net::IMAP::FetchData or nil
1659
+ # The return value is an array of FetchData or nil
1026
1660
  # (instead of an empty array) if there is no matching message.
1027
1661
  #
1028
- # For example:
1662
+ # Related: #uid_search, FetchData
1663
+ #
1664
+ # ===== For example:
1029
1665
  #
1030
1666
  # p imap.fetch(6..8, "UID")
1031
1667
  # #=> [#<Net::IMAP::FetchData seqno=6, attr={"UID"=>98}>, \\
@@ -1046,20 +1682,35 @@ module Net
1046
1682
  return fetch_internal("FETCH", set, attr, mod)
1047
1683
  end
1048
1684
 
1049
- # Similar to #fetch, but +set+ contains unique identifiers.
1685
+ # Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
1686
+ # to retrieve data associated with a message in the mailbox.
1687
+ #
1688
+ # Similar to #fetch, but the +set+ parameter contains unique identifiers
1689
+ # instead of message sequence numbers.
1690
+ #
1691
+ # >>>
1692
+ # *Note:* Servers _MUST_ implicitly include the +UID+ message data item as
1693
+ # part of any +FETCH+ response caused by a +UID+ command, regardless of
1694
+ # whether a +UID+ was specified as a message data item to the +FETCH+.
1695
+ #
1696
+ # Related: #fetch, FetchData
1050
1697
  def uid_fetch(set, attr, mod = nil)
1051
1698
  return fetch_internal("UID FETCH", set, attr, mod)
1052
1699
  end
1053
1700
 
1054
- # Sends a STORE command to alter data associated with messages
1055
- # in the mailbox, in particular their flags. The +set+ parameter
1056
- # is a number, an array of numbers, or a Range object. Each number
1057
- # is a message sequence number. +attr+ is the name of a data item
1058
- # to store: 'FLAGS' will replace the message's flag list
1059
- # with the provided one, '+FLAGS' will add the provided flags,
1060
- # and '-FLAGS' will remove them. +flags+ is a list of flags.
1701
+ # Sends a {STORE command [IMAP4rev1 §6.4.6]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.6]
1702
+ # to alter data associated with messages in the mailbox, in particular their
1703
+ # flags. The +set+ parameter is a number, an array of numbers, or a Range
1704
+ # object. Each number is a message sequence number. +attr+ is the name of a
1705
+ # data item to store: 'FLAGS' will replace the message's flag list with the
1706
+ # provided one, '+FLAGS' will add the provided flags, and '-FLAGS' will
1707
+ # remove them. +flags+ is a list of flags.
1708
+ #
1709
+ # The return value is an array of FetchData
1061
1710
  #
1062
- # The return value is an array of Net::IMAP::FetchData. For example:
1711
+ # Related: #uid_store
1712
+ #
1713
+ # ===== For example:
1063
1714
  #
1064
1715
  # p imap.store(6..8, "+FLAGS", [:Deleted])
1065
1716
  # #=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\
@@ -1069,110 +1720,137 @@ module Net
1069
1720
  return store_internal("STORE", set, attr, flags)
1070
1721
  end
1071
1722
 
1072
- # Similar to #store, but +set+ contains unique identifiers.
1723
+ # Sends a {UID STORE command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
1724
+ # to alter data associated with messages in the mailbox, in particular their
1725
+ # flags.
1726
+ #
1727
+ # Similar to #store, but +set+ contains unique identifiers instead of
1728
+ # message sequence numbers.
1729
+ #
1730
+ # Related: #store
1073
1731
  def uid_store(set, attr, flags)
1074
1732
  return store_internal("UID STORE", set, attr, flags)
1075
1733
  end
1076
1734
 
1077
- # Sends a COPY command to copy the specified message(s) to the end
1078
- # of the specified destination +mailbox+. The +set+ parameter is
1079
- # a number, an array of numbers, or a Range object. The number is
1080
- # a message sequence number.
1735
+ # Sends a {COPY command [IMAP4rev1 §6.4.7]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.7]
1736
+ # to copy the specified message(s) to the end of the specified destination
1737
+ # +mailbox+. The +set+ parameter is a number, an array of numbers, or a
1738
+ # Range object. The number is a message sequence number.
1081
1739
  #
1082
- # ==== Capabilities
1740
+ # Related: #uid_copy
1741
+ #
1742
+ # ===== Capabilities
1083
1743
  #
1084
1744
  # If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
1085
1745
  # supported, the server's response should include a +COPYUID+ response code
1086
- # with the UIDVALIDITY of the destination mailbox, the UID set of the source
1087
- # messages, and the assigned UID set of the moved messages.
1746
+ # with UIDPlusData. This will report the UIDVALIDITY of the destination
1747
+ # mailbox, the UID set of the source messages, and the assigned UID set of
1748
+ # the moved messages.
1088
1749
  def copy(set, mailbox)
1089
1750
  copy_internal("COPY", set, mailbox)
1090
1751
  end
1091
1752
 
1753
+ # Sends a {UID COPY command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
1754
+ # to copy the specified message(s) to the end of the specified destination
1755
+ # +mailbox+.
1756
+ #
1092
1757
  # Similar to #copy, but +set+ contains unique identifiers.
1093
1758
  #
1094
- # ==== Capabilities
1759
+ # ===== Capabilities
1095
1760
  #
1096
1761
  # +UIDPLUS+ affects #uid_copy the same way it affects #copy.
1097
1762
  def uid_copy(set, mailbox)
1098
1763
  copy_internal("UID COPY", set, mailbox)
1099
1764
  end
1100
1765
 
1101
- # Sends a MOVE command to move the specified message(s) to the end
1102
- # of the specified destination +mailbox+. The +set+ parameter is
1103
- # a number, an array of numbers, or a Range object. The number is
1104
- # a message sequence number.
1766
+ # Sends a {MOVE command [RFC6851 §3.1]}[https://www.rfc-editor.org/rfc/rfc6851#section-3.1]
1767
+ # {[IMAP4rev2 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.8]
1768
+ # to move the specified message(s) to the end of the specified destination
1769
+ # +mailbox+. The +set+ parameter is a number, an array of numbers, or a
1770
+ # Range object. The number is a message sequence number.
1771
+ #
1772
+ # Related: #uid_move
1105
1773
  #
1106
- # ==== Capabilities requirements
1774
+ # ===== Capabilities
1107
1775
  #
1108
- # +MOVE+ [RFC6851[https://tools.ietf.org/html/rfc6851]] must be supported by
1109
- # the server.
1776
+ # The server's capabilities must include +MOVE+
1777
+ # [RFC6851[https://tools.ietf.org/html/rfc6851]].
1110
1778
  #
1111
1779
  # If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
1112
- # also supported, the server's response should include a +COPYUID+ response
1113
- # code with the UIDVALIDITY of the destination mailbox, the UID set of the
1114
- # source messages, and the assigned UID set of the moved messages.
1780
+ # supported, the server's response should include a +COPYUID+ response code
1781
+ # with UIDPlusData. This will report the UIDVALIDITY of the destination
1782
+ # mailbox, the UID set of the source messages, and the assigned UID set of
1783
+ # the moved messages.
1115
1784
  #
1116
1785
  def move(set, mailbox)
1117
1786
  copy_internal("MOVE", set, mailbox)
1118
1787
  end
1119
1788
 
1789
+ # Sends a {UID MOVE command [RFC6851 §3.2]}[https://www.rfc-editor.org/rfc/rfc6851#section-3.2]
1790
+ # {[IMAP4rev2 §6.4.9]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.9]
1791
+ # to move the specified message(s) to the end of the specified destination
1792
+ # +mailbox+.
1793
+ #
1120
1794
  # Similar to #move, but +set+ contains unique identifiers.
1121
1795
  #
1122
- # ==== Capabilities requirements
1796
+ # Related: #move
1123
1797
  #
1124
- # Same as #move: +MOVE+ [RFC6851[https://tools.ietf.org/html/rfc6851]] must
1125
- # be supported by the server. +UIDPLUS+ also affects #uid_move the same way
1126
- # it affects #move.
1798
+ # ===== Capabilities
1799
+ #
1800
+ # Same as #move: The server's capabilities must include +MOVE+
1801
+ # [RFC6851[https://tools.ietf.org/html/rfc6851]]. +UIDPLUS+ also affects
1802
+ # #uid_move the same way it affects #move.
1127
1803
  def uid_move(set, mailbox)
1128
1804
  copy_internal("UID MOVE", set, mailbox)
1129
1805
  end
1130
1806
 
1131
- # Sends a SORT command to sort messages in the mailbox.
1132
- # Returns an array of message sequence numbers. For example:
1807
+ # Sends a {SORT command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
1808
+ # to search a mailbox for messages that match +search_keys+ and return an
1809
+ # array of message sequence numbers, sorted by +sort_keys+. +search_keys+
1810
+ # are interpreted the same as for #search.
1811
+ #
1812
+ #--
1813
+ # TODO: describe +sort_keys+
1814
+ #++
1815
+ #
1816
+ # Related: #uid_sort, #search, #uid_search, #thread, #uid_thread
1817
+ #
1818
+ # ===== For example:
1133
1819
  #
1134
1820
  # p imap.sort(["FROM"], ["ALL"], "US-ASCII")
1135
1821
  # #=> [1, 2, 3, 5, 6, 7, 8, 4, 9]
1136
1822
  # p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII")
1137
1823
  # #=> [6, 7, 8, 1]
1138
1824
  #
1139
- # The SORT extension is described in [SORT[https://tools.ietf.org/html/rfc5256]].
1825
+ # ===== Capabilities
1826
+ #
1827
+ # The server's capabilities must include +SORT+
1828
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1140
1829
  def sort(sort_keys, search_keys, charset)
1141
1830
  return sort_internal("SORT", sort_keys, search_keys, charset)
1142
1831
  end
1143
1832
 
1144
- # Similar to #sort, but returns an array of unique identifiers.
1833
+ # Sends a {UID SORT command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
1834
+ # to search a mailbox for messages that match +search_keys+ and return an
1835
+ # array of unique identifiers, sorted by +sort_keys+. +search_keys+ are
1836
+ # interpreted the same as for #search.
1145
1837
  #
1146
- # The SORT extension is described in [SORT[https://tools.ietf.org/html/rfc5256]].
1838
+ # Related: #sort, #search, #uid_search, #thread, #uid_thread
1839
+ #
1840
+ # ===== Capabilities
1841
+ #
1842
+ # The server's capabilities must include +SORT+
1843
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1147
1844
  def uid_sort(sort_keys, search_keys, charset)
1148
1845
  return sort_internal("UID SORT", sort_keys, search_keys, charset)
1149
1846
  end
1150
1847
 
1151
- # Adds a response handler. For example, to detect when
1152
- # the server sends a new EXISTS response (which normally
1153
- # indicates new messages being added to the mailbox),
1154
- # add the following handler after selecting the
1155
- # mailbox:
1848
+ # Sends a {THREAD command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
1849
+ # to search a mailbox and return message sequence numbers in threaded
1850
+ # format, as a ThreadMember tree. +search_keys+ are interpreted the same as
1851
+ # for #search.
1156
1852
  #
1157
- # imap.add_response_handler { |resp|
1158
- # if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
1159
- # puts "Mailbox now has #{resp.data} messages"
1160
- # end
1161
- # }
1162
- #
1163
- def add_response_handler(handler = nil, &block)
1164
- raise ArgumentError, "two Procs are passed" if handler && block
1165
- @response_handlers.push(block || handler)
1166
- end
1167
-
1168
- # Removes the response handler.
1169
- def remove_response_handler(handler)
1170
- @response_handlers.delete(handler)
1171
- end
1172
-
1173
- # Similar to #search, but returns message sequence numbers in threaded
1174
- # format, as a Net::IMAP::ThreadMember tree. The supported algorithms
1175
- # are:
1853
+ # The supported algorithms are:
1176
1854
  #
1177
1855
  # ORDEREDSUBJECT:: split into single-level threads according to subject,
1178
1856
  # ordered by date.
@@ -1182,21 +1860,34 @@ module Net
1182
1860
  # Unlike #search, +charset+ is a required argument. US-ASCII
1183
1861
  # and UTF-8 are sample values.
1184
1862
  #
1185
- # The THREAD extension is described in [THREAD[https://tools.ietf.org/html/rfc5256]].
1863
+ # Related: #uid_thread, #search, #uid_search, #sort, #uid_sort
1864
+ #
1865
+ # ===== Capabilities
1866
+ #
1867
+ # The server's capabilities must include +THREAD+
1868
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1186
1869
  def thread(algorithm, search_keys, charset)
1187
1870
  return thread_internal("THREAD", algorithm, search_keys, charset)
1188
1871
  end
1189
1872
 
1873
+ # Sends a {UID THREAD command [RFC5256 §3]}[https://www.rfc-editor.org/rfc/rfc5256#section-3]
1190
1874
  # Similar to #thread, but returns unique identifiers instead of
1191
1875
  # message sequence numbers.
1192
1876
  #
1193
- # The THREAD extension is described in [THREAD[https://tools.ietf.org/html/rfc5256]].
1877
+ # Related: #thread, #search, #uid_search, #sort, #uid_sort
1878
+ #
1879
+ # ===== Capabilities
1880
+ #
1881
+ # The server's capabilities must include +THREAD+
1882
+ # [RFC5256[https://tools.ietf.org/html/rfc5256]].
1194
1883
  def uid_thread(algorithm, search_keys, charset)
1195
1884
  return thread_internal("UID THREAD", algorithm, search_keys, charset)
1196
1885
  end
1197
1886
 
1198
- # Sends an IDLE command that waits for notifications of new or expunged
1199
- # messages. Yields responses from the server during the IDLE.
1887
+ # Sends an {IDLE command [RFC2177 §3]}[https://www.rfc-editor.org/rfc/rfc6851#section-3]
1888
+ # {[IMAP4rev2 §6.3.13]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.3.13]
1889
+ # that waits for notifications of new or expunged messages. Yields
1890
+ # responses from the server during the IDLE.
1200
1891
  #
1201
1892
  # Use #idle_done to leave IDLE.
1202
1893
  #
@@ -1209,6 +1900,13 @@ module Net
1209
1900
  # ...
1210
1901
  # end
1211
1902
  # end
1903
+ #
1904
+ # Related: #idle_done, #noop, #check
1905
+ #
1906
+ # ===== Capabilities
1907
+ #
1908
+ # The server's capabilities must include +IDLE+
1909
+ # [RFC2177[https://tools.ietf.org/html/rfc2177]].
1212
1910
  def idle(timeout = nil, &response_handler)
1213
1911
  raise LocalJumpError, "no block given" unless response_handler
1214
1912
 
@@ -1239,6 +1937,8 @@ module Net
1239
1937
  end
1240
1938
 
1241
1939
  # Leaves IDLE.
1940
+ #
1941
+ # Related: #idle
1242
1942
  def idle_done
1243
1943
  synchronize do
1244
1944
  if @idle_done_cond.nil?
@@ -1248,6 +1948,28 @@ module Net
1248
1948
  end
1249
1949
  end
1250
1950
 
1951
+ # Adds a response handler. For example, to detect when
1952
+ # the server sends a new EXISTS response (which normally
1953
+ # indicates new messages being added to the mailbox),
1954
+ # add the following handler after selecting the
1955
+ # mailbox:
1956
+ #
1957
+ # imap.add_response_handler { |resp|
1958
+ # if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
1959
+ # puts "Mailbox now has #{resp.data} messages"
1960
+ # end
1961
+ # }
1962
+ #
1963
+ def add_response_handler(handler = nil, &block)
1964
+ raise ArgumentError, "two Procs are passed" if handler && block
1965
+ @response_handlers.push(block || handler)
1966
+ end
1967
+
1968
+ # Removes the response handler.
1969
+ def remove_response_handler(handler)
1970
+ @response_handlers.delete(handler)
1971
+ end
1972
+
1251
1973
  private
1252
1974
 
1253
1975
  CRLF = "\r\n" # :nodoc: