net-imap 0.3.7 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/pages.yml +46 -0
  3. data/.github/workflows/test.yml +5 -12
  4. data/.gitignore +2 -0
  5. data/Gemfile +3 -0
  6. data/README.md +15 -4
  7. data/Rakefile +0 -7
  8. data/docs/styles.css +0 -12
  9. data/lib/net/imap/authenticators.rb +26 -57
  10. data/lib/net/imap/command_data.rb +13 -6
  11. data/lib/net/imap/data_encoding.rb +14 -2
  12. data/lib/net/imap/deprecated_client_options.rb +139 -0
  13. data/lib/net/imap/errors.rb +20 -0
  14. data/lib/net/imap/fetch_data.rb +518 -0
  15. data/lib/net/imap/response_data.rb +116 -252
  16. data/lib/net/imap/response_parser/parser_utils.rb +240 -0
  17. data/lib/net/imap/response_parser.rb +1535 -1003
  18. data/lib/net/imap/sasl/anonymous_authenticator.rb +69 -0
  19. data/lib/net/imap/sasl/authentication_exchange.rb +107 -0
  20. data/lib/net/imap/sasl/authenticators.rb +118 -0
  21. data/lib/net/imap/sasl/client_adapter.rb +72 -0
  22. data/lib/net/imap/{authenticators/cram_md5.rb → sasl/cram_md5_authenticator.rb} +21 -11
  23. data/lib/net/imap/sasl/digest_md5_authenticator.rb +180 -0
  24. data/lib/net/imap/sasl/external_authenticator.rb +83 -0
  25. data/lib/net/imap/sasl/gs2_header.rb +80 -0
  26. data/lib/net/imap/{authenticators/login.rb → sasl/login_authenticator.rb} +25 -16
  27. data/lib/net/imap/sasl/oauthbearer_authenticator.rb +199 -0
  28. data/lib/net/imap/sasl/plain_authenticator.rb +101 -0
  29. data/lib/net/imap/sasl/protocol_adapters.rb +45 -0
  30. data/lib/net/imap/sasl/scram_algorithm.rb +58 -0
  31. data/lib/net/imap/sasl/scram_authenticator.rb +287 -0
  32. data/lib/net/imap/sasl/stringprep.rb +6 -66
  33. data/lib/net/imap/sasl/xoauth2_authenticator.rb +106 -0
  34. data/lib/net/imap/sasl.rb +144 -43
  35. data/lib/net/imap/sasl_adapter.rb +21 -0
  36. data/lib/net/imap/sequence_set.rb +67 -0
  37. data/lib/net/imap/stringprep/nameprep.rb +70 -0
  38. data/lib/net/imap/stringprep/saslprep.rb +69 -0
  39. data/lib/net/imap/stringprep/saslprep_tables.rb +96 -0
  40. data/lib/net/imap/stringprep/tables.rb +146 -0
  41. data/lib/net/imap/stringprep/trace.rb +85 -0
  42. data/lib/net/imap/stringprep.rb +159 -0
  43. data/lib/net/imap.rb +1055 -612
  44. data/net-imap.gemspec +4 -3
  45. data/rakelib/benchmarks.rake +91 -0
  46. data/rakelib/saslprep.rake +4 -4
  47. data/rakelib/string_prep_tables_generator.rb +82 -60
  48. metadata +31 -13
  49. data/benchmarks/stringprep.yml +0 -65
  50. data/benchmarks/table-regexps.yml +0 -39
  51. data/lib/net/imap/authenticators/digest_md5.rb +0 -115
  52. data/lib/net/imap/authenticators/plain.rb +0 -41
  53. data/lib/net/imap/authenticators/xoauth2.rb +0 -20
  54. data/lib/net/imap/sasl/saslprep.rb +0 -55
  55. data/lib/net/imap/sasl/saslprep_tables.rb +0 -98
  56. data/lib/net/imap/sasl/stringprep_tables.rb +0 -153
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Net
4
4
  class IMAP < Protocol
5
+ autoload :FetchData, "#{__dir__}/fetch_data"
6
+ autoload :SequenceSet, "#{__dir__}/sequence_set"
5
7
 
6
8
  # Net::IMAP::ContinuationRequest represents command continuation requests.
7
9
  #
@@ -55,17 +57,71 @@ module Net
55
57
 
56
58
  # Net::IMAP::IgnoredResponse represents intentionally ignored responses.
57
59
  #
58
- # This includes untagged response "NOOP" sent by eg. Zimbra to avoid some
59
- # clients to close the connection.
60
+ # This includes untagged response "NOOP" sent by eg. Zimbra to avoid
61
+ # some clients to close the connection.
60
62
  #
61
63
  # It matches no IMAP standard.
64
+ class IgnoredResponse < UntaggedResponse
65
+ end
66
+
67
+ # **Note:** This represents an intentionally _unstable_ API. Where
68
+ # instances of this class are returned, future releases may return a
69
+ # different (incompatible) object <em>without deprecation or warning</em>.
70
+ #
71
+ # Net::IMAP::UnparsedData represents data for unknown response types or
72
+ # unknown extensions to response types without a well-defined extension
73
+ # grammar.
62
74
  #
63
- class IgnoredResponse < Struct.new(:raw_data)
75
+ # See also: UnparsedNumericResponseData, ExtensionData, IgnoredResponse
76
+ class UnparsedData < Struct.new(:unparsed_data)
64
77
  ##
65
- # method: raw_data
66
- # :call-seq: raw_data -> string
78
+ # method: unparsed_data
79
+ # :call-seq: unparsed_data -> string
67
80
  #
68
- # The raw response data.
81
+ # The unparsed data
82
+ end
83
+
84
+ # **Note:** This represents an intentionally _unstable_ API. Where
85
+ # instances of this class are returned, future releases may return a
86
+ # different (incompatible) object <em>without deprecation or warning</em>.
87
+ #
88
+ # Net::IMAP::UnparsedNumericResponseData represents data for unhandled
89
+ # response types with a numeric prefix. See the documentation for #number.
90
+ #
91
+ # See also: UnparsedData, ExtensionData, IgnoredResponse
92
+ class UnparsedNumericResponseData < Struct.new(:number, :unparsed_data)
93
+ ##
94
+ # method: number
95
+ # :call-seq: number -> integer
96
+ #
97
+ # Returns a numeric response data prefix, when available.
98
+ #
99
+ # Many response types are prefixed with a non-negative #number. For
100
+ # message data, #number may represent a sequence number or a UID. For
101
+ # mailbox data, #number may represent a message count.
102
+
103
+ ##
104
+ # method: unparsed_data
105
+ # :call-seq: unparsed_data -> string
106
+ #
107
+ # The unparsed data, not including #number or UntaggedResponse#name.
108
+ end
109
+
110
+ # **Note:** This represents an intentionally _unstable_ API. Where
111
+ # instances of this class are returned, future releases may return a
112
+ # different (incompatible) object <em>without deprecation or warning</em>.
113
+ #
114
+ # Net::IMAP::ExtensionData represents data that is parsable according to the
115
+ # forward-compatible extension syntax in RFC3501, RFC4466, or RFC9051, but
116
+ # isn't directly known or understood by Net::IMAP yet.
117
+ #
118
+ # See also: UnparsedData, UnparsedNumericResponseData, IgnoredResponse
119
+ class ExtensionData < Struct.new(:data)
120
+ ##
121
+ # method: data
122
+ # :call-seq: data -> string
123
+ #
124
+ # The parsed extension data.
69
125
  end
70
126
 
71
127
  # Net::IMAP::TaggedResponse represents tagged responses.
@@ -108,6 +164,9 @@ module Net
108
164
  # UntaggedResponse#data when the response type is a "condition" ("OK", "NO",
109
165
  # "BAD", "PREAUTH", or "BYE").
110
166
  class ResponseText < Struct.new(:code, :text)
167
+ # Used to avoid an allocation when ResponseText is empty
168
+ EMPTY = new(nil, "").freeze
169
+
111
170
  ##
112
171
  # method: code
113
172
  # :call-seq: code -> ResponseCode or nil
@@ -197,6 +256,10 @@ module Net
197
256
  # * +ALREADYEXISTS+
198
257
  # * +NONEXISTENT+
199
258
  #
259
+ # Other supported \IMAP extension response codes:
260
+ # * +OBJECTID+ {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html#section-7]
261
+ # * +MAILBOXID+, #data will be a string
262
+ #
200
263
  class ResponseCode < Struct.new(:name, :data)
201
264
  ##
202
265
  # method: name
@@ -448,210 +511,6 @@ module Net
448
511
  # "UIDVALIDITY", "UNSEEN". Each value is a number.
449
512
  end
450
513
 
451
- # Net::IMAP::FetchData represents the contents of a FETCH response.
452
- #
453
- # Net::IMAP#fetch and Net::IMAP#uid_fetch both return an array of
454
- # FetchData objects.
455
- #
456
- # === Fetch attributes
457
- #
458
- #--
459
- # TODO: merge branch with accessor methods for each type of attr. Then
460
- # move nearly all of the +attr+ documentation onto the appropriate
461
- # accessor methods.
462
- #++
463
- #
464
- # Each key of the #attr hash is the data item name for the fetched value.
465
- # Each data item represents a message attribute, part of one, or an
466
- # interpretation of one. #seqno is not a message attribute. Most message
467
- # attributes are static and must never change for a given <tt>[server,
468
- # account, mailbox, UIDVALIDITY, UID]</tt> tuple. A few message attributes
469
- # can be dynamically changed, e.g. using the {STORE
470
- # command}[rdoc-ref:Net::IMAP#store].
471
- #
472
- # See {[IMAP4rev1] §7.4.2}[https://www.rfc-editor.org/rfc/rfc3501.html#section-7.4.2]
473
- # and {[IMAP4rev2] §7.5.2}[https://www.rfc-editor.org/rfc/rfc9051.html#section-7.5.2]
474
- # for full description of the standard fetch response data items, and
475
- # Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs.
476
- #
477
- # ==== Static fetch data items
478
- #
479
- # The static data items
480
- # defined by [IMAP4rev1[https://www.rfc-editor.org/rfc/rfc3501.html]] are:
481
- #
482
- # [<tt>"UID"</tt>]
483
- # A number expressing the unique identifier of the message.
484
- #
485
- # [<tt>"BODY[]"</tt>, <tt>"BODY[]<#{offset}>"</tt>]
486
- # The [RFC5322[https://tools.ietf.org/html/rfc5322]] expression of the
487
- # entire message, as a string.
488
- #
489
- # If +offset+ is specified, this returned string is a substring of the
490
- # entire contents, starting at that origin octet. This means that
491
- # <tt>BODY[]<0></tt> MAY be truncated, but <tt>BODY[]</tt> is NEVER
492
- # truncated.
493
- #
494
- # <em>Messages can be parsed using the "mail" gem.</em>
495
- #
496
- # [Note]
497
- # When fetching <tt>BODY.PEEK[#{specifier}]</tt>, the data will be
498
- # returned in <tt>BODY[#{specifier}]</tt>, without the +PEEK+. This is
499
- # true for all of the <tt>BODY[...]</tt> attribute forms.
500
- #
501
- # [<tt>"BODY[HEADER]"</tt>, <tt>"BODY[HEADER]<#{offset}>"</tt>]
502
- # The [RFC5322[https://tools.ietf.org/html/rfc5322]] header of the
503
- # message.
504
- #
505
- # <em>Message headers can be parsed using the "mail" gem.</em>
506
- #
507
- # [<tt>"BODY[HEADER.FIELDS (#{fields.join(" ")})]"</tt>,]
508
- # [<tt>"BODY[HEADER.FIELDS (#{fields.join(" ")})]<#{offset}>"</tt>]
509
- # When field names are given, the subset contains only the header fields
510
- # that matches one of the names in the list. The field names are based
511
- # on what was requested, not on what was returned.
512
- #
513
- # [<tt>"BODY[HEADER.FIELDS.NOT (#{fields.join(" ")})]"</tt>,]
514
- # [<tt>"BODY[HEADER.FIELDS.NOT (#{fields.join(" ")})]<#{offset}>"</tt>]
515
- # When the <tt>HEADER.FIELDS.NOT</tt> is used, the subset is all of the
516
- # fields that <em>do not</em> match any names in the list.
517
- #
518
- # [<tt>"BODY[TEXT]"</tt>, <tt>"BODY[TEXT]<#{offset}>"</tt>]
519
- # The text body of the message, omitting
520
- # the [RFC5322[https://tools.ietf.org/html/rfc5322]] header.
521
- #
522
- # [<tt>"BODY[#{part}]"</tt>, <tt>"BODY[#{part}]<#{offset}>"</tt>]
523
- # The text of a particular body section, if it was fetched.
524
- #
525
- # Multiple part specifiers will be joined with <tt>"."</tt>. Numeric
526
- # part specifiers refer to the MIME part number, counting up from +1+.
527
- # Messages that don't use MIME, or MIME messages that are not multipart
528
- # and don't hold an encapsulated message, only have a part +1+.
529
- #
530
- # 8-bit textual data is permitted if
531
- # a [CHARSET[https://tools.ietf.org/html/rfc2978]] identifier is part of
532
- # the body parameter parenthesized list for this section. See
533
- # BodyTypeBasic.
534
- #
535
- # MESSAGE/RFC822 or MESSAGE/GLOBAL message, or a subset of the header, if
536
- # it was fetched.
537
- #
538
- # [<tt>"BODY[#{part}.HEADER]"</tt>,]
539
- # [<tt>"BODY[#{part}.HEADER]<#{offset}>"</tt>,]
540
- # [<tt>"BODY[#{part}.HEADER.FIELDS.NOT (#{fields.join(" ")})]"</tt>,]
541
- # [<tt>"BODY[#{part}.HEADER.FIELDS.NOT (#{fields.join(" ")})]<#{offset}>"</tt>,]
542
- # [<tt>"BODY[#{part}.TEXT]"</tt>,]
543
- # [<tt>"BODY[#{part}.TEXT]<#{offset}>"</tt>,]
544
- # [<tt>"BODY[#{part}.MIME]"</tt>,]
545
- # [<tt>"BODY[#{part}.MIME]<#{offset}>"</tt>]
546
- # +HEADER+, <tt>HEADER.FIELDS</tt>, <tt>HEADER.FIELDS.NOT</tt>, and
547
- # <tt>TEXT</tt> can be prefixed by numeric part specifiers, if it refers
548
- # to a part of type <tt>message/rfc822</tt> or <tt>message/global</tt>.
549
- #
550
- # +MIME+ refers to the [MIME-IMB[https://tools.ietf.org/html/rfc2045]]
551
- # header for this part.
552
- #
553
- # [<tt>"BODY"</tt>]
554
- # A form of +BODYSTRUCTURE+, without any extension data.
555
- #
556
- # [<tt>"BODYSTRUCTURE"</tt>]
557
- # Returns a BodyStructure object that describes
558
- # the [MIME-IMB[https://tools.ietf.org/html/rfc2045]] body structure of
559
- # a message, if it was fetched.
560
- #
561
- # [<tt>"ENVELOPE"</tt>]
562
- # An Envelope object that describes the envelope structure of a message.
563
- # See the documentation for Envelope for a description of the envelope
564
- # structure attributes.
565
- #
566
- # [<tt>"INTERNALDATE"</tt>]
567
- # The internal date and time of the message on the server. This is not
568
- # the date and time in
569
- # the [RFC5322[https://tools.ietf.org/html/rfc5322]] header, but rather
570
- # a date and time which reflects when the message was received.
571
- #
572
- # [<tt>"RFC822.SIZE"</tt>]
573
- # A number expressing the [RFC5322[https://tools.ietf.org/html/rfc5322]]
574
- # size of the message.
575
- #
576
- # [Note]
577
- # \IMAP was originally developed for the older RFC-822 standard, and
578
- # as a consequence several fetch items in \IMAP incorporate "RFC822"
579
- # in their name. With the exception of +RFC822.SIZE+, there are more
580
- # modern replacements; for example, the modern version of
581
- # +RFC822.HEADER+ is <tt>BODY.PEEK[HEADER]</tt>. In all cases,
582
- # "RFC822" should be interpreted as a reference to the
583
- # updated [RFC5322[https://tools.ietf.org/html/rfc5322]] standard.
584
- #
585
- # [<tt>"RFC822"</tt>]
586
- # Semantically equivalent to <tt>BODY[]</tt>.
587
- # [<tt>"RFC822.HEADER"</tt>]
588
- # Semantically equivalent to <tt>BODY[HEADER]</tt>.
589
- # [<tt>"RFC822.TEXT"</tt>]
590
- # Semantically equivalent to <tt>BODY[TEXT]</tt>.
591
- #
592
- # [Note:]
593
- # >>>
594
- # Additional static fields are defined in \IMAP extensions and
595
- # [IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051.html]], but
596
- # Net::IMAP can't parse them yet.
597
- #
598
- #--
599
- # <tt>"BINARY[#{section_binary}]<#{offset}>"</tt>:: TODO...
600
- # <tt>"BINARY.SIZE[#{sectionbinary}]"</tt>:: TODO...
601
- # <tt>"EMAILID"</tt>:: TODO...
602
- # <tt>"THREADID"</tt>:: TODO...
603
- # <tt>"SAVEDATE"</tt>:: TODO...
604
- #++
605
- #
606
- # ==== Dynamic message attributes
607
- # The only dynamic item defined
608
- # by [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501.html]] is:
609
- # [<tt>"FLAGS"</tt>]
610
- # An array of flags that are set for this message. System flags are
611
- # symbols that have been capitalized by String#capitalize. Keyword
612
- # flags are strings and their case is not changed.
613
- #
614
- # \IMAP extensions define new dynamic fields, e.g.:
615
- #
616
- # [<tt>"MODSEQ"</tt>]
617
- # The modification sequence number associated with this IMAP message.
618
- #
619
- # Requires the [CONDSTORE[https://tools.ietf.org/html/rfc7162]]
620
- # server {capability}[rdoc-ref:Net::IMAP#capability].
621
- #
622
- # [Note:]
623
- # >>>
624
- # Additional dynamic fields are defined in \IMAP extensions, but
625
- # Net::IMAP can't parse them yet.
626
- #
627
- #--
628
- # <tt>"ANNOTATE"</tt>:: TODO...
629
- # <tt>"PREVIEW"</tt>:: TODO...
630
- #++
631
- #
632
- class FetchData < Struct.new(:seqno, :attr)
633
- ##
634
- # method: seqno
635
- # :call-seq: seqno -> Integer
636
- #
637
- # The message sequence number.
638
- #
639
- # [Note]
640
- # This is never the unique identifier (UID), not even for the
641
- # Net::IMAP#uid_fetch result. If it was returned, the UID is available
642
- # from <tt>attr["UID"]</tt>.
643
-
644
- ##
645
- # method: attr
646
- # :call-seq: attr -> hash
647
- #
648
- # A hash. Each key is specifies a message attribute, and the value is the
649
- # corresponding data item.
650
- #
651
- # See rdoc-ref:FetchData@Fetch+attributes for descriptions of possible
652
- # values.
653
- end
654
-
655
514
  # Net::IMAP::Envelope represents envelope structures of messages.
656
515
  #
657
516
  # [Note]
@@ -665,6 +524,7 @@ module Net
665
524
  # for full description of the envelope fields, and
666
525
  # Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs.
667
526
  #
527
+ # Returned by FetchData#envelope
668
528
  class Envelope < Struct.new(:date, :subject, :from, :sender, :reply_to,
669
529
  :to, :cc, :bcc, :in_reply_to, :message_id)
670
530
  ##
@@ -891,13 +751,6 @@ module Net
891
751
  # should use BodyTypeBasic.
892
752
  # BodyTypeMultipart:: for <tt>multipart/*</tt> parts
893
753
  #
894
- # ==== Deprecated BodyStructure classes
895
- # The following classes represent invalid server responses or parser bugs:
896
- # BodyTypeExtension:: parser bug: used for <tt>message/*</tt> where
897
- # BodyTypeBasic should have been used.
898
- # BodyTypeAttachment:: server bug: some servers sometimes return the
899
- # "Content-Disposition: attachment" data where the
900
- # entire body structure for a message part is expected.
901
754
  module BodyStructure
902
755
  end
903
756
 
@@ -914,6 +767,7 @@ module Net
914
767
  :param, :content_id,
915
768
  :description, :encoding, :size,
916
769
  :md5, :disposition, :language,
770
+ :location,
917
771
  :extension)
918
772
  include BodyStructure
919
773
 
@@ -1049,6 +903,7 @@ module Net
1049
903
  :description, :encoding, :size,
1050
904
  :lines,
1051
905
  :md5, :disposition, :language,
906
+ :location,
1052
907
  :extension)
1053
908
  include BodyStructure
1054
909
 
@@ -1088,12 +943,12 @@ module Net
1088
943
  # * description[rdoc-ref:BodyTypeBasic#description]
1089
944
  # * encoding[rdoc-ref:BodyTypeBasic#encoding]
1090
945
  # * size[rdoc-ref:BodyTypeBasic#size]
1091
- #
1092
946
  class BodyTypeMessage < Struct.new(:media_type, :subtype,
1093
947
  :param, :content_id,
1094
948
  :description, :encoding, :size,
1095
949
  :envelope, :body, :lines,
1096
950
  :md5, :disposition, :language,
951
+ :location,
1097
952
  :extension)
1098
953
  include BodyStructure
1099
954
 
@@ -1126,36 +981,41 @@ module Net
1126
981
  end
1127
982
  end
1128
983
 
1129
- # === WARNING
1130
- # BodyTypeAttachment represents a <tt>body-fld-dsp</tt> that is
1131
- # incorrectly in a position where the IMAP4rev1 grammar expects a nested
1132
- # +body+ structure.
984
+ # BodyTypeAttachment is not used and will be removed in an upcoming release.
1133
985
  #
1134
- # >>>
1135
- # \IMAP body structures are parenthesized lists and assign their fields
1136
- # positionally, so missing fields change the intepretation of all
1137
- # following fields. Buggy \IMAP servers sometimes leave fields missing
1138
- # rather than empty, which inevitably confuses parsers.
1139
- # BodyTypeAttachment was an attempt to parse a common type of buggy body
1140
- # structure without crashing.
1141
- #
1142
- # Currently, when Net::IMAP::ResponseParser sees "attachment" as the first
1143
- # entry in a <tt>body-type-1part</tt>, which is where the MIME type should
1144
- # be, it uses BodyTypeAttachment to capture the rest. "attachment" is not
1145
- # a valid MIME type, but _is_ a common <tt>Content-Disposition</tt>. What
1146
- # might have happened was that buggy server could not parse the message
1147
- # (which might have been incorrectly formatted) and output a
1148
- # <tt>body-type-dsp</tt> where a Net::IMAP::ResponseParser expected to see
1149
- # a +body+.
1150
- #
1151
- # A future release will replace this, probably with a ContentDisposition
1152
- # nested inside another body structure object, maybe BodyTypeBasic, or
1153
- # perhaps a new body structure class that represents any unparsable body
1154
- # structure.
986
+ # === Bug Analysis
987
+ #
988
+ # \IMAP body structures are parenthesized lists and assign their fields
989
+ # positionally, so missing fields change the intepretation of all
990
+ # following fields. Additionally, different body types have a different
991
+ # number of required fields, followed by optional "extension" fields.
992
+ #
993
+ # BodyTypeAttachment was previously returned when a "message/rfc822" part,
994
+ # which should be sent as <tt>body-type-msg</tt> with ten required fields,
995
+ # was actually sent as a <tt>body-type-basic</tt> with _seven_ required
996
+ # fields.
997
+ #
998
+ # basic => type, subtype, param, id, desc, enc, octets, md5=nil, dsp=nil, lang=nil, loc=nil, *ext
999
+ # msg => type, subtype, param, id, desc, enc, octets, envelope, body, lines, md5=nil, ...
1000
+ #
1001
+ # Normally, +envelope+ and +md5+ are incompatible, but Net::IMAP leniently
1002
+ # allowed buggy servers to send +NIL+ for +envelope+. As a result, when a
1003
+ # server sent a <tt>message/rfc822</tt> part with +NIL+ for +md5+ and a
1004
+ # non-<tt>NIL</tt> +dsp+, Net::IMAP mis-interpreted the
1005
+ # <tt>Content-Disposition</tt> as if it were a strange body type. In all
1006
+ # reported cases, the <tt>Content-Disposition</tt> was "attachment", so
1007
+ # BodyTypeAttachment was created as the workaround.
1008
+ #
1009
+ # === Current behavior
1010
+ #
1011
+ # When interpreted strictly, +envelope+ and +md5+ are incompatible. So the
1012
+ # current parsing algorithm peeks ahead after it has recieved the seventh
1013
+ # body field. If the next token is not the start of an +envelope+, we assume
1014
+ # the server has incorrectly sent us a <tt>body-type-basic</tt> and return
1015
+ # BodyTypeBasic. As a result, what was previously BodyTypeMessage#body =>
1016
+ # BodyTypeAttachment is now BodyTypeBasic#disposition => ContentDisposition.
1155
1017
  #
1156
1018
  class BodyTypeAttachment < Struct.new(:dsp_type, :_unused_, :param)
1157
- include BodyStructure
1158
-
1159
1019
  # *invalid for BodyTypeAttachment*
1160
1020
  def media_type
1161
1021
  warn(<<~WARN, uplevel: 1)
@@ -1190,11 +1050,14 @@ module Net
1190
1050
  end
1191
1051
  end
1192
1052
 
1053
+ deprecate_constant :BodyTypeAttachment
1054
+
1193
1055
  # Net::IMAP::BodyTypeMultipart represents body structures of messages and
1194
1056
  # message parts, when <tt>Content-Type</tt> is <tt>multipart/*</tt>.
1195
1057
  class BodyTypeMultipart < Struct.new(:media_type, :subtype,
1196
1058
  :parts,
1197
1059
  :param, :disposition, :language,
1060
+ :location,
1198
1061
  :extension)
1199
1062
  include BodyStructure
1200
1063
 
@@ -1265,23 +1128,24 @@ module Net
1265
1128
  end
1266
1129
  end
1267
1130
 
1268
- # === WARNING:
1131
+ # === Obsolete
1132
+ # BodyTypeExtension is not used and will be removed in an upcoming release.
1133
+ #
1269
1134
  # >>>
1270
- # BodyTypeExtension is (incorrectly) used for <tt>message/*</tt> parts
1135
+ # BodyTypeExtension was (incorrectly) used for <tt>message/*</tt> parts
1271
1136
  # (besides <tt>message/rfc822</tt>, which correctly uses BodyTypeMessage).
1272
1137
  #
1273
- # A future release will replace this class with:
1274
- # * BodyTypeMessage for <tt>message/rfc822</tt> and <tt>message/global</tt>
1275
- # * BodyTypeBasic for any other <tt>message/*</tt>
1138
+ # Net::IMAP now (correctly) parses all message types (other than
1139
+ # <tt>message/rfc822</tt> or <tt>message/global</tt>) as BodyTypeBasic.
1276
1140
  class BodyTypeExtension < Struct.new(:media_type, :subtype,
1277
1141
  :params, :content_id,
1278
1142
  :description, :encoding, :size)
1279
- include BodyStructure
1280
-
1281
1143
  def multipart?
1282
1144
  return false
1283
1145
  end
1284
1146
  end
1285
1147
 
1148
+ deprecate_constant :BodyTypeExtension
1149
+
1286
1150
  end
1287
1151
  end