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.
- checksums.yaml +4 -4
- data/lib/net/imap/authenticators.rb +30 -10
- data/lib/net/imap/flags.rb +1 -0
- data/lib/net/imap/sasl/stringprep.rb +6 -2
- data/lib/net/imap.rb +979 -257
- data/rakelib/rfcs.rake +3 -1
- metadata +2 -2
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
|
-
# [
|
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
|
45
|
-
# read-only access)
|
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
|
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.
|
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
|
-
#
|
712
|
+
# Returns the initial greeting the server, an UntaggedResponse.
|
344
713
|
attr_reader :greeting
|
345
714
|
|
346
|
-
# Returns recorded untagged responses.
|
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
|
423
|
-
# capabilities that the server supports. Each
|
424
|
-
# is a string.
|
425
|
-
#
|
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
|
440
|
-
# response, or nil if the server does not
|
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
|
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
|
469
|
-
#
|
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
|
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
|
-
#
|
490
|
-
#
|
491
|
-
#
|
492
|
-
#
|
493
|
-
#
|
494
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
522
|
-
#
|
523
|
-
|
524
|
-
|
525
|
-
|
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
|
536
|
-
# the plaintext +password+ authenticating
|
537
|
-
#
|
538
|
-
#
|
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
|
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
|
-
#
|
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
|
573
|
-
# in the +mailbox+ can be accessed.
|
574
|
-
# except that the selected +mailbox+ is
|
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
|
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
|
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
|
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
|
614
|
-
# the server's set of "active" or
|
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
|
624
|
-
# from the server's set of "active"
|
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
|
634
|
-
# the complete set of all names available
|
635
|
-
# +refname+ provides a context (for instance, a base
|
636
|
-
# in a directory-based mailbox hierarchy). +mailbox+ specifies
|
637
|
-
#
|
638
|
-
#
|
639
|
-
#
|
640
|
-
#
|
641
|
-
#
|
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
|
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
|
663
|
-
#
|
664
|
-
# namespaces used by a server
|
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
|
668
|
-
#
|
669
|
-
#
|
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.
|
675
|
-
# as the hierarchy delimiter. If the client does not check for
|
676
|
-
# naively assumes it can use the same folder names for all
|
677
|
-
# folder creation (and listing, moving, etc) can lead to
|
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.
|
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.
|
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
|
-
#
|
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
|
-
#
|
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
|
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
|
752
|
-
# This command is generally available
|
753
|
-
# If this mailbox exists, it returns an array
|
754
|
-
#
|
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
|
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
|
768
|
-
# If this mailbox exists, then an array
|
769
|
-
#
|
770
|
-
#
|
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
|
-
#
|
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
|
781
|
-
# +quota+. If +quota+ is nil, then
|
782
|
-
# mailbox. Typically one needs to be logged
|
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
|
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
|
796
|
-
# +rights+ that user is to have on that
|
797
|
-
# then that user will be stripped of any
|
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
|
-
#
|
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
|
-
#
|
809
|
-
# If this mailbox exists, an array
|
810
|
-
#
|
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
|
-
#
|
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
|
821
|
-
# of names
|
822
|
-
# "subscribed." +refname+ and +mailbox+ are
|
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
|
-
#
|
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
|
834
|
-
# +mailbox+. +attr+ is a list of one
|
835
|
-
# statuses are to be requested. Supported
|
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
|
857
|
-
# the +mailbox+. The optional +flags+
|
858
|
-
# flags initially passed to the new message. The
|
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
|
-
#
|
1476
|
+
# ===== Capabilities
|
876
1477
|
#
|
877
1478
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
878
|
-
# supported
|
879
|
-
#
|
880
|
-
# of the
|
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
|
896
|
-
# selected mailbox. This performs
|
897
|
-
# housekeeping; for instance, reconciling the
|
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
|
904
|
-
#
|
905
|
-
# messages that have the
|
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 [
|
911
|
-
# §6.4.2]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.2]
|
912
|
-
# session resources for a mailbox and return to the
|
913
|
-
# This is the same as #close, except that
|
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
|
-
#
|
934
|
-
#
|
935
|
-
# messages that have both the
|
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
|
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
|
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
|
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
|
-
#
|
1564
|
+
# Related: #expunge
|
1565
|
+
#
|
1566
|
+
# ===== Capabilities
|
951
1567
|
#
|
952
|
-
#
|
953
|
-
#
|
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
|
962
|
-
#
|
963
|
-
# numbers. +keys+ can either be a
|
964
|
-
# search string, or a single-dimension array of
|
965
|
-
#
|
966
|
-
#
|
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
|
-
#
|
969
|
-
#
|
970
|
-
#
|
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
|
-
#
|
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
|
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
|
1657
|
+
# for FetchData for a list of valid attributes.
|
1024
1658
|
#
|
1025
|
-
# The return value is an array of
|
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
|
-
#
|
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
|
-
#
|
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
|
1055
|
-
# in the mailbox, in particular their
|
1056
|
-
# is a number, an array of numbers, or a Range
|
1057
|
-
# is a message sequence number. +attr+ is the name of a
|
1058
|
-
# to store: 'FLAGS' will replace the message's flag list
|
1059
|
-
#
|
1060
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
1078
|
-
#
|
1079
|
-
# a number, an array of numbers, or a
|
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
|
-
#
|
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
|
1087
|
-
# messages, and the assigned UID set of
|
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
|
-
#
|
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
|
1102
|
-
#
|
1103
|
-
#
|
1104
|
-
# a
|
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
|
-
#
|
1774
|
+
# ===== Capabilities
|
1107
1775
|
#
|
1108
|
-
#
|
1109
|
-
#
|
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
|
-
#
|
1113
|
-
#
|
1114
|
-
# source messages, and the assigned UID set of
|
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
|
-
#
|
1796
|
+
# Related: #move
|
1123
1797
|
#
|
1124
|
-
#
|
1125
|
-
#
|
1126
|
-
#
|
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
|
1132
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
1152
|
-
#
|
1153
|
-
#
|
1154
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
1199
|
-
#
|
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:
|