net-imap 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

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: