net-imap 0.3.7 → 0.4.9
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/.github/workflows/pages.yml +46 -0
- data/.github/workflows/test.yml +5 -12
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.md +15 -4
- data/Rakefile +0 -7
- data/docs/styles.css +0 -12
- data/lib/net/imap/authenticators.rb +26 -57
- data/lib/net/imap/command_data.rb +13 -6
- data/lib/net/imap/data_encoding.rb +14 -2
- data/lib/net/imap/deprecated_client_options.rb +139 -0
- data/lib/net/imap/errors.rb +20 -0
- data/lib/net/imap/fetch_data.rb +518 -0
- data/lib/net/imap/response_data.rb +178 -255
- data/lib/net/imap/response_parser/parser_utils.rb +240 -0
- data/lib/net/imap/response_parser.rb +1722 -1193
- data/lib/net/imap/sasl/anonymous_authenticator.rb +69 -0
- data/lib/net/imap/sasl/authentication_exchange.rb +107 -0
- data/lib/net/imap/sasl/authenticators.rb +118 -0
- data/lib/net/imap/sasl/client_adapter.rb +72 -0
- data/lib/net/imap/{authenticators/cram_md5.rb → sasl/cram_md5_authenticator.rb} +21 -11
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +180 -0
- data/lib/net/imap/sasl/external_authenticator.rb +83 -0
- data/lib/net/imap/sasl/gs2_header.rb +80 -0
- data/lib/net/imap/{authenticators/login.rb → sasl/login_authenticator.rb} +25 -16
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +199 -0
- data/lib/net/imap/sasl/plain_authenticator.rb +101 -0
- data/lib/net/imap/sasl/protocol_adapters.rb +45 -0
- data/lib/net/imap/sasl/scram_algorithm.rb +58 -0
- data/lib/net/imap/sasl/scram_authenticator.rb +287 -0
- data/lib/net/imap/sasl/stringprep.rb +6 -66
- data/lib/net/imap/sasl/xoauth2_authenticator.rb +106 -0
- data/lib/net/imap/sasl.rb +144 -43
- data/lib/net/imap/sasl_adapter.rb +21 -0
- data/lib/net/imap/search_result.rb +150 -0
- data/lib/net/imap/sequence_set.rb +1414 -0
- data/lib/net/imap/stringprep/nameprep.rb +70 -0
- data/lib/net/imap/stringprep/saslprep.rb +69 -0
- data/lib/net/imap/stringprep/saslprep_tables.rb +96 -0
- data/lib/net/imap/stringprep/tables.rb +146 -0
- data/lib/net/imap/stringprep/trace.rb +85 -0
- data/lib/net/imap/stringprep.rb +159 -0
- data/lib/net/imap.rb +1213 -636
- data/net-imap.gemspec +5 -3
- data/rakelib/benchmarks.rake +91 -0
- data/rakelib/saslprep.rake +4 -4
- data/rakelib/string_prep_tables_generator.rb +82 -60
- metadata +34 -14
- data/benchmarks/stringprep.yml +0 -65
- data/benchmarks/table-regexps.yml +0 -39
- data/lib/net/imap/authenticators/digest_md5.rb +0 -115
- data/lib/net/imap/authenticators/plain.rb +0 -41
- data/lib/net/imap/authenticators/xoauth2.rb +0 -20
- data/lib/net/imap/sasl/saslprep.rb +0 -55
- data/lib/net/imap/sasl/saslprep_tables.rb +0 -98
- data/lib/net/imap/sasl/stringprep_tables.rb +0 -153
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Net
|
4
4
|
class IMAP < Protocol
|
5
|
+
autoload :FetchData, "#{__dir__}/fetch_data"
|
6
|
+
autoload :SearchResult, "#{__dir__}/search_result"
|
7
|
+
autoload :SequenceSet, "#{__dir__}/sequence_set"
|
5
8
|
|
6
9
|
# Net::IMAP::ContinuationRequest represents command continuation requests.
|
7
10
|
#
|
@@ -55,17 +58,71 @@ module Net
|
|
55
58
|
|
56
59
|
# Net::IMAP::IgnoredResponse represents intentionally ignored responses.
|
57
60
|
#
|
58
|
-
# This includes untagged response "NOOP" sent by eg. Zimbra to avoid
|
59
|
-
# clients to close the connection.
|
61
|
+
# This includes untagged response "NOOP" sent by eg. Zimbra to avoid
|
62
|
+
# some clients to close the connection.
|
60
63
|
#
|
61
64
|
# It matches no IMAP standard.
|
65
|
+
class IgnoredResponse < UntaggedResponse
|
66
|
+
end
|
67
|
+
|
68
|
+
# **Note:** This represents an intentionally _unstable_ API. Where
|
69
|
+
# instances of this class are returned, future releases may return a
|
70
|
+
# different (incompatible) object <em>without deprecation or warning</em>.
|
71
|
+
#
|
72
|
+
# Net::IMAP::UnparsedData represents data for unknown response types or
|
73
|
+
# unknown extensions to response types without a well-defined extension
|
74
|
+
# grammar.
|
62
75
|
#
|
63
|
-
|
76
|
+
# See also: UnparsedNumericResponseData, ExtensionData, IgnoredResponse
|
77
|
+
class UnparsedData < Struct.new(:unparsed_data)
|
64
78
|
##
|
65
|
-
# method:
|
66
|
-
# :call-seq:
|
79
|
+
# method: unparsed_data
|
80
|
+
# :call-seq: unparsed_data -> string
|
67
81
|
#
|
68
|
-
# The
|
82
|
+
# The unparsed data
|
83
|
+
end
|
84
|
+
|
85
|
+
# **Note:** This represents an intentionally _unstable_ API. Where
|
86
|
+
# instances of this class are returned, future releases may return a
|
87
|
+
# different (incompatible) object <em>without deprecation or warning</em>.
|
88
|
+
#
|
89
|
+
# Net::IMAP::UnparsedNumericResponseData represents data for unhandled
|
90
|
+
# response types with a numeric prefix. See the documentation for #number.
|
91
|
+
#
|
92
|
+
# See also: UnparsedData, ExtensionData, IgnoredResponse
|
93
|
+
class UnparsedNumericResponseData < Struct.new(:number, :unparsed_data)
|
94
|
+
##
|
95
|
+
# method: number
|
96
|
+
# :call-seq: number -> integer
|
97
|
+
#
|
98
|
+
# Returns a numeric response data prefix, when available.
|
99
|
+
#
|
100
|
+
# Many response types are prefixed with a non-negative #number. For
|
101
|
+
# message data, #number may represent a sequence number or a UID. For
|
102
|
+
# mailbox data, #number may represent a message count.
|
103
|
+
|
104
|
+
##
|
105
|
+
# method: unparsed_data
|
106
|
+
# :call-seq: unparsed_data -> string
|
107
|
+
#
|
108
|
+
# The unparsed data, not including #number or UntaggedResponse#name.
|
109
|
+
end
|
110
|
+
|
111
|
+
# **Note:** This represents an intentionally _unstable_ API. Where
|
112
|
+
# instances of this class are returned, future releases may return a
|
113
|
+
# different (incompatible) object <em>without deprecation or warning</em>.
|
114
|
+
#
|
115
|
+
# Net::IMAP::ExtensionData represents data that is parsable according to the
|
116
|
+
# forward-compatible extension syntax in RFC3501, RFC4466, or RFC9051, but
|
117
|
+
# isn't directly known or understood by Net::IMAP yet.
|
118
|
+
#
|
119
|
+
# See also: UnparsedData, UnparsedNumericResponseData, IgnoredResponse
|
120
|
+
class ExtensionData < Struct.new(:data)
|
121
|
+
##
|
122
|
+
# method: data
|
123
|
+
# :call-seq: data -> string
|
124
|
+
#
|
125
|
+
# The parsed extension data.
|
69
126
|
end
|
70
127
|
|
71
128
|
# Net::IMAP::TaggedResponse represents tagged responses.
|
@@ -108,6 +165,9 @@ module Net
|
|
108
165
|
# UntaggedResponse#data when the response type is a "condition" ("OK", "NO",
|
109
166
|
# "BAD", "PREAUTH", or "BYE").
|
110
167
|
class ResponseText < Struct.new(:code, :text)
|
168
|
+
# Used to avoid an allocation when ResponseText is empty
|
169
|
+
EMPTY = new(nil, "").freeze
|
170
|
+
|
111
171
|
##
|
112
172
|
# method: code
|
113
173
|
# :call-seq: code -> ResponseCode or nil
|
@@ -146,6 +206,7 @@ module Net
|
|
146
206
|
# defines them. When unknown response code data is encountered, #data
|
147
207
|
# will return an unparsed string.
|
148
208
|
#
|
209
|
+
# ==== +IMAP4rev1+ Response Codes
|
149
210
|
# See [IMAP4rev1[https://www.rfc-editor.org/rfc/rfc3501]] {§7.1, "Server
|
150
211
|
# Responses - Status
|
151
212
|
# Responses"}[https://www.rfc-editor.org/rfc/rfc3501#section-7.1] for full
|
@@ -169,13 +230,32 @@ module Net
|
|
169
230
|
# {§2.3.1.1, "Unique Identifier (UID) Message
|
170
231
|
# Attribute}[https://www.rfc-editor.org/rfc/rfc3501#section-2.3.1.1].
|
171
232
|
# * +UIDVALIDITY+, #data is an Integer, the UID validity value of the
|
172
|
-
# mailbox See [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501]],
|
233
|
+
# mailbox. See [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501]],
|
173
234
|
# {§2.3.1.1, "Unique Identifier (UID) Message
|
174
235
|
# Attribute}[https://www.rfc-editor.org/rfc/rfc3501#section-2.3.1.1].
|
175
236
|
# * +UNSEEN+, #data is an Integer, the number of messages which do not have
|
176
237
|
# the <tt>\Seen</tt> flag set.
|
177
|
-
#
|
178
|
-
#
|
238
|
+
# <em>DEPRECATED by IMAP4rev2.</em>
|
239
|
+
#
|
240
|
+
# ==== +BINARY+ extension
|
241
|
+
# See {[RFC3516]}[https://www.rfc-editor.org/rfc/rfc3516].
|
242
|
+
# * +UNKNOWN-CTE+, with a tagged +NO+ response, when the server does not
|
243
|
+
# known how to decode a CTE (content-transfer-encoding). #data is +nil+.
|
244
|
+
# See IMAP#fetch.
|
245
|
+
#
|
246
|
+
# ==== +UIDPLUS+ extension
|
247
|
+
# See {[RFC4315 §3]}[https://www.rfc-editor.org/rfc/rfc4315#section-3].
|
248
|
+
# * +APPENDUID+, #data is UIDPlusData. See IMAP#append.
|
249
|
+
# * +COPYUID+, #data is UIDPlusData. See IMAP#copy.
|
250
|
+
# * +UIDNOTSTICKY+, #data is +nil+. See IMAP#select.
|
251
|
+
#
|
252
|
+
# ==== +SEARCHRES+ extension
|
253
|
+
# See {[RFC5182]}[https://www.rfc-editor.org/rfc/rfc5182].
|
254
|
+
# * +NOTSAVED+, with a tagged +NO+ response, when the search result variable
|
255
|
+
# is not saved. #data is +nil+.
|
256
|
+
#
|
257
|
+
# ==== +RFC5530+ Response Codes
|
258
|
+
# See {[RFC5530]}[https://www.rfc-editor.org/rfc/rfc5530], "IMAP Response
|
179
259
|
# Codes" for the definition of the following response codes, which are all
|
180
260
|
# machine-readable annotations for the human-readable ResponseText#text, and
|
181
261
|
# have +nil+ #data of their own:
|
@@ -197,6 +277,35 @@ module Net
|
|
197
277
|
# * +ALREADYEXISTS+
|
198
278
|
# * +NONEXISTENT+
|
199
279
|
#
|
280
|
+
# ==== +QRESYNC+ extension
|
281
|
+
# See {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
282
|
+
# * +CLOSED+, returned when the currently selected mailbox is closed
|
283
|
+
# implicity by selecting or examining another mailbox. #data is +nil+.
|
284
|
+
#
|
285
|
+
# ==== +IMAP4rev2+ Response Codes
|
286
|
+
# See {[RFC9051]}[https://www.rfc-editor.org/rfc/rfc9051] {§7.1, "Server
|
287
|
+
# Responses - Status
|
288
|
+
# Responses"}[https://www.rfc-editor.org/rfc/rfc9051#section-7.1] for full
|
289
|
+
# descriptions of IMAP4rev2 response codes. IMAP4rev2 includes all of the
|
290
|
+
# response codes listed above (except "UNSEEN") and adds the following:
|
291
|
+
# * +HASCHILDREN+, with a tagged +NO+ response, when a mailbox delete failed
|
292
|
+
# because the server doesn't allow deletion of mailboxes with children.
|
293
|
+
# #data is +nil+.
|
294
|
+
#
|
295
|
+
# ==== +CONDSTORE+ extension
|
296
|
+
# See {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
297
|
+
# * +NOMODSEQ+, when selecting a mailbox that does not support
|
298
|
+
# mod-sequences. #data is +nil+. See IMAP#select.
|
299
|
+
# * +HIGHESTMODSEQ+, #data is an Integer, the highest mod-sequence value of
|
300
|
+
# all messages in the mailbox. See IMAP#select.
|
301
|
+
# * +MODIFIED+, #data is a SequenceSet, the messages that have been modified
|
302
|
+
# since the +UNCHANGEDSINCE+ mod-sequence given to +STORE+ or <tt>UID
|
303
|
+
# STORE</tt>.
|
304
|
+
#
|
305
|
+
# ==== +OBJECTID+ extension
|
306
|
+
# See {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html].
|
307
|
+
# * +MAILBOXID+, #data is a string
|
308
|
+
#
|
200
309
|
class ResponseCode < Struct.new(:name, :data)
|
201
310
|
##
|
202
311
|
# method: name
|
@@ -448,210 +557,6 @@ module Net
|
|
448
557
|
# "UIDVALIDITY", "UNSEEN". Each value is a number.
|
449
558
|
end
|
450
559
|
|
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
560
|
# Net::IMAP::Envelope represents envelope structures of messages.
|
656
561
|
#
|
657
562
|
# [Note]
|
@@ -665,6 +570,7 @@ module Net
|
|
665
570
|
# for full description of the envelope fields, and
|
666
571
|
# Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs.
|
667
572
|
#
|
573
|
+
# Returned by FetchData#envelope
|
668
574
|
class Envelope < Struct.new(:date, :subject, :from, :sender, :reply_to,
|
669
575
|
:to, :cc, :bcc, :in_reply_to, :message_id)
|
670
576
|
##
|
@@ -868,6 +774,19 @@ module Net
|
|
868
774
|
#
|
869
775
|
# An array of Net::IMAP::ThreadMember objects for mail items that are
|
870
776
|
# children of this in the thread.
|
777
|
+
|
778
|
+
# Returns a SequenceSet containing #seqno and all #children's seqno,
|
779
|
+
# recursively.
|
780
|
+
def to_sequence_set
|
781
|
+
SequenceSet.new all_seqnos
|
782
|
+
end
|
783
|
+
|
784
|
+
protected
|
785
|
+
|
786
|
+
def all_seqnos(node = self)
|
787
|
+
[node.seqno].concat node.children.flat_map { _1.all_seqnos }
|
788
|
+
end
|
789
|
+
|
871
790
|
end
|
872
791
|
|
873
792
|
# Net::IMAP::BodyStructure is included by all of the structs that can be
|
@@ -891,13 +810,6 @@ module Net
|
|
891
810
|
# should use BodyTypeBasic.
|
892
811
|
# BodyTypeMultipart:: for <tt>multipart/*</tt> parts
|
893
812
|
#
|
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
813
|
module BodyStructure
|
902
814
|
end
|
903
815
|
|
@@ -914,6 +826,7 @@ module Net
|
|
914
826
|
:param, :content_id,
|
915
827
|
:description, :encoding, :size,
|
916
828
|
:md5, :disposition, :language,
|
829
|
+
:location,
|
917
830
|
:extension)
|
918
831
|
include BodyStructure
|
919
832
|
|
@@ -1049,6 +962,7 @@ module Net
|
|
1049
962
|
:description, :encoding, :size,
|
1050
963
|
:lines,
|
1051
964
|
:md5, :disposition, :language,
|
965
|
+
:location,
|
1052
966
|
:extension)
|
1053
967
|
include BodyStructure
|
1054
968
|
|
@@ -1088,12 +1002,12 @@ module Net
|
|
1088
1002
|
# * description[rdoc-ref:BodyTypeBasic#description]
|
1089
1003
|
# * encoding[rdoc-ref:BodyTypeBasic#encoding]
|
1090
1004
|
# * size[rdoc-ref:BodyTypeBasic#size]
|
1091
|
-
#
|
1092
1005
|
class BodyTypeMessage < Struct.new(:media_type, :subtype,
|
1093
1006
|
:param, :content_id,
|
1094
1007
|
:description, :encoding, :size,
|
1095
1008
|
:envelope, :body, :lines,
|
1096
1009
|
:md5, :disposition, :language,
|
1010
|
+
:location,
|
1097
1011
|
:extension)
|
1098
1012
|
include BodyStructure
|
1099
1013
|
|
@@ -1126,36 +1040,41 @@ module Net
|
|
1126
1040
|
end
|
1127
1041
|
end
|
1128
1042
|
|
1129
|
-
#
|
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.
|
1043
|
+
# BodyTypeAttachment is not used and will be removed in an upcoming release.
|
1133
1044
|
#
|
1134
|
-
#
|
1135
|
-
#
|
1136
|
-
#
|
1137
|
-
#
|
1138
|
-
#
|
1139
|
-
#
|
1140
|
-
#
|
1141
|
-
#
|
1142
|
-
#
|
1143
|
-
#
|
1144
|
-
#
|
1145
|
-
#
|
1146
|
-
#
|
1147
|
-
#
|
1148
|
-
#
|
1149
|
-
#
|
1150
|
-
#
|
1151
|
-
#
|
1152
|
-
#
|
1153
|
-
#
|
1154
|
-
#
|
1045
|
+
# === Bug Analysis
|
1046
|
+
#
|
1047
|
+
# \IMAP body structures are parenthesized lists and assign their fields
|
1048
|
+
# positionally, so missing fields change the intepretation of all
|
1049
|
+
# following fields. Additionally, different body types have a different
|
1050
|
+
# number of required fields, followed by optional "extension" fields.
|
1051
|
+
#
|
1052
|
+
# BodyTypeAttachment was previously returned when a "message/rfc822" part,
|
1053
|
+
# which should be sent as <tt>body-type-msg</tt> with ten required fields,
|
1054
|
+
# was actually sent as a <tt>body-type-basic</tt> with _seven_ required
|
1055
|
+
# fields.
|
1056
|
+
#
|
1057
|
+
# basic => type, subtype, param, id, desc, enc, octets, md5=nil, dsp=nil, lang=nil, loc=nil, *ext
|
1058
|
+
# msg => type, subtype, param, id, desc, enc, octets, envelope, body, lines, md5=nil, ...
|
1059
|
+
#
|
1060
|
+
# Normally, +envelope+ and +md5+ are incompatible, but Net::IMAP leniently
|
1061
|
+
# allowed buggy servers to send +NIL+ for +envelope+. As a result, when a
|
1062
|
+
# server sent a <tt>message/rfc822</tt> part with +NIL+ for +md5+ and a
|
1063
|
+
# non-<tt>NIL</tt> +dsp+, Net::IMAP mis-interpreted the
|
1064
|
+
# <tt>Content-Disposition</tt> as if it were a strange body type. In all
|
1065
|
+
# reported cases, the <tt>Content-Disposition</tt> was "attachment", so
|
1066
|
+
# BodyTypeAttachment was created as the workaround.
|
1067
|
+
#
|
1068
|
+
# === Current behavior
|
1069
|
+
#
|
1070
|
+
# When interpreted strictly, +envelope+ and +md5+ are incompatible. So the
|
1071
|
+
# current parsing algorithm peeks ahead after it has recieved the seventh
|
1072
|
+
# body field. If the next token is not the start of an +envelope+, we assume
|
1073
|
+
# the server has incorrectly sent us a <tt>body-type-basic</tt> and return
|
1074
|
+
# BodyTypeBasic. As a result, what was previously BodyTypeMessage#body =>
|
1075
|
+
# BodyTypeAttachment is now BodyTypeBasic#disposition => ContentDisposition.
|
1155
1076
|
#
|
1156
1077
|
class BodyTypeAttachment < Struct.new(:dsp_type, :_unused_, :param)
|
1157
|
-
include BodyStructure
|
1158
|
-
|
1159
1078
|
# *invalid for BodyTypeAttachment*
|
1160
1079
|
def media_type
|
1161
1080
|
warn(<<~WARN, uplevel: 1)
|
@@ -1190,11 +1109,14 @@ module Net
|
|
1190
1109
|
end
|
1191
1110
|
end
|
1192
1111
|
|
1112
|
+
deprecate_constant :BodyTypeAttachment
|
1113
|
+
|
1193
1114
|
# Net::IMAP::BodyTypeMultipart represents body structures of messages and
|
1194
1115
|
# message parts, when <tt>Content-Type</tt> is <tt>multipart/*</tt>.
|
1195
1116
|
class BodyTypeMultipart < Struct.new(:media_type, :subtype,
|
1196
1117
|
:parts,
|
1197
1118
|
:param, :disposition, :language,
|
1119
|
+
:location,
|
1198
1120
|
:extension)
|
1199
1121
|
include BodyStructure
|
1200
1122
|
|
@@ -1265,23 +1187,24 @@ module Net
|
|
1265
1187
|
end
|
1266
1188
|
end
|
1267
1189
|
|
1268
|
-
# ===
|
1190
|
+
# === Obsolete
|
1191
|
+
# BodyTypeExtension is not used and will be removed in an upcoming release.
|
1192
|
+
#
|
1269
1193
|
# >>>
|
1270
|
-
# BodyTypeExtension
|
1194
|
+
# BodyTypeExtension was (incorrectly) used for <tt>message/*</tt> parts
|
1271
1195
|
# (besides <tt>message/rfc822</tt>, which correctly uses BodyTypeMessage).
|
1272
1196
|
#
|
1273
|
-
#
|
1274
|
-
#
|
1275
|
-
# * BodyTypeBasic for any other <tt>message/*</tt>
|
1197
|
+
# Net::IMAP now (correctly) parses all message types (other than
|
1198
|
+
# <tt>message/rfc822</tt> or <tt>message/global</tt>) as BodyTypeBasic.
|
1276
1199
|
class BodyTypeExtension < Struct.new(:media_type, :subtype,
|
1277
1200
|
:params, :content_id,
|
1278
1201
|
:description, :encoding, :size)
|
1279
|
-
include BodyStructure
|
1280
|
-
|
1281
1202
|
def multipart?
|
1282
1203
|
return false
|
1283
1204
|
end
|
1284
1205
|
end
|
1285
1206
|
|
1207
|
+
deprecate_constant :BodyTypeExtension
|
1208
|
+
|
1286
1209
|
end
|
1287
1210
|
end
|