net-imap 0.5.2 → 0.5.6

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

Potentially problematic release.


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

data/lib/net/imap.rb CHANGED
@@ -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://tools.ietf.org/html/rfc3501]
29
- # and {IMAP4rev2 [RFC9051]}[https://tools.ietf.org/html/rfc9051].
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://tools.ietf.org/html/rfc3501]] base specification, or
302
+ # the [IMAP4rev1[https://www.rfc-editor.org/rfc/rfc3501]] base specification, or
303
303
  # by one of the following extensions:
304
- # [IDLE[https://tools.ietf.org/html/rfc2177]],
305
- # [NAMESPACE[https://tools.ietf.org/html/rfc2342]],
306
- # [UNSELECT[https://tools.ietf.org/html/rfc3691]],
307
- # [ENABLE[https://tools.ietf.org/html/rfc5161]],
308
- # [MOVE[https://tools.ietf.org/html/rfc6851]].
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://tools.ietf.org/html/rfc9051]].
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://tools.ietf.org/html/rfc9051] is not supported
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://tools.ietf.org/html/rfc9051] and also included
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://tools.ietf.org/html/rfc9051] and also included
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://tools.ietf.org/html/rfc9051].
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://tools.ietf.org/html/rfc9051] and also included
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://tools.ietf.org/html/rfc9051] and also included
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://tools.ietf.org/html/rfc9051].
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://tools.ietf.org/html/rfc9051].
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://tools.ietf.org/html/rfc9051] and also included
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://tools.ietf.org/html/rfc9051] and also included
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://tools.ietf.org/html/rfc2152]]::
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://tools.ietf.org/html/rfc5322]]::
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://tools.ietf.org/html/rfc2822]<em> (April 2001) and</em>
581
- # RFC-822[https://tools.ietf.org/html/rfc822]<em> (August 1982).</em>
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://tools.ietf.org/html/rfc2978]]::
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://tools.ietf.org/html/rfc2183]]::
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://tools.ietf.org/html/rfc2045]]::
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://tools.ietf.org/html/rfc2046]]::
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://tools.ietf.org/html/rfc2047]]::
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://tools.ietf.org/html/rfc2231]]::
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://tools.ietf.org/html/rfc6532]]::
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://tools.ietf.org/html/rfc1864]]::
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://tools.ietf.org/html/rfc3503]]::
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://tools.ietf.org/html/rfc9208]]::
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://tools.ietf.org/html/rfc2087]<em> (January 1997)</em>.
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://tools.ietf.org/html/rfc2177]]::
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://tools.ietf.org/html/rfc2342]]::
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://tools.ietf.org/html/rfc2971]]::
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://tools.ietf.org/html/rfc3516]]::
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://tools.ietf.org/html/rfc4314]]::
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://tools.ietf.org/html/rfc5256]]::
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://tools.ietf.org/html/rfc5256]]::
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://tools.ietf.org/html/rfc6851]]::
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://tools.ietf.org/html/rfc6855]]::
690
- # [UTF8=ONLY[https://tools.ietf.org/html/rfc6855]]::
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://tools.ietf.org/html/rfc7162]]::
695
- # [QRESYNC[https://tools.ietf.org/html/rfc7162]]::
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://tools.ietf.org/html/rfc8474]]::
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
- # ===== For currently unsupported features:
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.2"
747
+ VERSION = "0.5.6"
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://tools.ietf.org/html/rfc2971]] for field definitions.
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://tools.ietf.org/html/rfc2971]].
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))
@@ -1218,13 +1239,21 @@ module Net
1218
1239
  #
1219
1240
  def starttls(**options)
1220
1241
  @ssl_ctx_params, @ssl_ctx = build_ssl_ctx(options)
1221
- send_command("STARTTLS") do |resp|
1242
+ error = nil
1243
+ ok = send_command("STARTTLS") do |resp|
1222
1244
  if resp.kind_of?(TaggedResponse) && resp.name == "OK"
1223
1245
  clear_cached_capabilities
1224
1246
  clear_responses
1225
1247
  start_tls_session
1226
1248
  end
1249
+ rescue Exception => error
1250
+ raise # note that the error backtrace is in the receiver_thread
1227
1251
  end
1252
+ if error
1253
+ disconnect
1254
+ raise error
1255
+ end
1256
+ ok
1228
1257
  end
1229
1258
 
1230
1259
  # :call-seq:
@@ -1553,7 +1582,7 @@ module Net
1553
1582
  # servers, then folder creation (and listing, moving, etc) can lead to
1554
1583
  # errors.
1555
1584
  #
1556
- # From RFC2342[https://tools.ietf.org/html/rfc2342]:
1585
+ # From RFC2342[https://www.rfc-editor.org/rfc/rfc2342]:
1557
1586
  # >>>
1558
1587
  # <em>Although typically a server will support only a single Personal
1559
1588
  # Namespace, and a single Other User's Namespace, circumstances exist
@@ -1582,8 +1611,8 @@ module Net
1582
1611
  #
1583
1612
  # ==== Capabilities
1584
1613
  #
1585
- # The server's capabilities must include +NAMESPACE+
1586
- # [RFC2342[https://tools.ietf.org/html/rfc2342]].
1614
+ # The server's capabilities must include either +IMAP4rev2+ or +NAMESPACE+
1615
+ # [RFC2342[https://www.rfc-editor.org/rfc/rfc2342]].
1587
1616
  def namespace
1588
1617
  synchronize do
1589
1618
  send_command("NAMESPACE")
@@ -1645,7 +1674,7 @@ module Net
1645
1674
  # ==== Capabilities
1646
1675
  #
1647
1676
  # The server's capabilities must include +QUOTA+
1648
- # [RFC2087[https://tools.ietf.org/html/rfc2087]].
1677
+ # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1649
1678
  def getquotaroot(mailbox)
1650
1679
  synchronize do
1651
1680
  send_command("GETQUOTAROOT", mailbox)
@@ -1666,7 +1695,7 @@ module Net
1666
1695
  # ==== Capabilities
1667
1696
  #
1668
1697
  # The server's capabilities must include +QUOTA+
1669
- # [RFC2087[https://tools.ietf.org/html/rfc2087]].
1698
+ # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1670
1699
  def getquota(mailbox)
1671
1700
  synchronize do
1672
1701
  send_command("GETQUOTA", mailbox)
@@ -1684,7 +1713,7 @@ module Net
1684
1713
  # ==== Capabilities
1685
1714
  #
1686
1715
  # The server's capabilities must include +QUOTA+
1687
- # [RFC2087[https://tools.ietf.org/html/rfc2087]].
1716
+ # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1688
1717
  def setquota(mailbox, quota)
1689
1718
  if quota.nil?
1690
1719
  data = '()'
@@ -1704,7 +1733,7 @@ module Net
1704
1733
  # ==== Capabilities
1705
1734
  #
1706
1735
  # The server's capabilities must include +ACL+
1707
- # [RFC4314[https://tools.ietf.org/html/rfc4314]].
1736
+ # [RFC4314[https://www.rfc-editor.org/rfc/rfc4314]].
1708
1737
  def setacl(mailbox, user, rights)
1709
1738
  if rights.nil?
1710
1739
  send_command("SETACL", mailbox, user, "")
@@ -1722,7 +1751,7 @@ module Net
1722
1751
  # ==== Capabilities
1723
1752
  #
1724
1753
  # The server's capabilities must include +ACL+
1725
- # [RFC4314[https://tools.ietf.org/html/rfc4314]].
1754
+ # [RFC4314[https://www.rfc-editor.org/rfc/rfc4314]].
1726
1755
  def getacl(mailbox)
1727
1756
  synchronize do
1728
1757
  send_command("GETACL", mailbox)
@@ -1883,54 +1912,70 @@ module Net
1883
1912
  #
1884
1913
  # ==== Capabilities
1885
1914
  #
1886
- # The server's capabilities must include +UNSELECT+
1887
- # [RFC3691[https://tools.ietf.org/html/rfc3691]].
1915
+ # The server's capabilities must include either +IMAP4rev2+ or +UNSELECT+
1916
+ # [RFC3691[https://www.rfc-editor.org/rfc/rfc3691]].
1888
1917
  def unselect
1889
1918
  send_command("UNSELECT")
1890
1919
  end
1891
1920
 
1921
+ # call-seq:
1922
+ # expunge -> array of message sequence numbers
1923
+ # expunge -> VanishedData of UIDs
1924
+ #
1892
1925
  # Sends an {EXPUNGE command [IMAP4rev1 §6.4.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.3]
1893
- # Sends a EXPUNGE command to permanently remove from the currently
1894
- # selected mailbox all messages that have the \Deleted flag set.
1926
+ # to permanently remove all messages with the +\Deleted+ flag from the
1927
+ # currently selected mailbox.
1928
+ #
1929
+ # Returns either an array of expunged message <em>sequence numbers</em> or
1930
+ # (when the appropriate capability is enabled) VanishedData of expunged
1931
+ # UIDs. Previously unhandled +EXPUNGE+ or +VANISHED+ responses are merged
1932
+ # with the direct response to this command. <tt>VANISHED (EARLIER)</tt>
1933
+ # responses will _not_ be merged.
1934
+ #
1935
+ # When no messages have been expunged, an empty array is returned,
1936
+ # regardless of which extensions are enabled. In a future release, an empty
1937
+ # VanishedData may be returned, based on the currently enabled extensions.
1895
1938
  #
1896
1939
  # Related: #uid_expunge
1940
+ #
1941
+ # ==== Capabilities
1942
+ #
1943
+ # When either QRESYNC[https://www.rfc-editor.org/rfc/rfc7162] or
1944
+ # UIDONLY[https://www.rfc-editor.org/rfc/rfc9586] are enabled, #expunge
1945
+ # returns VanishedData, which contains UIDs---<em>not message sequence
1946
+ # numbers</em>.
1897
1947
  def expunge
1898
- synchronize do
1899
- send_command("EXPUNGE")
1900
- clear_responses("EXPUNGE")
1901
- end
1948
+ expunge_internal("EXPUNGE")
1902
1949
  end
1903
1950
 
1951
+ # call-seq:
1952
+ # uid_expunge{uid_set) -> array of message sequence numbers
1953
+ # uid_expunge{uid_set) -> VanishedData of UIDs
1954
+ #
1904
1955
  # Sends a {UID EXPUNGE command [RFC4315 §2.1]}[https://www.rfc-editor.org/rfc/rfc4315#section-2.1]
1905
1956
  # {[IMAP4rev2 §6.4.9]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.9]
1906
1957
  # to permanently remove all messages that have both the <tt>\\Deleted</tt>
1907
1958
  # flag set and a UID that is included in +uid_set+.
1908
1959
  #
1960
+ # Returns the same result type as #expunge.
1961
+ #
1909
1962
  # By using #uid_expunge instead of #expunge when resynchronizing with
1910
1963
  # the server, the client can ensure that it does not inadvertantly
1911
1964
  # remove any messages that have been marked as <tt>\\Deleted</tt> by other
1912
1965
  # clients between the time that the client was last connected and
1913
1966
  # the time the client resynchronizes.
1914
1967
  #
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
1968
  # Related: #expunge
1924
1969
  #
1925
1970
  # ==== Capabilities
1926
1971
  #
1927
- # The server's capabilities must include +UIDPLUS+
1972
+ # The server's capabilities must include either +IMAP4rev2+ or +UIDPLUS+
1928
1973
  # [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]].
1974
+ #
1975
+ # Otherwise, #uid_expunge is updated by extensions in the same way as
1976
+ # #expunge.
1929
1977
  def uid_expunge(uid_set)
1930
- synchronize do
1931
- send_command("UID EXPUNGE", SequenceSet.new(uid_set))
1932
- clear_responses("EXPUNGE")
1933
- end
1978
+ expunge_internal("UID EXPUNGE", SequenceSet.new(uid_set))
1934
1979
  end
1935
1980
 
1936
1981
  # :call-seq:
@@ -1942,7 +1987,7 @@ module Net
1942
1987
  # and returns either a SearchResult or an ESearchResult. SearchResult
1943
1988
  # inherits from Array (for backward compatibility) but adds
1944
1989
  # SearchResult#modseq when the +CONDSTORE+ capability has been enabled.
1945
- # ESearchResult also implements to_a{rdoc-ref:ESearchResult#to_a}, for
1990
+ # ESearchResult also implements {#to_a}[rdoc-ref:ESearchResult#to_a], for
1946
1991
  # compatibility with SearchResult.
1947
1992
  #
1948
1993
  # +criteria+ is one or more search keys and their arguments, which may be
@@ -1955,8 +2000,9 @@ module Net
1955
2000
  # the server to return an ESearchResult instead of a SearchResult, but some
1956
2001
  # servers disobey this requirement. <em>Requires an extended search
1957
2002
  # capability, such as +ESEARCH+ or +IMAP4rev2+.</em>
1958
- # See {"Argument translation"}[rdoc-ref:#search@Argument+translation]
1959
- # and {"Return options"}[rdoc-ref:#search@Return+options], below.
2003
+ # See {"Argument translation"}[rdoc-ref:#search@Argument+translation] and
2004
+ # {"Supported return options"}[rdoc-ref:#search@Supported+return+options],
2005
+ # below.
1960
2006
  #
1961
2007
  # +charset+ is the name of the {registered character
1962
2008
  # set}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
@@ -2066,33 +2112,58 @@ module Net
2066
2112
  # <em>*WARNING:* This is vulnerable to injection attacks when external
2067
2113
  # inputs are used.</em>
2068
2114
  #
2069
- # ==== Return options
2115
+ # ==== Supported return options
2070
2116
  #
2071
2117
  # For full definitions of the standard return options and return data, see
2072
2118
  # the relevant RFCs.
2073
2119
  #
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
2120
  # [+ALL+]
2081
2121
  # Returns ESearchResult#all with a SequenceSet of all matching sequence
2082
2122
  # numbers or UIDs. This is the default, when return options are empty.
2083
2123
  #
2084
2124
  # For compatibility with SearchResult, ESearchResult#to_a returns an
2085
2125
  # Array of message sequence numbers or UIDs.
2126
+ #
2127
+ # <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
2128
+ # {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
2129
+ # {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
2130
+ #
2086
2131
  # [+COUNT+]
2087
2132
  # Returns ESearchResult#count with the number of matching messages.
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
+ #
2088
2138
  # [+MAX+]
2089
2139
  # Returns ESearchResult#max with the highest matching sequence number or
2090
2140
  # UID.
2141
+ #
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
+ #
2091
2146
  # [+MIN+]
2092
2147
  # Returns ESearchResult#min with the lowest matching sequence number or
2093
2148
  # UID.
2094
2149
  #
2095
- # ===== +CONDSTORE+
2150
+ # <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
2151
+ # {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
2152
+ # {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
2153
+ #
2154
+ # [+PARTIAL+ _range_]
2155
+ # Returns ESearchResult#partial with a SequenceSet of a subset of
2156
+ # matching sequence numbers or UIDs, as selected by _range_. As with
2157
+ # sequence numbers, the first result is +1+: <tt>1..500</tt> selects the
2158
+ # first 500 search results (in mailbox order), <tt>501..1000</tt> the
2159
+ # second 500, and so on. _range_ may also be negative: <tt>-500..-1</tt>
2160
+ # selects the last 500 search results.
2161
+ #
2162
+ # <em>Requires either the <tt>CONTEXT=SEARCH</tt> or +PARTIAL+ capabability.</em>
2163
+ # {[RFC5267]}[https://rfc-editor.org/rfc/rfc5267]
2164
+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
2165
+ #
2166
+ # ===== +MODSEQ+ return data
2096
2167
  #
2097
2168
  # ESearchResult#modseq return data does not have a corresponding return
2098
2169
  # option. Instead, it is returned if the +MODSEQ+ search key is used or
@@ -2104,8 +2175,8 @@ module Net
2104
2175
  #
2105
2176
  # {RFC4466 §2.6}[https://www.rfc-editor.org/rfc/rfc4466.html#section-2.6]
2106
2177
  # defines standard syntax for search extensions. Net::IMAP allows sending
2107
- # unknown search return options and will parse unknown search extensions'
2108
- # return values into ExtensionData. Please note that this is an
2178
+ # unsupported search return options and will parse unsupported search
2179
+ # extensions' return values into ExtensionData. Please note that this is an
2109
2180
  # intentionally _unstable_ API. Future releases may return different
2110
2181
  # (incompatible) objects, <em>without deprecation or warning</em>.
2111
2182
  #
@@ -2314,6 +2385,9 @@ module Net
2314
2385
  # result = imap.search(["SUBJECT", "hi there", "not", "new"])
2315
2386
  # #=> Net::IMAP::SearchResult[1, 6, 7, 8, modseq: 5594]
2316
2387
  # result.modseq # => 5594
2388
+ #
2389
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
2390
+ # the +SEARCH+ command is prohibited. Use #uid_search instead.
2317
2391
  def search(...)
2318
2392
  search_internal("SEARCH", ...)
2319
2393
  end
@@ -2331,6 +2405,16 @@ module Net
2331
2405
  # capability has been enabled.
2332
2406
  #
2333
2407
  # See #search for documentation of parameters.
2408
+ #
2409
+ # ==== Capabilities
2410
+ #
2411
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
2412
+ # #uid_search must be used instead of #search, and the <tt><message
2413
+ # set></tt> search criterion is prohibited. Use +ALL+ or <tt>UID
2414
+ # sequence-set</tt> instead.
2415
+ #
2416
+ # Otherwise, #uid_search is updated by extensions in the same way as
2417
+ # #search.
2334
2418
  def uid_search(...)
2335
2419
  search_internal("UID SEARCH", ...)
2336
2420
  end
@@ -2341,24 +2425,19 @@ module Net
2341
2425
  # Sends a {FETCH command [IMAP4rev1 §6.4.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5]
2342
2426
  # to retrieve data associated with a message in the mailbox.
2343
2427
  #
2344
- # The +set+ parameter is a number or a range between two numbers,
2345
- # or an array of those. The number is a message sequence number,
2346
- # where -1 represents a '*' for use in range notation like 100..-1
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.
2428
+ # +set+ is the message sequence numbers to fetch, and may be any valid input
2429
+ # to {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
2430
+ # (For UIDs, use #uid_fetch instead.)
2352
2431
  #
2353
- # +attr+ is a list of attributes to fetch; see the documentation
2354
- # for FetchData for a list of valid attributes.
2432
+ # +attr+ is a list of attributes to fetch; see FetchStruct documentation for
2433
+ # a list of supported attributes.
2355
2434
  #
2356
2435
  # +changedsince+ is an optional integer mod-sequence. It limits results to
2357
2436
  # messages with a mod-sequence greater than +changedsince+.
2358
2437
  #
2359
2438
  # The return value is an array of FetchData.
2360
2439
  #
2361
- # Related: #uid_search, FetchData
2440
+ # Related: #uid_fetch, FetchData
2362
2441
  #
2363
2442
  # ==== For example:
2364
2443
  #
@@ -2380,37 +2459,80 @@ module Net
2380
2459
  #
2381
2460
  # ==== Capabilities
2382
2461
  #
2383
- # Many extensions define new message +attr+ names. See FetchData for a list
2384
- # of supported extension fields.
2462
+ # Many extensions define new message +attr+ names. See FetchStruct for a
2463
+ # list of supported extension fields.
2385
2464
  #
2386
2465
  # The server's capabilities must include +CONDSTORE+
2387
- # {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
2466
+ # {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162] in order to use the
2388
2467
  # +changedsince+ argument. Using +changedsince+ implicitly enables the
2389
2468
  # +CONDSTORE+ extension.
2390
- def fetch(set, attr, mod = nil, changedsince: nil)
2391
- fetch_internal("FETCH", set, attr, mod, changedsince: changedsince)
2469
+ #
2470
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
2471
+ # +FETCH+ command is prohibited. Use #uid_fetch instead.
2472
+ def fetch(...)
2473
+ fetch_internal("FETCH", ...)
2392
2474
  end
2393
2475
 
2394
2476
  # :call-seq:
2395
- # uid_fetch(set, attr, changedsince: nil) -> array of FetchData
2477
+ # uid_fetch(set, attr, changedsince: nil, partial: nil) -> array of FetchData (or UIDFetchData)
2396
2478
  #
2397
2479
  # Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
2398
2480
  # to retrieve data associated with a message in the mailbox.
2399
2481
  #
2400
- # Similar to #fetch, but the +set+ parameter contains unique identifiers
2401
- # instead of message sequence numbers.
2482
+ # +set+ is the message UIDs to fetch, and may be any valid input to
2483
+ # {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
2484
+ # (For message sequence numbers, use #fetch instead.)
2402
2485
  #
2486
+ # +attr+ behaves the same as with #fetch.
2403
2487
  # >>>
2404
2488
  # *Note:* Servers _MUST_ implicitly include the +UID+ message data item as
2405
2489
  # part of any +FETCH+ response caused by a +UID+ command, regardless of
2406
2490
  # whether a +UID+ was specified as a message data item to the +FETCH+.
2407
2491
  #
2492
+ # +changedsince+ (optional) behaves the same as with #fetch.
2493
+ #
2494
+ # +partial+ is an optional range to limit the number of results returned.
2495
+ # It's useful when +set+ contains an unknown number of messages.
2496
+ # <tt>1..500</tt> returns the first 500 messages in +set+ (in mailbox
2497
+ # order), <tt>501..1000</tt> the second 500, and so on. +partial+ may also
2498
+ # be negative: <tt>-500..-1</tt> selects the last 500 messages in +set+.
2499
+ # <em>Requires the +PARTIAL+ capabability.</em>
2500
+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
2501
+ #
2502
+ # For example:
2503
+ #
2504
+ # # Without partial, the size of the results may be unknown beforehand:
2505
+ # results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS))
2506
+ # # ... maybe wait for a long time ... and allocate a lot of memory ...
2507
+ # results.size # => 0..2**32-1
2508
+ # process results # may also take a long time and use a lot of memory...
2509
+ #
2510
+ # # Using partial, the results may be paginated:
2511
+ # loop do
2512
+ # results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS),
2513
+ # partial: 1..500)
2514
+ # # fetch should return quickly and allocate little memory
2515
+ # results.size # => 0..500
2516
+ # break if results.empty?
2517
+ # next_uid_to_fetch = results.last.uid + 1
2518
+ # process results
2519
+ # end
2520
+ #
2408
2521
  # Related: #fetch, FetchData
2409
2522
  #
2410
2523
  # ==== Capabilities
2411
- # Same as #fetch.
2412
- def uid_fetch(set, attr, mod = nil, changedsince: nil)
2413
- fetch_internal("UID FETCH", set, attr, mod, changedsince: changedsince)
2524
+ #
2525
+ # The server's capabilities must include +PARTIAL+
2526
+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394] in order to use the
2527
+ # +partial+ argument.
2528
+ #
2529
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
2530
+ # #uid_fetch must be used instead of #fetch, and UIDFetchData will be
2531
+ # returned instead of FetchData.
2532
+ #
2533
+ # Otherwise, #uid_fetch is updated by extensions in the same way as #fetch.
2534
+ def uid_fetch(...)
2535
+ fetch_internal("UID FETCH", ...)
2414
2536
  end
2415
2537
 
2416
2538
  # :call-seq:
@@ -2453,15 +2575,18 @@ module Net
2453
2575
  # Extensions may define new data items to be used with #store.
2454
2576
  #
2455
2577
  # The server's capabilities must include +CONDSTORE+
2456
- # {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
2578
+ # {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162] in order to use the
2457
2579
  # +unchangedsince+ argument. Using +unchangedsince+ implicitly enables the
2458
2580
  # +CONDSTORE+ extension.
2581
+ #
2582
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
2583
+ # +STORE+ command is prohibited. Use #uid_store instead.
2459
2584
  def store(set, attr, flags, unchangedsince: nil)
2460
2585
  store_internal("STORE", set, attr, flags, unchangedsince: unchangedsince)
2461
2586
  end
2462
2587
 
2463
2588
  # :call-seq:
2464
- # uid_store(set, attr, value, unchangedsince: nil) -> array of FetchData
2589
+ # uid_store(set, attr, value, unchangedsince: nil) -> array of FetchData (or UIDFetchData)
2465
2590
  #
2466
2591
  # Sends a {UID STORE command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
2467
2592
  # to alter data associated with messages in the mailbox, in particular their
@@ -2473,7 +2598,12 @@ module Net
2473
2598
  # Related: #store
2474
2599
  #
2475
2600
  # ==== Capabilities
2476
- # Same as #store.
2601
+ #
2602
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
2603
+ # #uid_store must be used instead of #store, and UIDFetchData will be
2604
+ # returned instead of FetchData.
2605
+ #
2606
+ # Otherwise, #uid_store is updated by extensions in the same way as #store.
2477
2607
  def uid_store(set, attr, flags, unchangedsince: nil)
2478
2608
  store_internal("UID STORE", set, attr, flags, unchangedsince: unchangedsince)
2479
2609
  end
@@ -2492,6 +2622,9 @@ module Net
2492
2622
  # with UIDPlusData. This will report the UIDVALIDITY of the destination
2493
2623
  # mailbox, the UID set of the source messages, and the assigned UID set of
2494
2624
  # the moved messages.
2625
+ #
2626
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
2627
+ # +COPY+ command is prohibited. Use #uid_copy instead.
2495
2628
  def copy(set, mailbox)
2496
2629
  copy_internal("COPY", set, mailbox)
2497
2630
  end
@@ -2504,7 +2637,10 @@ module Net
2504
2637
  #
2505
2638
  # ==== Capabilities
2506
2639
  #
2507
- # +UIDPLUS+ affects #uid_copy the same way it affects #copy.
2640
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] in enabled,
2641
+ # #uid_copy must be used instead of #copy.
2642
+ #
2643
+ # Otherwise, #uid_copy is updated by extensions in the same way as #copy.
2508
2644
  def uid_copy(set, mailbox)
2509
2645
  copy_internal("UID COPY", set, mailbox)
2510
2646
  end
@@ -2519,8 +2655,8 @@ module Net
2519
2655
  #
2520
2656
  # ==== Capabilities
2521
2657
  #
2522
- # The server's capabilities must include +MOVE+
2523
- # [RFC6851[https://tools.ietf.org/html/rfc6851]].
2658
+ # The server's capabilities must include either +IMAP4rev2+ or +MOVE+
2659
+ # [RFC6851[https://www.rfc-editor.org/rfc/rfc6851]].
2524
2660
  #
2525
2661
  # If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
2526
2662
  # supported, the server's response should include a +COPYUID+ response code
@@ -2528,6 +2664,8 @@ module Net
2528
2664
  # mailbox, the UID set of the source messages, and the assigned UID set of
2529
2665
  # the moved messages.
2530
2666
  #
2667
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled, the
2668
+ # +MOVE+ command is prohibited. Use #uid_move instead.
2531
2669
  def move(set, mailbox)
2532
2670
  copy_internal("MOVE", set, mailbox)
2533
2671
  end
@@ -2543,9 +2681,13 @@ module Net
2543
2681
  #
2544
2682
  # ==== Capabilities
2545
2683
  #
2546
- # Same as #move: The server's capabilities must include +MOVE+
2547
- # [RFC6851[https://tools.ietf.org/html/rfc6851]]. +UIDPLUS+ also affects
2548
- # #uid_move the same way it affects #move.
2684
+ # The server's capabilities must include either +IMAP4rev2+ or +MOVE+
2685
+ # [RFC6851[https://www.rfc-editor.org/rfc/rfc6851]].
2686
+ #
2687
+ # When UIDONLY[https://www.rfc-editor.org/rfc/rfc9586.html] is enabled,
2688
+ # #uid_move must be used instead of #move.
2689
+ #
2690
+ # Otherwise, #uid_move is updated by extensions in the same way as #move.
2549
2691
  def uid_move(set, mailbox)
2550
2692
  copy_internal("UID MOVE", set, mailbox)
2551
2693
  end
@@ -2571,7 +2713,7 @@ module Net
2571
2713
  # ==== Capabilities
2572
2714
  #
2573
2715
  # The server's capabilities must include +SORT+
2574
- # [RFC5256[https://tools.ietf.org/html/rfc5256]].
2716
+ # [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
2575
2717
  def sort(sort_keys, search_keys, charset)
2576
2718
  return sort_internal("SORT", sort_keys, search_keys, charset)
2577
2719
  end
@@ -2586,7 +2728,7 @@ module Net
2586
2728
  # ==== Capabilities
2587
2729
  #
2588
2730
  # The server's capabilities must include +SORT+
2589
- # [RFC5256[https://tools.ietf.org/html/rfc5256]].
2731
+ # [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
2590
2732
  def uid_sort(sort_keys, search_keys, charset)
2591
2733
  return sort_internal("UID SORT", sort_keys, search_keys, charset)
2592
2734
  end
@@ -2611,7 +2753,7 @@ module Net
2611
2753
  # ==== Capabilities
2612
2754
  #
2613
2755
  # The server's capabilities must include +THREAD+
2614
- # [RFC5256[https://tools.ietf.org/html/rfc5256]].
2756
+ # [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
2615
2757
  def thread(algorithm, search_keys, charset)
2616
2758
  return thread_internal("THREAD", algorithm, search_keys, charset)
2617
2759
  end
@@ -2625,7 +2767,7 @@ module Net
2625
2767
  # ==== Capabilities
2626
2768
  #
2627
2769
  # The server's capabilities must include +THREAD+
2628
- # [RFC5256[https://tools.ietf.org/html/rfc5256]].
2770
+ # [RFC5256[https://www.rfc-editor.org/rfc/rfc5256]].
2629
2771
  def uid_thread(algorithm, search_keys, charset)
2630
2772
  return thread_internal("UID THREAD", algorithm, search_keys, charset)
2631
2773
  end
@@ -2644,8 +2786,8 @@ module Net
2644
2786
  # ==== Capabilities
2645
2787
  #
2646
2788
  # The server's capabilities must include
2647
- # +ENABLE+ [RFC5161[https://tools.ietf.org/html/rfc5161]]
2648
- # or +IMAP4REV2+ [RFC9051[https://tools.ietf.org/html/rfc9051]].
2789
+ # +ENABLE+ [RFC5161[https://www.rfc-editor.org/rfc/rfc5161]]
2790
+ # or +IMAP4REV2+ [RFC9051[https://www.rfc-editor.org/rfc/rfc9051]].
2649
2791
  #
2650
2792
  # Additionally, the server capabilities must include a capability matching
2651
2793
  # each enabled extension (usually the same name as the enabled extension).
@@ -2664,7 +2806,7 @@ module Net
2664
2806
  # <tt>"UTF8=ACCEPT"</tt> or <tt>"IMAP4rev2"</tt>, depending on server
2665
2807
  # capabilities.
2666
2808
  #
2667
- # [<tt>"UTF8=ACCEPT"</tt> [RFC6855[https://tools.ietf.org/html/rfc6855]]]
2809
+ # [<tt>"UTF8=ACCEPT"</tt> [RFC6855[https://www.rfc-editor.org/rfc/rfc6855]]]
2668
2810
  #
2669
2811
  # The server's capabilities must include <tt>UTF8=ACCEPT</tt> _or_
2670
2812
  # <tt>UTF8=ONLY</tt>.
@@ -2683,13 +2825,23 @@ module Net
2683
2825
  # encoding, even if they generally contain UTF-8 data, if they are
2684
2826
  # text at all.
2685
2827
  #
2686
- # [<tt>"UTF8=ONLY"</tt> [RFC6855[https://tools.ietf.org/html/rfc6855]]]
2828
+ # [<tt>"UTF8=ONLY"</tt> [RFC6855[https://www.rfc-editor.org/rfc/rfc6855]]]
2687
2829
  #
2688
2830
  # A server that reports the <tt>UTF8=ONLY</tt> capability _requires_ that
2689
2831
  # the client <tt>enable("UTF8=ACCEPT")</tt> before any mailboxes may be
2690
2832
  # selected. For convenience, <tt>enable("UTF8=ONLY")</tt> is aliased to
2691
2833
  # <tt>enable("UTF8=ACCEPT")</tt>.
2692
2834
  #
2835
+ # [+UIDONLY+ {[RFC9586]}[https://www.rfc-editor.org/rfc/rfc9586.pdf]]
2836
+ #
2837
+ # When UIDONLY is enabled, the #fetch, #store, #search, #copy, and #move
2838
+ # commands are prohibited and result in a tagged BAD response. Clients
2839
+ # should instead use uid_fetch, uid_store, uid_search, uid_copy, or
2840
+ # uid_move, respectively. All +FETCH+ responses that would be returned are
2841
+ # replaced by +UIDFETCH+ responses. All +EXPUNGED+ responses that would be
2842
+ # returned are replaced by +VANISHED+ responses. The "<sequence set>"
2843
+ # uid_search criterion is prohibited.
2844
+ #
2693
2845
  # ===== Unsupported capabilities
2694
2846
  #
2695
2847
  # *Note:* Some extensions that use ENABLE permit the server to send syntax
@@ -2745,8 +2897,8 @@ module Net
2745
2897
  #
2746
2898
  # ==== Capabilities
2747
2899
  #
2748
- # The server's capabilities must include +IDLE+
2749
- # [RFC2177[https://tools.ietf.org/html/rfc2177]].
2900
+ # The server's capabilities must include either +IMAP4rev2+ or +IDLE+
2901
+ # [RFC2177[https://www.rfc-editor.org/rfc/rfc2177]].
2750
2902
  def idle(timeout = nil, &response_handler)
2751
2903
  raise LocalJumpError, "no block given" unless response_handler
2752
2904
 
@@ -3261,6 +3413,22 @@ module Net
3261
3413
  end
3262
3414
  end
3263
3415
 
3416
+ def expunge_internal(...)
3417
+ synchronize do
3418
+ send_command(...)
3419
+ expunged_array = clear_responses("EXPUNGE")
3420
+ vanished_array = extract_responses("VANISHED") { !_1.earlier? }
3421
+ if vanished_array.empty?
3422
+ expunged_array
3423
+ elsif vanished_array.length == 1
3424
+ vanished_array.first
3425
+ else
3426
+ merged_uids = SequenceSet[*vanished_array.map(&:uids)]
3427
+ VanishedData[uids: merged_uids, earlier: false]
3428
+ end
3429
+ end
3430
+ end
3431
+
3264
3432
  RETURN_WHOLE = /\ARETURN\z/i
3265
3433
  RETURN_START = /\ARETURN\b/i
3266
3434
  private_constant :RETURN_WHOLE, :RETURN_START
@@ -3306,24 +3474,14 @@ module Net
3306
3474
  ]
3307
3475
  return_opts.map {|opt|
3308
3476
  case opt
3309
- when Symbol then opt.to_s
3310
- when Range then partial_range_last_or_seqset(opt)
3311
- else opt
3477
+ when Symbol then opt.to_s
3478
+ when PartialRange::Negative then PartialRange[opt]
3479
+ when Range then SequenceSet[opt]
3480
+ else opt
3312
3481
  end
3313
3482
  }
3314
3483
  end
3315
3484
 
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
3485
  def search_internal(cmd, ...)
3328
3486
  args, esearch = search_args(...)
3329
3487
  synchronize do
@@ -3350,7 +3508,12 @@ module Net
3350
3508
  end
3351
3509
  end
3352
3510
 
3353
- def fetch_internal(cmd, set, attr, mod = nil, changedsince: nil)
3511
+ def fetch_internal(cmd, set, attr, mod = nil, partial: nil, changedsince: nil)
3512
+ set = SequenceSet[set]
3513
+ if partial
3514
+ mod ||= []
3515
+ mod << "PARTIAL" << PartialRange[partial]
3516
+ end
3354
3517
  if changedsince
3355
3518
  mod ||= []
3356
3519
  mod << "CHANGEDSINCE" << Integer(changedsince)
@@ -3364,15 +3527,9 @@ module Net
3364
3527
  }
3365
3528
  end
3366
3529
 
3367
- synchronize do
3368
- clear_responses("FETCH")
3369
- if mod
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
3530
+ args = [cmd, set, attr]
3531
+ args << mod if mod
3532
+ send_command_returning_fetch_results(*args)
3376
3533
  end
3377
3534
 
3378
3535
  def store_internal(cmd, set, attr, flags, unchangedsince: nil)
@@ -3380,10 +3537,17 @@ module Net
3380
3537
  args = [SequenceSet.new(set)]
3381
3538
  args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
3382
3539
  args << attr << flags
3540
+ send_command_returning_fetch_results(cmd, *args)
3541
+ end
3542
+
3543
+ def send_command_returning_fetch_results(...)
3383
3544
  synchronize do
3384
3545
  clear_responses("FETCH")
3385
- send_command(cmd, *args)
3386
- clear_responses("FETCH")
3546
+ clear_responses("UIDFETCH")
3547
+ send_command(...)
3548
+ fetches = clear_responses("FETCH")
3549
+ uidfetches = clear_responses("UIDFETCH")
3550
+ uidfetches.any? ? uidfetches : fetches
3387
3551
  end
3388
3552
  end
3389
3553