net-imap 0.5.2 → 0.5.5
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/README.md +3 -1
- data/docs/styles.css +12 -7
- data/lib/net/imap/command_data.rb +32 -0
- data/lib/net/imap/config.rb +5 -3
- data/lib/net/imap/data_lite.rb +11 -10
- data/lib/net/imap/esearch_result.rb +44 -4
- data/lib/net/imap/fetch_data.rb +126 -47
- data/lib/net/imap/response_data.rb +119 -100
- data/lib/net/imap/response_parser.rb +78 -3
- data/lib/net/imap/sasl/anonymous_authenticator.rb +3 -3
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +3 -3
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +8 -8
- data/lib/net/imap/sasl/external_authenticator.rb +2 -2
- data/lib/net/imap/sasl/gs2_header.rb +7 -7
- data/lib/net/imap/sasl/login_authenticator.rb +2 -2
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +6 -6
- data/lib/net/imap/sasl/plain_authenticator.rb +7 -7
- data/lib/net/imap/sasl/scram_authenticator.rb +8 -8
- data/lib/net/imap/sasl.rb +1 -1
- data/lib/net/imap/search_result.rb +2 -2
- data/lib/net/imap/stringprep/nameprep.rb +1 -1
- data/lib/net/imap/stringprep/trace.rb +4 -4
- data/lib/net/imap/vanished_data.rb +56 -0
- data/lib/net/imap.rb +316 -160
- data/rakelib/rfcs.rake +2 -0
- metadata +4 -6
data/lib/net/imap.rb
CHANGED
@@ -25,8 +25,8 @@ module Net
|
|
25
25
|
|
26
26
|
# Net::IMAP implements Internet Message Access Protocol (\IMAP) client
|
27
27
|
# functionality. The protocol is described
|
28
|
-
# in {IMAP4rev1 [RFC3501]}[https://
|
29
|
-
# and {IMAP4rev2 [RFC9051]}[https://
|
28
|
+
# in {IMAP4rev1 [RFC3501]}[https://www.rfc-editor.org/rfc/rfc3501]
|
29
|
+
# and {IMAP4rev2 [RFC9051]}[https://www.rfc-editor.org/rfc/rfc9051].
|
30
30
|
#
|
31
31
|
# == \IMAP Overview
|
32
32
|
#
|
@@ -299,15 +299,15 @@ module Net
|
|
299
299
|
# === Core \IMAP commands
|
300
300
|
#
|
301
301
|
# The following commands are defined either by
|
302
|
-
# the [IMAP4rev1[https://
|
302
|
+
# the [IMAP4rev1[https://www.rfc-editor.org/rfc/rfc3501]] base specification, or
|
303
303
|
# by one of the following extensions:
|
304
|
-
# [IDLE[https://
|
305
|
-
# [NAMESPACE[https://
|
306
|
-
# [UNSELECT[https://
|
307
|
-
# [ENABLE[https://
|
308
|
-
# [MOVE[https://
|
304
|
+
# [IDLE[https://www.rfc-editor.org/rfc/rfc2177]],
|
305
|
+
# [NAMESPACE[https://www.rfc-editor.org/rfc/rfc2342]],
|
306
|
+
# [UNSELECT[https://www.rfc-editor.org/rfc/rfc3691]],
|
307
|
+
# [ENABLE[https://www.rfc-editor.org/rfc/rfc5161]],
|
308
|
+
# [MOVE[https://www.rfc-editor.org/rfc/rfc6851]].
|
309
309
|
# These extensions are widely supported by modern IMAP4rev1 servers and have
|
310
|
-
# all been integrated into [IMAP4rev2[https://
|
310
|
+
# all been integrated into [IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051]].
|
311
311
|
# <em>*NOTE:* Net::IMAP doesn't support IMAP4rev2 yet.</em>
|
312
312
|
#
|
313
313
|
# ==== Any state
|
@@ -404,7 +404,7 @@ module Net
|
|
404
404
|
#
|
405
405
|
# ==== RFC9051: +IMAP4rev2+
|
406
406
|
#
|
407
|
-
# Although IMAP4rev2[https://
|
407
|
+
# Although IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] is not supported
|
408
408
|
# yet, Net::IMAP supports several extensions that have been folded into it:
|
409
409
|
# +ENABLE+, +IDLE+, +MOVE+, +NAMESPACE+, +SASL-IR+, +UIDPLUS+, +UNSELECT+,
|
410
410
|
# <tt>STATUS=SIZE</tt>, and the fetch side of +BINARY+.
|
@@ -424,13 +424,13 @@ module Net
|
|
424
424
|
# - #setquota: sets the resource limits for a given quota root.
|
425
425
|
#
|
426
426
|
# ==== RFC2177: +IDLE+
|
427
|
-
# Folded into IMAP4rev2[https://
|
427
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
|
428
428
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
429
429
|
# - #idle: Allows the server to send updates to the client, without the client
|
430
430
|
# needing to poll using #noop.
|
431
431
|
#
|
432
432
|
# ==== RFC2342: +NAMESPACE+
|
433
|
-
# Folded into IMAP4rev2[https://
|
433
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
|
434
434
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
435
435
|
# - #namespace: Returns mailbox namespaces, with path prefixes and delimiters.
|
436
436
|
#
|
@@ -439,7 +439,7 @@ module Net
|
|
439
439
|
#
|
440
440
|
# ==== RFC3516: +BINARY+
|
441
441
|
# The fetch side of +BINARY+ has been folded into
|
442
|
-
# IMAP4rev2[https://
|
442
|
+
# IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051].
|
443
443
|
# - Updates #fetch and #uid_fetch with the +BINARY+, +BINARY.PEEK+, and
|
444
444
|
# +BINARY.SIZE+ items. See FetchData#binary and FetchData#binary_size.
|
445
445
|
#
|
@@ -447,7 +447,7 @@ module Net
|
|
447
447
|
# *NOTE:* The binary extension the #append command is _not_ supported yet.
|
448
448
|
#
|
449
449
|
# ==== RFC3691: +UNSELECT+
|
450
|
-
# Folded into IMAP4rev2[https://
|
450
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
|
451
451
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
452
452
|
# - #unselect: Closes the mailbox and returns to the "_authenticated_" state,
|
453
453
|
# without expunging any messages.
|
@@ -459,7 +459,7 @@ module Net
|
|
459
459
|
# *NOTE:* +DELETEACL+, +LISTRIGHTS+, and +MYRIGHTS+ are not supported yet.
|
460
460
|
#
|
461
461
|
# ==== RFC4315: +UIDPLUS+
|
462
|
-
# Folded into IMAP4rev2[https://
|
462
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
|
463
463
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
464
464
|
# - #uid_expunge: Restricts #expunge to only remove the specified UIDs.
|
465
465
|
# - Updates #select, #examine with the +UIDNOTSTICKY+ ResponseCode
|
@@ -467,15 +467,15 @@ module Net
|
|
467
467
|
# - Updates #copy, #move with the +COPYUID+ ResponseCode
|
468
468
|
#
|
469
469
|
# ==== RFC4731: +ESEARCH+
|
470
|
-
# Folded into IMAP4rev2[https://
|
470
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051].
|
471
471
|
# - Updates #search, #uid_search with +return+ options and ESearchResult.
|
472
472
|
#
|
473
473
|
# ==== RFC4959: +SASL-IR+
|
474
|
-
# Folded into IMAP4rev2[https://
|
474
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051].
|
475
475
|
# - Updates #authenticate with the option to send an initial response.
|
476
476
|
#
|
477
477
|
# ==== RFC5161: +ENABLE+
|
478
|
-
# Folded into IMAP4rev2[https://
|
478
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
|
479
479
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
480
480
|
# - #enable: Enables backwards incompatible server extensions.
|
481
481
|
#
|
@@ -499,7 +499,7 @@ module Net
|
|
499
499
|
# +X-GM-THRID+, but Gmail does not support it (as of 2023-11-10).
|
500
500
|
#
|
501
501
|
# ==== RFC6851: +MOVE+
|
502
|
-
# Folded into IMAP4rev2[https://
|
502
|
+
# Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
|
503
503
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
504
504
|
# - #move, #uid_move: Moves the specified messages to the end of the
|
505
505
|
# specified destination mailbox, expunging them from the current mailbox.
|
@@ -534,6 +534,17 @@ module Net
|
|
534
534
|
# See FetchData#emailid and FetchData#emailid.
|
535
535
|
# - Updates #status with support for the +MAILBOXID+ status attribute.
|
536
536
|
#
|
537
|
+
# ==== RFC9394: +PARTIAL+
|
538
|
+
# - Updates #search, #uid_search with the +PARTIAL+ return option which adds
|
539
|
+
# ESearchResult#partial return data.
|
540
|
+
# - Updates #uid_fetch with the +partial+ modifier.
|
541
|
+
#
|
542
|
+
# ==== RFC9586: +UIDONLY+
|
543
|
+
# - Updates #enable with +UIDONLY+ parameter.
|
544
|
+
# - Updates #uid_fetch and #uid_store to return +UIDFETCH+ response.
|
545
|
+
# - Updates #expunge and #uid_expunge to return +VANISHED+ response.
|
546
|
+
# - Prohibits use of message sequence numbers in responses or requests.
|
547
|
+
#
|
537
548
|
# == References
|
538
549
|
#
|
539
550
|
# [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501.html]]::
|
@@ -564,57 +575,57 @@ module Net
|
|
564
575
|
# Gahrns, M., "IMAP4 Multi-Accessed Mailbox Practice", RFC 2180, DOI
|
565
576
|
# 10.17487/RFC2180, July 1997, <https://www.rfc-editor.org/info/rfc2180>.
|
566
577
|
#
|
567
|
-
# [UTF7[https://
|
578
|
+
# [UTF7[https://www.rfc-editor.org/rfc/rfc2152]]::
|
568
579
|
# Goldsmith, D. and M. Davis, "UTF-7 A Mail-Safe Transformation Format of
|
569
580
|
# Unicode", RFC 2152, DOI 10.17487/RFC2152, May 1997,
|
570
581
|
# <https://www.rfc-editor.org/info/rfc2152>.
|
571
582
|
#
|
572
583
|
# === Message envelope and body structure
|
573
584
|
#
|
574
|
-
# [RFC5322[https://
|
585
|
+
# [RFC5322[https://www.rfc-editor.org/rfc/rfc5322]]::
|
575
586
|
# Resnick, P., Ed., "Internet Message Format",
|
576
587
|
# RFC 5322, DOI 10.17487/RFC5322, October 2008,
|
577
588
|
# <https://www.rfc-editor.org/info/rfc5322>.
|
578
589
|
#
|
579
590
|
# <em>Note: obsoletes</em>
|
580
|
-
# RFC-2822[https://
|
581
|
-
# RFC-822[https://
|
591
|
+
# RFC-2822[https://www.rfc-editor.org/rfc/rfc2822]<em> (April 2001) and</em>
|
592
|
+
# RFC-822[https://www.rfc-editor.org/rfc/rfc822]<em> (August 1982).</em>
|
582
593
|
#
|
583
|
-
# [CHARSET[https://
|
594
|
+
# [CHARSET[https://www.rfc-editor.org/rfc/rfc2978]]::
|
584
595
|
# Freed, N. and J. Postel, "IANA Charset Registration Procedures", BCP 19,
|
585
596
|
# RFC 2978, DOI 10.17487/RFC2978, October 2000,
|
586
597
|
# <https://www.rfc-editor.org/info/rfc2978>.
|
587
598
|
#
|
588
|
-
# [DISPOSITION[https://
|
599
|
+
# [DISPOSITION[https://www.rfc-editor.org/rfc/rfc2183]]::
|
589
600
|
# Troost, R., Dorner, S., and K. Moore, Ed., "Communicating Presentation
|
590
601
|
# Information in Internet Messages: The Content-Disposition Header
|
591
602
|
# Field", RFC 2183, DOI 10.17487/RFC2183, August 1997,
|
592
603
|
# <https://www.rfc-editor.org/info/rfc2183>.
|
593
604
|
#
|
594
|
-
# [MIME-IMB[https://
|
605
|
+
# [MIME-IMB[https://www.rfc-editor.org/rfc/rfc2045]]::
|
595
606
|
# Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions
|
596
607
|
# (MIME) Part One: Format of Internet Message Bodies",
|
597
608
|
# RFC 2045, DOI 10.17487/RFC2045, November 1996,
|
598
609
|
# <https://www.rfc-editor.org/info/rfc2045>.
|
599
610
|
#
|
600
|
-
# [MIME-IMT[https://
|
611
|
+
# [MIME-IMT[https://www.rfc-editor.org/rfc/rfc2046]]::
|
601
612
|
# Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions
|
602
613
|
# (MIME) Part Two: Media Types", RFC 2046, DOI 10.17487/RFC2046,
|
603
614
|
# November 1996, <https://www.rfc-editor.org/info/rfc2046>.
|
604
615
|
#
|
605
|
-
# [MIME-HDRS[https://
|
616
|
+
# [MIME-HDRS[https://www.rfc-editor.org/rfc/rfc2047]]::
|
606
617
|
# Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three:
|
607
618
|
# Message Header Extensions for Non-ASCII Text",
|
608
619
|
# RFC 2047, DOI 10.17487/RFC2047, November 1996,
|
609
620
|
# <https://www.rfc-editor.org/info/rfc2047>.
|
610
621
|
#
|
611
|
-
# [RFC2231[https://
|
622
|
+
# [RFC2231[https://www.rfc-editor.org/rfc/rfc2231]]::
|
612
623
|
# Freed, N. and K. Moore, "MIME Parameter Value and Encoded Word
|
613
624
|
# Extensions: Character Sets, Languages, and Continuations",
|
614
625
|
# RFC 2231, DOI 10.17487/RFC2231, November 1997,
|
615
626
|
# <https://www.rfc-editor.org/info/rfc2231>.
|
616
627
|
#
|
617
|
-
# [I18n-HDRS[https://
|
628
|
+
# [I18n-HDRS[https://www.rfc-editor.org/rfc/rfc6532]]::
|
618
629
|
# Yang, A., Steele, S., and N. Freed, "Internationalized Email Headers",
|
619
630
|
# RFC 6532, DOI 10.17487/RFC6532, February 2012,
|
620
631
|
# <https://www.rfc-editor.org/info/rfc6532>.
|
@@ -630,12 +641,12 @@ module Net
|
|
630
641
|
# RFC 2557, DOI 10.17487/RFC2557, March 1999,
|
631
642
|
# <https://www.rfc-editor.org/info/rfc2557>.
|
632
643
|
#
|
633
|
-
# [MD5[https://
|
644
|
+
# [MD5[https://www.rfc-editor.org/rfc/rfc1864]]::
|
634
645
|
# Myers, J. and M. Rose, "The Content-MD5 Header Field",
|
635
646
|
# RFC 1864, DOI 10.17487/RFC1864, October 1995,
|
636
647
|
# <https://www.rfc-editor.org/info/rfc1864>.
|
637
648
|
#
|
638
|
-
# [RFC3503[https://
|
649
|
+
# [RFC3503[https://www.rfc-editor.org/rfc/rfc3503]]::
|
639
650
|
# Melnikov, A., "Message Disposition Notification (MDN)
|
640
651
|
# profile for Internet Message Access Protocol (IMAP)",
|
641
652
|
# RFC 3503, DOI 10.17487/RFC3503, March 2003,
|
@@ -643,27 +654,27 @@ module Net
|
|
643
654
|
#
|
644
655
|
# === \IMAP Extensions
|
645
656
|
#
|
646
|
-
# [QUOTA[https://
|
657
|
+
# [QUOTA[https://www.rfc-editor.org/rfc/rfc9208]]::
|
647
658
|
# Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
|
648
659
|
# March 2022, <https://www.rfc-editor.org/info/rfc9208>.
|
649
660
|
#
|
650
661
|
# <em>Note: obsoletes</em>
|
651
|
-
# RFC-2087[https://
|
662
|
+
# RFC-2087[https://www.rfc-editor.org/rfc/rfc2087]<em> (January 1997)</em>.
|
652
663
|
# <em>Net::IMAP does not fully support the RFC9208 updates yet.</em>
|
653
|
-
# [IDLE[https://
|
664
|
+
# [IDLE[https://www.rfc-editor.org/rfc/rfc2177]]::
|
654
665
|
# Leiba, B., "IMAP4 IDLE command", RFC 2177, DOI 10.17487/RFC2177,
|
655
666
|
# June 1997, <https://www.rfc-editor.org/info/rfc2177>.
|
656
|
-
# [NAMESPACE[https://
|
667
|
+
# [NAMESPACE[https://www.rfc-editor.org/rfc/rfc2342]]::
|
657
668
|
# Gahrns, M. and C. Newman, "IMAP4 Namespace", RFC 2342,
|
658
669
|
# DOI 10.17487/RFC2342, May 1998, <https://www.rfc-editor.org/info/rfc2342>.
|
659
|
-
# [ID[https://
|
670
|
+
# [ID[https://www.rfc-editor.org/rfc/rfc2971]]::
|
660
671
|
# Showalter, T., "IMAP4 ID extension", RFC 2971, DOI 10.17487/RFC2971,
|
661
672
|
# October 2000, <https://www.rfc-editor.org/info/rfc2971>.
|
662
|
-
# [BINARY[https://
|
673
|
+
# [BINARY[https://www.rfc-editor.org/rfc/rfc3516]]::
|
663
674
|
# Nerenberg, L., "IMAP4 Binary Content Extension", RFC 3516,
|
664
675
|
# DOI 10.17487/RFC3516, April 2003,
|
665
676
|
# <https://www.rfc-editor.org/info/rfc3516>.
|
666
|
-
# [ACL[https://
|
677
|
+
# [ACL[https://www.rfc-editor.org/rfc/rfc4314]]::
|
667
678
|
# Melnikov, A., "IMAP4 Access Control List (ACL) Extension", RFC 4314,
|
668
679
|
# DOI 10.17487/RFC4314, December 2005,
|
669
680
|
# <https://www.rfc-editor.org/info/rfc4314>.
|
@@ -671,36 +682,46 @@ module Net
|
|
671
682
|
# Crispin, M., "Internet Message Access Protocol (\IMAP) - UIDPLUS
|
672
683
|
# extension", RFC 4315, DOI 10.17487/RFC4315, December 2005,
|
673
684
|
# <https://www.rfc-editor.org/info/rfc4315>.
|
674
|
-
# [SORT[https://
|
685
|
+
# [SORT[https://www.rfc-editor.org/rfc/rfc5256]]::
|
675
686
|
# Crispin, M. and K. Murchison, "Internet Message Access Protocol - SORT and
|
676
687
|
# THREAD Extensions", RFC 5256, DOI 10.17487/RFC5256, June 2008,
|
677
688
|
# <https://www.rfc-editor.org/info/rfc5256>.
|
678
|
-
# [THREAD[https://
|
689
|
+
# [THREAD[https://www.rfc-editor.org/rfc/rfc5256]]::
|
679
690
|
# Crispin, M. and K. Murchison, "Internet Message Access Protocol - SORT and
|
680
691
|
# THREAD Extensions", RFC 5256, DOI 10.17487/RFC5256, June 2008,
|
681
692
|
# <https://www.rfc-editor.org/info/rfc5256>.
|
682
693
|
# [RFC5530[https://www.rfc-editor.org/rfc/rfc5530.html]]::
|
683
694
|
# Gulbrandsen, A., "IMAP Response Codes", RFC 5530, DOI 10.17487/RFC5530,
|
684
695
|
# May 2009, <https://www.rfc-editor.org/info/rfc5530>.
|
685
|
-
# [MOVE[https://
|
696
|
+
# [MOVE[https://www.rfc-editor.org/rfc/rfc6851]]::
|
686
697
|
# Gulbrandsen, A. and N. Freed, Ed., "Internet Message Access Protocol
|
687
698
|
# (\IMAP) - MOVE Extension", RFC 6851, DOI 10.17487/RFC6851, January 2013,
|
688
699
|
# <https://www.rfc-editor.org/info/rfc6851>.
|
689
|
-
# [UTF8=ACCEPT[https://
|
690
|
-
# [UTF8=ONLY[https://
|
700
|
+
# [UTF8=ACCEPT[https://www.rfc-editor.org/rfc/rfc6855]]::
|
701
|
+
# [UTF8=ONLY[https://www.rfc-editor.org/rfc/rfc6855]]::
|
691
702
|
# Resnick, P., Ed., Newman, C., Ed., and S. Shen, Ed.,
|
692
703
|
# "IMAP Support for UTF-8", RFC 6855, DOI 10.17487/RFC6855, March 2013,
|
693
704
|
# <https://www.rfc-editor.org/info/rfc6855>.
|
694
|
-
# [CONDSTORE[https://
|
695
|
-
# [QRESYNC[https://
|
705
|
+
# [CONDSTORE[https://www.rfc-editor.org/rfc/rfc7162]]::
|
706
|
+
# [QRESYNC[https://www.rfc-editor.org/rfc/rfc7162]]::
|
696
707
|
# Melnikov, A. and D. Cridland, "IMAP Extensions: Quick Flag Changes
|
697
708
|
# Resynchronization (CONDSTORE) and Quick Mailbox Resynchronization
|
698
709
|
# (QRESYNC)", RFC 7162, DOI 10.17487/RFC7162, May 2014,
|
699
710
|
# <https://www.rfc-editor.org/info/rfc7162>.
|
700
|
-
# [OBJECTID[https://
|
711
|
+
# [OBJECTID[https://www.rfc-editor.org/rfc/rfc8474]]::
|
701
712
|
# Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
|
702
713
|
# RFC 8474, DOI 10.17487/RFC8474, September 2018,
|
703
714
|
# <https://www.rfc-editor.org/info/rfc8474>.
|
715
|
+
# [PARTIAL[https://www.rfc-editor.org/info/rfc9394]]::
|
716
|
+
# Melnikov, A., Achuthan, A., Nagulakonda, V., and L. Alves,
|
717
|
+
# "IMAP PARTIAL Extension for Paged SEARCH and FETCH", RFC 9394,
|
718
|
+
# DOI 10.17487/RFC9394, June 2023,
|
719
|
+
# <https://www.rfc-editor.org/info/rfc9394>.
|
720
|
+
# [UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.pdf]]::
|
721
|
+
# Melnikov, A., Achuthan, A., Nagulakonda, V., Singh, A., and L. Alves,
|
722
|
+
# "\IMAP Extension for Using and Returning Unique Identifiers (UIDs) Only",
|
723
|
+
# RFC 9586, DOI 10.17487/RFC9586, May 2024,
|
724
|
+
# <https://www.rfc-editor.org/info/rfc9586>.
|
704
725
|
#
|
705
726
|
# === IANA registries
|
706
727
|
# * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
|
@@ -714,7 +735,7 @@ module Net
|
|
714
735
|
# * {GSSAPI/Kerberos/SASL Service Names}[https://www.iana.org/assignments/gssapi-service-names/gssapi-service-names.xhtml]:
|
715
736
|
# +imap+
|
716
737
|
# * {Character sets}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
|
717
|
-
#
|
738
|
+
# ==== For currently unsupported features:
|
718
739
|
# * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
|
719
740
|
# * {LIST-EXTENDED options and responses}[https://www.iana.org/assignments/imap-list-extended/imap-list-extended.xhtml]
|
720
741
|
# * {IMAP METADATA Server Entry and Mailbox Entry Registries}[https://www.iana.org/assignments/imap-metadata/imap-metadata.xhtml]
|
@@ -723,7 +744,7 @@ module Net
|
|
723
744
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
724
745
|
#
|
725
746
|
class IMAP < Protocol
|
726
|
-
VERSION = "0.5.
|
747
|
+
VERSION = "0.5.5"
|
727
748
|
|
728
749
|
# Aliases for supported capabilities, to be used with the #enable command.
|
729
750
|
ENABLE_ALIASES = {
|
@@ -1125,12 +1146,12 @@ module Net
|
|
1125
1146
|
# )
|
1126
1147
|
# end
|
1127
1148
|
#
|
1128
|
-
# See [ID[https://
|
1149
|
+
# See [ID[https://www.rfc-editor.org/rfc/rfc2971]] for field definitions.
|
1129
1150
|
#
|
1130
1151
|
# ==== Capabilities
|
1131
1152
|
#
|
1132
1153
|
# The server's capabilities must include +ID+
|
1133
|
-
# [RFC2971[https://
|
1154
|
+
# [RFC2971[https://www.rfc-editor.org/rfc/rfc2971]].
|
1134
1155
|
def id(client_id=nil)
|
1135
1156
|
synchronize do
|
1136
1157
|
send_command("ID", ClientID.new(client_id))
|
@@ -1553,7 +1574,7 @@ module Net
|
|
1553
1574
|
# servers, then folder creation (and listing, moving, etc) can lead to
|
1554
1575
|
# errors.
|
1555
1576
|
#
|
1556
|
-
# From RFC2342[https://
|
1577
|
+
# From RFC2342[https://www.rfc-editor.org/rfc/rfc2342]:
|
1557
1578
|
# >>>
|
1558
1579
|
# <em>Although typically a server will support only a single Personal
|
1559
1580
|
# Namespace, and a single Other User's Namespace, circumstances exist
|
@@ -1582,8 +1603,8 @@ module Net
|
|
1582
1603
|
#
|
1583
1604
|
# ==== Capabilities
|
1584
1605
|
#
|
1585
|
-
# The server's capabilities must include +NAMESPACE+
|
1586
|
-
# [RFC2342[https://
|
1606
|
+
# The server's capabilities must include either +IMAP4rev2+ or +NAMESPACE+
|
1607
|
+
# [RFC2342[https://www.rfc-editor.org/rfc/rfc2342]].
|
1587
1608
|
def namespace
|
1588
1609
|
synchronize do
|
1589
1610
|
send_command("NAMESPACE")
|
@@ -1645,7 +1666,7 @@ module Net
|
|
1645
1666
|
# ==== Capabilities
|
1646
1667
|
#
|
1647
1668
|
# The server's capabilities must include +QUOTA+
|
1648
|
-
# [RFC2087[https://
|
1669
|
+
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
|
1649
1670
|
def getquotaroot(mailbox)
|
1650
1671
|
synchronize do
|
1651
1672
|
send_command("GETQUOTAROOT", mailbox)
|
@@ -1666,7 +1687,7 @@ module Net
|
|
1666
1687
|
# ==== Capabilities
|
1667
1688
|
#
|
1668
1689
|
# The server's capabilities must include +QUOTA+
|
1669
|
-
# [RFC2087[https://
|
1690
|
+
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
|
1670
1691
|
def getquota(mailbox)
|
1671
1692
|
synchronize do
|
1672
1693
|
send_command("GETQUOTA", mailbox)
|
@@ -1684,7 +1705,7 @@ module Net
|
|
1684
1705
|
# ==== Capabilities
|
1685
1706
|
#
|
1686
1707
|
# The server's capabilities must include +QUOTA+
|
1687
|
-
# [RFC2087[https://
|
1708
|
+
# [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
|
1688
1709
|
def setquota(mailbox, quota)
|
1689
1710
|
if quota.nil?
|
1690
1711
|
data = '()'
|
@@ -1704,7 +1725,7 @@ module Net
|
|
1704
1725
|
# ==== Capabilities
|
1705
1726
|
#
|
1706
1727
|
# The server's capabilities must include +ACL+
|
1707
|
-
# [RFC4314[https://
|
1728
|
+
# [RFC4314[https://www.rfc-editor.org/rfc/rfc4314]].
|
1708
1729
|
def setacl(mailbox, user, rights)
|
1709
1730
|
if rights.nil?
|
1710
1731
|
send_command("SETACL", mailbox, user, "")
|
@@ -1722,7 +1743,7 @@ module Net
|
|
1722
1743
|
# ==== Capabilities
|
1723
1744
|
#
|
1724
1745
|
# The server's capabilities must include +ACL+
|
1725
|
-
# [RFC4314[https://
|
1746
|
+
# [RFC4314[https://www.rfc-editor.org/rfc/rfc4314]].
|
1726
1747
|
def getacl(mailbox)
|
1727
1748
|
synchronize do
|
1728
1749
|
send_command("GETACL", mailbox)
|
@@ -1883,54 +1904,70 @@ module Net
|
|
1883
1904
|
#
|
1884
1905
|
# ==== Capabilities
|
1885
1906
|
#
|
1886
|
-
# The server's capabilities must include +UNSELECT+
|
1887
|
-
# [RFC3691[https://
|
1907
|
+
# The server's capabilities must include either +IMAP4rev2+ or +UNSELECT+
|
1908
|
+
# [RFC3691[https://www.rfc-editor.org/rfc/rfc3691]].
|
1888
1909
|
def unselect
|
1889
1910
|
send_command("UNSELECT")
|
1890
1911
|
end
|
1891
1912
|
|
1913
|
+
# call-seq:
|
1914
|
+
# expunge -> array of message sequence numbers
|
1915
|
+
# expunge -> VanishedData of UIDs
|
1916
|
+
#
|
1892
1917
|
# Sends an {EXPUNGE command [IMAP4rev1 §6.4.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.3]
|
1893
|
-
#
|
1894
|
-
# selected mailbox
|
1918
|
+
# to permanently remove all messages with the +\Deleted+ flag from the
|
1919
|
+
# currently selected mailbox.
|
1920
|
+
#
|
1921
|
+
# Returns either an array of expunged message <em>sequence numbers</em> or
|
1922
|
+
# (when the appropriate capability is enabled) VanishedData of expunged
|
1923
|
+
# UIDs. Previously unhandled +EXPUNGE+ or +VANISHED+ responses are merged
|
1924
|
+
# with the direct response to this command. <tt>VANISHED (EARLIER)</tt>
|
1925
|
+
# responses will _not_ be merged.
|
1926
|
+
#
|
1927
|
+
# When no messages have been expunged, an empty array is returned,
|
1928
|
+
# regardless of which extensions are enabled. In a future release, an empty
|
1929
|
+
# VanishedData may be returned, based on the currently enabled extensions.
|
1895
1930
|
#
|
1896
1931
|
# Related: #uid_expunge
|
1932
|
+
#
|
1933
|
+
# ==== Capabilities
|
1934
|
+
#
|
1935
|
+
# When either QRESYNC[https://www.rfc-editor.org/rfc/rfc7162] or
|
1936
|
+
# UIDONLY[https://www.rfc-editor.org/rfc/rfc9586] are enabled, #expunge
|
1937
|
+
# returns VanishedData, which contains UIDs---<em>not message sequence
|
1938
|
+
# numbers</em>.
|
1897
1939
|
def expunge
|
1898
|
-
|
1899
|
-
send_command("EXPUNGE")
|
1900
|
-
clear_responses("EXPUNGE")
|
1901
|
-
end
|
1940
|
+
expunge_internal("EXPUNGE")
|
1902
1941
|
end
|
1903
1942
|
|
1943
|
+
# call-seq:
|
1944
|
+
# uid_expunge{uid_set) -> array of message sequence numbers
|
1945
|
+
# uid_expunge{uid_set) -> VanishedData of UIDs
|
1946
|
+
#
|
1904
1947
|
# Sends a {UID EXPUNGE command [RFC4315 §2.1]}[https://www.rfc-editor.org/rfc/rfc4315#section-2.1]
|
1905
1948
|
# {[IMAP4rev2 §6.4.9]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.9]
|
1906
1949
|
# to permanently remove all messages that have both the <tt>\\Deleted</tt>
|
1907
1950
|
# flag set and a UID that is included in +uid_set+.
|
1908
1951
|
#
|
1952
|
+
# Returns the same result type as #expunge.
|
1953
|
+
#
|
1909
1954
|
# By using #uid_expunge instead of #expunge when resynchronizing with
|
1910
1955
|
# the server, the client can ensure that it does not inadvertantly
|
1911
1956
|
# remove any messages that have been marked as <tt>\\Deleted</tt> by other
|
1912
1957
|
# clients between the time that the client was last connected and
|
1913
1958
|
# the time the client resynchronizes.
|
1914
1959
|
#
|
1915
|
-
# *Note:*
|
1916
|
-
# >>>
|
1917
|
-
# Although the command takes a set of UIDs for its argument, the
|
1918
|
-
# server still returns regular EXPUNGE responses, which contain
|
1919
|
-
# a <em>sequence number</em>. These will be deleted from
|
1920
|
-
# #responses and this method returns them as an array of
|
1921
|
-
# <em>sequence number</em> integers.
|
1922
|
-
#
|
1923
1960
|
# Related: #expunge
|
1924
1961
|
#
|
1925
1962
|
# ==== Capabilities
|
1926
1963
|
#
|
1927
|
-
# The server's capabilities must include +UIDPLUS+
|
1964
|
+
# The server's capabilities must include either +IMAP4rev2+ or +UIDPLUS+
|
1928
1965
|
# [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]].
|
1966
|
+
#
|
1967
|
+
# Otherwise, #uid_expunge is updated by extensions in the same way as
|
1968
|
+
# #expunge.
|
1929
1969
|
def uid_expunge(uid_set)
|
1930
|
-
|
1931
|
-
send_command("UID EXPUNGE", SequenceSet.new(uid_set))
|
1932
|
-
clear_responses("EXPUNGE")
|
1933
|
-
end
|
1970
|
+
expunge_internal("UID EXPUNGE", SequenceSet.new(uid_set))
|
1934
1971
|
end
|
1935
1972
|
|
1936
1973
|
# :call-seq:
|
@@ -1942,7 +1979,7 @@ module Net
|
|
1942
1979
|
# and returns either a SearchResult or an ESearchResult. SearchResult
|
1943
1980
|
# inherits from Array (for backward compatibility) but adds
|
1944
1981
|
# SearchResult#modseq when the +CONDSTORE+ capability has been enabled.
|
1945
|
-
# ESearchResult also implements to_a
|
1982
|
+
# ESearchResult also implements {#to_a}[rdoc-ref:ESearchResult#to_a], for
|
1946
1983
|
# compatibility with SearchResult.
|
1947
1984
|
#
|
1948
1985
|
# +criteria+ is one or more search keys and their arguments, which may be
|
@@ -1955,8 +1992,9 @@ module Net
|
|
1955
1992
|
# the server to return an ESearchResult instead of a SearchResult, but some
|
1956
1993
|
# servers disobey this requirement. <em>Requires an extended search
|
1957
1994
|
# capability, such as +ESEARCH+ or +IMAP4rev2+.</em>
|
1958
|
-
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation]
|
1959
|
-
#
|
1995
|
+
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation] and
|
1996
|
+
# {"Supported return options"}[rdoc-ref:#search@Supported+return+options],
|
1997
|
+
# below.
|
1960
1998
|
#
|
1961
1999
|
# +charset+ is the name of the {registered character
|
1962
2000
|
# set}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
|
@@ -2066,33 +2104,58 @@ module Net
|
|
2066
2104
|
# <em>*WARNING:* This is vulnerable to injection attacks when external
|
2067
2105
|
# inputs are used.</em>
|
2068
2106
|
#
|
2069
|
-
# ====
|
2107
|
+
# ==== Supported return options
|
2070
2108
|
#
|
2071
2109
|
# For full definitions of the standard return options and return data, see
|
2072
2110
|
# the relevant RFCs.
|
2073
2111
|
#
|
2074
|
-
# ===== +ESEARCH+ or +IMAP4rev2+
|
2075
|
-
#
|
2076
|
-
# The following return options require either +ESEARCH+ or +IMAP4rev2+.
|
2077
|
-
# See [{RFC4731 §3.1}[https://rfc-editor.org/rfc/rfc4731#section-3.1]] or
|
2078
|
-
# [{IMAP4rev2 §6.4.4}[https://www.rfc-editor.org/rfc/rfc9051.html#section-6.4.4]].
|
2079
|
-
#
|
2080
2112
|
# [+ALL+]
|
2081
2113
|
# Returns ESearchResult#all with a SequenceSet of all matching sequence
|
2082
2114
|
# numbers or UIDs. This is the default, when return options are empty.
|
2083
2115
|
#
|
2084
2116
|
# For compatibility with SearchResult, ESearchResult#to_a returns an
|
2085
2117
|
# Array of message sequence numbers or UIDs.
|
2118
|
+
#
|
2119
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2120
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2121
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2122
|
+
#
|
2086
2123
|
# [+COUNT+]
|
2087
2124
|
# Returns ESearchResult#count with the number of matching messages.
|
2125
|
+
#
|
2126
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2127
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2128
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2129
|
+
#
|
2088
2130
|
# [+MAX+]
|
2089
2131
|
# Returns ESearchResult#max with the highest matching sequence number or
|
2090
2132
|
# UID.
|
2133
|
+
#
|
2134
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2135
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2136
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2137
|
+
#
|
2091
2138
|
# [+MIN+]
|
2092
2139
|
# Returns ESearchResult#min with the lowest matching sequence number or
|
2093
2140
|
# UID.
|
2094
2141
|
#
|
2095
|
-
#
|
2142
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2143
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2144
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2145
|
+
#
|
2146
|
+
# [+PARTIAL+ _range_]
|
2147
|
+
# Returns ESearchResult#partial with a SequenceSet of a subset of
|
2148
|
+
# matching sequence numbers or UIDs, as selected by _range_. As with
|
2149
|
+
# sequence numbers, the first result is +1+: <tt>1..500</tt> selects the
|
2150
|
+
# first 500 search results (in mailbox order), <tt>501..1000</tt> the
|
2151
|
+
# second 500, and so on. _range_ may also be negative: <tt>-500..-1</tt>
|
2152
|
+
# selects the last 500 search results.
|
2153
|
+
#
|
2154
|
+
# <em>Requires either the <tt>CONTEXT=SEARCH</tt> or +PARTIAL+ capabability.</em>
|
2155
|
+
# {[RFC5267]}[https://rfc-editor.org/rfc/rfc5267]
|
2156
|
+
# {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
|
2157
|
+
#
|
2158
|
+
# ===== +MODSEQ+ return data
|
2096
2159
|
#
|
2097
2160
|
# ESearchResult#modseq return data does not have a corresponding return
|
2098
2161
|
# option. Instead, it is returned if the +MODSEQ+ search key is used or
|
@@ -2104,8 +2167,8 @@ module Net
|
|
2104
2167
|
#
|
2105
2168
|
# {RFC4466 §2.6}[https://www.rfc-editor.org/rfc/rfc4466.html#section-2.6]
|
2106
2169
|
# defines standard syntax for search extensions. Net::IMAP allows sending
|
2107
|
-
#
|
2108
|
-
# return values into ExtensionData. Please note that this is an
|
2170
|
+
# unsupported search return options and will parse unsupported search
|
2171
|
+
# extensions' return values into ExtensionData. Please note that this is an
|
2109
2172
|
# intentionally _unstable_ API. Future releases may return different
|
2110
2173
|
# (incompatible) objects, <em>without deprecation or warning</em>.
|
2111
2174
|
#
|
@@ -2314,6 +2377,9 @@ module Net
|
|
2314
2377
|
# result = imap.search(["SUBJECT", "hi there", "not", "new"])
|
2315
2378
|
# #=> Net::IMAP::SearchResult[1, 6, 7, 8, modseq: 5594]
|
2316
2379
|
# result.modseq # => 5594
|
2380
|
+
#
|
2381
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
|
2382
|
+
# the +SEARCH+ command is prohibited. Use #uid_search instead.
|
2317
2383
|
def search(...)
|
2318
2384
|
search_internal("SEARCH", ...)
|
2319
2385
|
end
|
@@ -2331,6 +2397,16 @@ module Net
|
|
2331
2397
|
# capability has been enabled.
|
2332
2398
|
#
|
2333
2399
|
# See #search for documentation of parameters.
|
2400
|
+
#
|
2401
|
+
# ==== Capabilities
|
2402
|
+
#
|
2403
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
|
2404
|
+
# #uid_search must be used instead of #search, and the <tt><message
|
2405
|
+
# set></tt> search criterion is prohibited. Use +ALL+ or <tt>UID
|
2406
|
+
# sequence-set</tt> instead.
|
2407
|
+
#
|
2408
|
+
# Otherwise, #uid_search is updated by extensions in the same way as
|
2409
|
+
# #search.
|
2334
2410
|
def uid_search(...)
|
2335
2411
|
search_internal("UID SEARCH", ...)
|
2336
2412
|
end
|
@@ -2341,24 +2417,19 @@ module Net
|
|
2341
2417
|
# Sends a {FETCH command [IMAP4rev1 §6.4.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5]
|
2342
2418
|
# to retrieve data associated with a message in the mailbox.
|
2343
2419
|
#
|
2344
|
-
#
|
2345
|
-
#
|
2346
|
-
#
|
2347
|
-
# being interpreted as '100:*'. Beware that the +exclude_end?+
|
2348
|
-
# property of a Range object is ignored, and the contents of a
|
2349
|
-
# range are independent of the order of the range endpoints as per
|
2350
|
-
# the protocol specification, so 1...5, 5..1 and 5...1 are all
|
2351
|
-
# equivalent to 1..5.
|
2420
|
+
# +set+ is the message sequence numbers to fetch, and may be any valid input
|
2421
|
+
# to {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
|
2422
|
+
# (For UIDs, use #uid_fetch instead.)
|
2352
2423
|
#
|
2353
|
-
# +attr+ is a list of attributes to fetch; see
|
2354
|
-
#
|
2424
|
+
# +attr+ is a list of attributes to fetch; see FetchStruct documentation for
|
2425
|
+
# a list of supported attributes.
|
2355
2426
|
#
|
2356
2427
|
# +changedsince+ is an optional integer mod-sequence. It limits results to
|
2357
2428
|
# messages with a mod-sequence greater than +changedsince+.
|
2358
2429
|
#
|
2359
2430
|
# The return value is an array of FetchData.
|
2360
2431
|
#
|
2361
|
-
# Related: #
|
2432
|
+
# Related: #uid_fetch, FetchData
|
2362
2433
|
#
|
2363
2434
|
# ==== For example:
|
2364
2435
|
#
|
@@ -2380,37 +2451,80 @@ module Net
|
|
2380
2451
|
#
|
2381
2452
|
# ==== Capabilities
|
2382
2453
|
#
|
2383
|
-
# Many extensions define new message +attr+ names. See
|
2384
|
-
# of supported extension fields.
|
2454
|
+
# Many extensions define new message +attr+ names. See FetchStruct for a
|
2455
|
+
# list of supported extension fields.
|
2385
2456
|
#
|
2386
2457
|
# The server's capabilities must include +CONDSTORE+
|
2387
|
-
# {[RFC7162]}[https://
|
2458
|
+
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162] in order to use the
|
2388
2459
|
# +changedsince+ argument. Using +changedsince+ implicitly enables the
|
2389
2460
|
# +CONDSTORE+ extension.
|
2390
|
-
|
2391
|
-
|
2461
|
+
#
|
2462
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
|
2463
|
+
# +FETCH+ command is prohibited. Use #uid_fetch instead.
|
2464
|
+
def fetch(...)
|
2465
|
+
fetch_internal("FETCH", ...)
|
2392
2466
|
end
|
2393
2467
|
|
2394
2468
|
# :call-seq:
|
2395
|
-
# uid_fetch(set, attr, changedsince: nil) -> array of FetchData
|
2469
|
+
# uid_fetch(set, attr, changedsince: nil, partial: nil) -> array of FetchData (or UIDFetchData)
|
2396
2470
|
#
|
2397
2471
|
# Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
|
2398
2472
|
# to retrieve data associated with a message in the mailbox.
|
2399
2473
|
#
|
2400
|
-
#
|
2401
|
-
#
|
2474
|
+
# +set+ is the message UIDs to fetch, and may be any valid input to
|
2475
|
+
# {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
|
2476
|
+
# (For message sequence numbers, use #fetch instead.)
|
2402
2477
|
#
|
2478
|
+
# +attr+ behaves the same as with #fetch.
|
2403
2479
|
# >>>
|
2404
2480
|
# *Note:* Servers _MUST_ implicitly include the +UID+ message data item as
|
2405
2481
|
# part of any +FETCH+ response caused by a +UID+ command, regardless of
|
2406
2482
|
# whether a +UID+ was specified as a message data item to the +FETCH+.
|
2407
2483
|
#
|
2484
|
+
# +changedsince+ (optional) behaves the same as with #fetch.
|
2485
|
+
#
|
2486
|
+
# +partial+ is an optional range to limit the number of results returned.
|
2487
|
+
# It's useful when +set+ contains an unknown number of messages.
|
2488
|
+
# <tt>1..500</tt> returns the first 500 messages in +set+ (in mailbox
|
2489
|
+
# order), <tt>501..1000</tt> the second 500, and so on. +partial+ may also
|
2490
|
+
# be negative: <tt>-500..-1</tt> selects the last 500 messages in +set+.
|
2491
|
+
# <em>Requires the +PARTIAL+ capabability.</em>
|
2492
|
+
# {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
|
2493
|
+
#
|
2494
|
+
# For example:
|
2495
|
+
#
|
2496
|
+
# # Without partial, the size of the results may be unknown beforehand:
|
2497
|
+
# results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS))
|
2498
|
+
# # ... maybe wait for a long time ... and allocate a lot of memory ...
|
2499
|
+
# results.size # => 0..2**32-1
|
2500
|
+
# process results # may also take a long time and use a lot of memory...
|
2501
|
+
#
|
2502
|
+
# # Using partial, the results may be paginated:
|
2503
|
+
# loop do
|
2504
|
+
# results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS),
|
2505
|
+
# partial: 1..500)
|
2506
|
+
# # fetch should return quickly and allocate little memory
|
2507
|
+
# results.size # => 0..500
|
2508
|
+
# break if results.empty?
|
2509
|
+
# next_uid_to_fetch = results.last.uid + 1
|
2510
|
+
# process results
|
2511
|
+
# end
|
2512
|
+
#
|
2408
2513
|
# Related: #fetch, FetchData
|
2409
2514
|
#
|
2410
2515
|
# ==== Capabilities
|
2411
|
-
#
|
2412
|
-
|
2413
|
-
|
2516
|
+
#
|
2517
|
+
# The server's capabilities must include +PARTIAL+
|
2518
|
+
# {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394] in order to use the
|
2519
|
+
# +partial+ argument.
|
2520
|
+
#
|
2521
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
|
2522
|
+
# #uid_fetch must be used instead of #fetch, and UIDFetchData will be
|
2523
|
+
# returned instead of FetchData.
|
2524
|
+
#
|
2525
|
+
# Otherwise, #uid_fetch is updated by extensions in the same way as #fetch.
|
2526
|
+
def uid_fetch(...)
|
2527
|
+
fetch_internal("UID FETCH", ...)
|
2414
2528
|
end
|
2415
2529
|
|
2416
2530
|
# :call-seq:
|
@@ -2453,15 +2567,18 @@ module Net
|
|
2453
2567
|
# Extensions may define new data items to be used with #store.
|
2454
2568
|
#
|
2455
2569
|
# The server's capabilities must include +CONDSTORE+
|
2456
|
-
# {[RFC7162]}[https://
|
2570
|
+
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162] in order to use the
|
2457
2571
|
# +unchangedsince+ argument. Using +unchangedsince+ implicitly enables the
|
2458
2572
|
# +CONDSTORE+ extension.
|
2573
|
+
#
|
2574
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
|
2575
|
+
# +STORE+ command is prohibited. Use #uid_store instead.
|
2459
2576
|
def store(set, attr, flags, unchangedsince: nil)
|
2460
2577
|
store_internal("STORE", set, attr, flags, unchangedsince: unchangedsince)
|
2461
2578
|
end
|
2462
2579
|
|
2463
2580
|
# :call-seq:
|
2464
|
-
# uid_store(set, attr, value, unchangedsince: nil) -> array of FetchData
|
2581
|
+
# uid_store(set, attr, value, unchangedsince: nil) -> array of FetchData (or UIDFetchData)
|
2465
2582
|
#
|
2466
2583
|
# Sends a {UID STORE command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
|
2467
2584
|
# to alter data associated with messages in the mailbox, in particular their
|
@@ -2473,7 +2590,12 @@ module Net
|
|
2473
2590
|
# Related: #store
|
2474
2591
|
#
|
2475
2592
|
# ==== Capabilities
|
2476
|
-
#
|
2593
|
+
#
|
2594
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
|
2595
|
+
# #uid_store must be used instead of #store, and UIDFetchData will be
|
2596
|
+
# returned instead of FetchData.
|
2597
|
+
#
|
2598
|
+
# Otherwise, #uid_store is updated by extensions in the same way as #store.
|
2477
2599
|
def uid_store(set, attr, flags, unchangedsince: nil)
|
2478
2600
|
store_internal("UID STORE", set, attr, flags, unchangedsince: unchangedsince)
|
2479
2601
|
end
|
@@ -2492,6 +2614,9 @@ module Net
|
|
2492
2614
|
# with UIDPlusData. This will report the UIDVALIDITY of the destination
|
2493
2615
|
# mailbox, the UID set of the source messages, and the assigned UID set of
|
2494
2616
|
# the moved messages.
|
2617
|
+
#
|
2618
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
|
2619
|
+
# +COPY+ command is prohibited. Use #uid_copy instead.
|
2495
2620
|
def copy(set, mailbox)
|
2496
2621
|
copy_internal("COPY", set, mailbox)
|
2497
2622
|
end
|
@@ -2504,7 +2629,10 @@ module Net
|
|
2504
2629
|
#
|
2505
2630
|
# ==== Capabilities
|
2506
2631
|
#
|
2507
|
-
#
|
2632
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] in enabled,
|
2633
|
+
# #uid_copy must be used instead of #copy.
|
2634
|
+
#
|
2635
|
+
# Otherwise, #uid_copy is updated by extensions in the same way as #copy.
|
2508
2636
|
def uid_copy(set, mailbox)
|
2509
2637
|
copy_internal("UID COPY", set, mailbox)
|
2510
2638
|
end
|
@@ -2519,8 +2647,8 @@ module Net
|
|
2519
2647
|
#
|
2520
2648
|
# ==== Capabilities
|
2521
2649
|
#
|
2522
|
-
# The server's capabilities must include +MOVE+
|
2523
|
-
# [RFC6851[https://
|
2650
|
+
# The server's capabilities must include either +IMAP4rev2+ or +MOVE+
|
2651
|
+
# [RFC6851[https://www.rfc-editor.org/rfc/rfc6851]].
|
2524
2652
|
#
|
2525
2653
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
2526
2654
|
# supported, the server's response should include a +COPYUID+ response code
|
@@ -2528,6 +2656,8 @@ module Net
|
|
2528
2656
|
# mailbox, the UID set of the source messages, and the assigned UID set of
|
2529
2657
|
# the moved messages.
|
2530
2658
|
#
|
2659
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
|
2660
|
+
# +MOVE+ command is prohibited. Use #uid_move instead.
|
2531
2661
|
def move(set, mailbox)
|
2532
2662
|
copy_internal("MOVE", set, mailbox)
|
2533
2663
|
end
|
@@ -2543,9 +2673,13 @@ module Net
|
|
2543
2673
|
#
|
2544
2674
|
# ==== Capabilities
|
2545
2675
|
#
|
2546
|
-
#
|
2547
|
-
# [RFC6851[https://
|
2548
|
-
#
|
2676
|
+
# The server's capabilities must include either +IMAP4rev2+ or +MOVE+
|
2677
|
+
# [RFC6851[https://www.rfc-editor.org/rfc/rfc6851]].
|
2678
|
+
#
|
2679
|
+
# When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
|
2680
|
+
# #uid_move must be used instead of #move.
|
2681
|
+
#
|
2682
|
+
# Otherwise, #uid_move is updated by extensions in the same way as #move.
|
2549
2683
|
def uid_move(set, mailbox)
|
2550
2684
|
copy_internal("UID MOVE", set, mailbox)
|
2551
2685
|
end
|
@@ -2571,7 +2705,7 @@ module Net
|
|
2571
2705
|
# ==== Capabilities
|
2572
2706
|
#
|
2573
2707
|
# The server's capabilities must include +SORT+
|
2574
|
-
# [RFC5256[https://
|
2708
|
+
# [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
|
2575
2709
|
def sort(sort_keys, search_keys, charset)
|
2576
2710
|
return sort_internal("SORT", sort_keys, search_keys, charset)
|
2577
2711
|
end
|
@@ -2586,7 +2720,7 @@ module Net
|
|
2586
2720
|
# ==== Capabilities
|
2587
2721
|
#
|
2588
2722
|
# The server's capabilities must include +SORT+
|
2589
|
-
# [RFC5256[https://
|
2723
|
+
# [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
|
2590
2724
|
def uid_sort(sort_keys, search_keys, charset)
|
2591
2725
|
return sort_internal("UID SORT", sort_keys, search_keys, charset)
|
2592
2726
|
end
|
@@ -2611,7 +2745,7 @@ module Net
|
|
2611
2745
|
# ==== Capabilities
|
2612
2746
|
#
|
2613
2747
|
# The server's capabilities must include +THREAD+
|
2614
|
-
# [RFC5256[https://
|
2748
|
+
# [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
|
2615
2749
|
def thread(algorithm, search_keys, charset)
|
2616
2750
|
return thread_internal("THREAD", algorithm, search_keys, charset)
|
2617
2751
|
end
|
@@ -2625,7 +2759,7 @@ module Net
|
|
2625
2759
|
# ==== Capabilities
|
2626
2760
|
#
|
2627
2761
|
# The server's capabilities must include +THREAD+
|
2628
|
-
# [RFC5256[https://
|
2762
|
+
# [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
|
2629
2763
|
def uid_thread(algorithm, search_keys, charset)
|
2630
2764
|
return thread_internal("UID THREAD", algorithm, search_keys, charset)
|
2631
2765
|
end
|
@@ -2644,8 +2778,8 @@ module Net
|
|
2644
2778
|
# ==== Capabilities
|
2645
2779
|
#
|
2646
2780
|
# The server's capabilities must include
|
2647
|
-
# +ENABLE+ [RFC5161[https://
|
2648
|
-
# or +IMAP4REV2+ [RFC9051[https://
|
2781
|
+
# +ENABLE+ [RFC5161[https://www.rfc-editor.org/rfc/rfc5161]]
|
2782
|
+
# or +IMAP4REV2+ [RFC9051[https://www.rfc-editor.org/rfc/rfc9051]].
|
2649
2783
|
#
|
2650
2784
|
# Additionally, the server capabilities must include a capability matching
|
2651
2785
|
# each enabled extension (usually the same name as the enabled extension).
|
@@ -2664,7 +2798,7 @@ module Net
|
|
2664
2798
|
# <tt>"UTF8=ACCEPT"</tt> or <tt>"IMAP4rev2"</tt>, depending on server
|
2665
2799
|
# capabilities.
|
2666
2800
|
#
|
2667
|
-
# [<tt>"UTF8=ACCEPT"</tt> [RFC6855[https://
|
2801
|
+
# [<tt>"UTF8=ACCEPT"</tt> [RFC6855[https://www.rfc-editor.org/rfc/rfc6855]]]
|
2668
2802
|
#
|
2669
2803
|
# The server's capabilities must include <tt>UTF8=ACCEPT</tt> _or_
|
2670
2804
|
# <tt>UTF8=ONLY</tt>.
|
@@ -2683,13 +2817,23 @@ module Net
|
|
2683
2817
|
# encoding, even if they generally contain UTF-8 data, if they are
|
2684
2818
|
# text at all.
|
2685
2819
|
#
|
2686
|
-
# [<tt>"UTF8=ONLY"</tt> [RFC6855[https://
|
2820
|
+
# [<tt>"UTF8=ONLY"</tt> [RFC6855[https://www.rfc-editor.org/rfc/rfc6855]]]
|
2687
2821
|
#
|
2688
2822
|
# A server that reports the <tt>UTF8=ONLY</tt> capability _requires_ that
|
2689
2823
|
# the client <tt>enable("UTF8=ACCEPT")</tt> before any mailboxes may be
|
2690
2824
|
# selected. For convenience, <tt>enable("UTF8=ONLY")</tt> is aliased to
|
2691
2825
|
# <tt>enable("UTF8=ACCEPT")</tt>.
|
2692
2826
|
#
|
2827
|
+
# [+UIDONLY+ {[RFC9586]}[https://www.rfc-editor.org/rfc/rfc9586.pdf]]
|
2828
|
+
#
|
2829
|
+
# When UIDONLY is enabled, the #fetch, #store, #search, #copy, and #move
|
2830
|
+
# commands are prohibited and result in a tagged BAD response. Clients
|
2831
|
+
# should instead use uid_fetch, uid_store, uid_search, uid_copy, or
|
2832
|
+
# uid_move, respectively. All +FETCH+ responses that would be returned are
|
2833
|
+
# replaced by +UIDFETCH+ responses. All +EXPUNGED+ responses that would be
|
2834
|
+
# returned are replaced by +VANISHED+ responses. The "<sequence set>"
|
2835
|
+
# uid_search criterion is prohibited.
|
2836
|
+
#
|
2693
2837
|
# ===== Unsupported capabilities
|
2694
2838
|
#
|
2695
2839
|
# *Note:* Some extensions that use ENABLE permit the server to send syntax
|
@@ -2745,8 +2889,8 @@ module Net
|
|
2745
2889
|
#
|
2746
2890
|
# ==== Capabilities
|
2747
2891
|
#
|
2748
|
-
# The server's capabilities must include +IDLE+
|
2749
|
-
# [RFC2177[https://
|
2892
|
+
# The server's capabilities must include either +IMAP4rev2+ or +IDLE+
|
2893
|
+
# [RFC2177[https://www.rfc-editor.org/rfc/rfc2177]].
|
2750
2894
|
def idle(timeout = nil, &response_handler)
|
2751
2895
|
raise LocalJumpError, "no block given" unless response_handler
|
2752
2896
|
|
@@ -3261,6 +3405,22 @@ module Net
|
|
3261
3405
|
end
|
3262
3406
|
end
|
3263
3407
|
|
3408
|
+
def expunge_internal(...)
|
3409
|
+
synchronize do
|
3410
|
+
send_command(...)
|
3411
|
+
expunged_array = clear_responses("EXPUNGE")
|
3412
|
+
vanished_array = extract_responses("VANISHED") { !_1.earlier? }
|
3413
|
+
if vanished_array.empty?
|
3414
|
+
expunged_array
|
3415
|
+
elsif vanished_array.length == 1
|
3416
|
+
vanished_array.first
|
3417
|
+
else
|
3418
|
+
merged_uids = SequenceSet[*vanished_array.map(&:uids)]
|
3419
|
+
VanishedData[uids: merged_uids, earlier: false]
|
3420
|
+
end
|
3421
|
+
end
|
3422
|
+
end
|
3423
|
+
|
3264
3424
|
RETURN_WHOLE = /\ARETURN\z/i
|
3265
3425
|
RETURN_START = /\ARETURN\b/i
|
3266
3426
|
private_constant :RETURN_WHOLE, :RETURN_START
|
@@ -3306,24 +3466,14 @@ module Net
|
|
3306
3466
|
]
|
3307
3467
|
return_opts.map {|opt|
|
3308
3468
|
case opt
|
3309
|
-
when Symbol
|
3310
|
-
when
|
3311
|
-
|
3469
|
+
when Symbol then opt.to_s
|
3470
|
+
when PartialRange::Negative then PartialRange[opt]
|
3471
|
+
when Range then SequenceSet[opt]
|
3472
|
+
else opt
|
3312
3473
|
end
|
3313
3474
|
}
|
3314
3475
|
end
|
3315
3476
|
|
3316
|
-
def partial_range_last_or_seqset(range)
|
3317
|
-
case [range.begin, range.end]
|
3318
|
-
in [Integer => first, Integer => last] if first.negative? && last.negative?
|
3319
|
-
# partial-range-last [RFC9394]
|
3320
|
-
first <= last or raise DataFormatError, "empty range: %p" % [range]
|
3321
|
-
"#{first}:#{last}"
|
3322
|
-
else
|
3323
|
-
SequenceSet[range]
|
3324
|
-
end
|
3325
|
-
end
|
3326
|
-
|
3327
3477
|
def search_internal(cmd, ...)
|
3328
3478
|
args, esearch = search_args(...)
|
3329
3479
|
synchronize do
|
@@ -3350,7 +3500,12 @@ module Net
|
|
3350
3500
|
end
|
3351
3501
|
end
|
3352
3502
|
|
3353
|
-
def fetch_internal(cmd, set, attr, mod = nil, changedsince: nil)
|
3503
|
+
def fetch_internal(cmd, set, attr, mod = nil, partial: nil, changedsince: nil)
|
3504
|
+
set = SequenceSet[set]
|
3505
|
+
if partial
|
3506
|
+
mod ||= []
|
3507
|
+
mod << "PARTIAL" << PartialRange[partial]
|
3508
|
+
end
|
3354
3509
|
if changedsince
|
3355
3510
|
mod ||= []
|
3356
3511
|
mod << "CHANGEDSINCE" << Integer(changedsince)
|
@@ -3364,15 +3519,9 @@ module Net
|
|
3364
3519
|
}
|
3365
3520
|
end
|
3366
3521
|
|
3367
|
-
|
3368
|
-
|
3369
|
-
|
3370
|
-
send_command(cmd, SequenceSet.new(set), attr, mod)
|
3371
|
-
else
|
3372
|
-
send_command(cmd, SequenceSet.new(set), attr)
|
3373
|
-
end
|
3374
|
-
clear_responses("FETCH")
|
3375
|
-
end
|
3522
|
+
args = [cmd, set, attr]
|
3523
|
+
args << mod if mod
|
3524
|
+
send_command_returning_fetch_results(*args)
|
3376
3525
|
end
|
3377
3526
|
|
3378
3527
|
def store_internal(cmd, set, attr, flags, unchangedsince: nil)
|
@@ -3380,10 +3529,17 @@ module Net
|
|
3380
3529
|
args = [SequenceSet.new(set)]
|
3381
3530
|
args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
|
3382
3531
|
args << attr << flags
|
3532
|
+
send_command_returning_fetch_results(cmd, *args)
|
3533
|
+
end
|
3534
|
+
|
3535
|
+
def send_command_returning_fetch_results(...)
|
3383
3536
|
synchronize do
|
3384
3537
|
clear_responses("FETCH")
|
3385
|
-
|
3386
|
-
|
3538
|
+
clear_responses("UIDFETCH")
|
3539
|
+
send_command(...)
|
3540
|
+
fetches = clear_responses("FETCH")
|
3541
|
+
uidfetches = clear_responses("UIDFETCH")
|
3542
|
+
uidfetches.any? ? uidfetches : fetches
|
3387
3543
|
end
|
3388
3544
|
end
|
3389
3545
|
|