net-imap 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,34 +10,47 @@ module Net
10
10
  # ready to accept the continuation of a command from the client. The
11
11
  # remainder of this response is a line of text.
12
12
  #
13
- # continue_req ::= "+" SPACE (resp_text / base64)
14
- #
15
- # ==== Fields:
16
- #
17
- # data:: Returns the data (Net::IMAP::ResponseText).
18
- #
19
- # raw_data:: Returns the raw data string.
20
13
  class ContinuationRequest < Struct.new(:data, :raw_data)
14
+ ##
15
+ # method: data
16
+ # :call-seq: data -> ResponseText
17
+ #
18
+ # Returns a ResponseText object
19
+
20
+ ##
21
+ # method: raw_data
22
+ # :call-seq: raw_data -> string
23
+ #
24
+ # the raw response data
21
25
  end
22
26
 
23
27
  # Net::IMAP::UntaggedResponse represents untagged responses.
24
28
  #
25
29
  # Data transmitted by the server to the client and status responses
26
30
  # that do not indicate command completion are prefixed with the token
27
- # "*", and are called untagged responses.
28
- #
29
- # response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye /
30
- # mailbox_data / message_data / capability_data)
31
- #
32
- # ==== Fields:
31
+ # <tt>"*"</tt>, and are called untagged responses.
33
32
  #
34
- # name:: Returns the name, such as "FLAGS", "LIST", or "FETCH".
35
- #
36
- # data:: Returns the data such as an array of flag symbols,
37
- # a ((<Net::IMAP::MailboxList>)) object.
38
- #
39
- # raw_data:: Returns the raw data string.
40
33
  class UntaggedResponse < Struct.new(:name, :data, :raw_data)
34
+ ##
35
+ # method: name
36
+ # :call-seq: name -> string
37
+ #
38
+ # The uppercase response name, e.g. "FLAGS", "LIST", "FETCH", etc.
39
+
40
+ ##
41
+ # method: data
42
+ # :call-seq: data -> object or nil
43
+ #
44
+ # The parsed response data, e.g: an array of flag symbols, an array of
45
+ # capabilities strings, a ResponseText object, a MailboxList object, a
46
+ # FetchData object, a Namespaces object, etc. The response #name
47
+ # determines what form the data can take.
48
+
49
+ ##
50
+ # method: raw_data
51
+ # :call-seq: raw_data -> string
52
+ #
53
+ # The raw response data.
41
54
  end
42
55
 
43
56
  # Net::IMAP::IgnoredResponse represents intentionally ignored responses.
@@ -47,10 +60,12 @@ module Net
47
60
  #
48
61
  # It matches no IMAP standard.
49
62
  #
50
- # ==== Fields:
51
- #
52
- # raw_data:: Returns the raw data string.
53
63
  class IgnoredResponse < Struct.new(:raw_data)
64
+ ##
65
+ # method: raw_data
66
+ # :call-seq: raw_data -> string
67
+ #
68
+ # The raw response data.
54
69
  end
55
70
 
56
71
  # Net::IMAP::TaggedResponse represents tagged responses.
@@ -59,76 +74,231 @@ module Net
59
74
  # failure of the operation. It is tagged with the same tag as the
60
75
  # client command which began the operation.
61
76
  #
62
- # response_tagged ::= tag SPACE resp_cond_state CRLF
63
- #
64
- # tag ::= 1*<any ATOM_CHAR except "+">
65
- #
66
- # resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text
67
- #
68
- # ==== Fields:
69
- #
70
- # tag:: Returns the tag.
71
- #
72
- # name:: Returns the name, one of "OK", "NO", or "BAD".
73
- #
74
- # data:: Returns the data. See ((<Net::IMAP::ResponseText>)).
75
- #
76
- # raw_data:: Returns the raw data string.
77
- #
78
77
  class TaggedResponse < Struct.new(:tag, :name, :data, :raw_data)
78
+ ##
79
+ # method: tag
80
+ # :call-seq: tag -> string
81
+ #
82
+ # Returns the command tag
83
+
84
+ ##
85
+ # method: name
86
+ # :call-seq: name -> string
87
+ #
88
+ # Returns the name, one of "OK", "NO", or "BAD".
89
+
90
+ ##
91
+ # method: data
92
+ # :call-seq: data -> ResponseText
93
+ #
94
+ # Returns a ResponseText object
95
+
96
+ ##
97
+ # method: raw_data
98
+ # :call-seq: raw_data -> string
99
+ #
100
+ # The raw response data.
79
101
  end
80
102
 
81
103
  # Net::IMAP::ResponseText represents texts of responses.
82
- # The text may be prefixed by the response code.
83
- #
84
- # resp_text ::= ["[" resp-text-code "]" SP] text
85
- #
86
- # ==== Fields:
87
104
  #
88
- # code:: Returns the response code. See ((<Net::IMAP::ResponseCode>)).
89
- #
90
- # text:: Returns the text.
105
+ # The text may be prefixed by a ResponseCode.
91
106
  #
107
+ # ResponseText is returned from TaggedResponse#data, or from
108
+ # UntaggedResponse#data when the response type is a "condition" ("OK", "NO",
109
+ # "BAD", "PREAUTH", or "BYE").
92
110
  class ResponseText < Struct.new(:code, :text)
111
+ ##
112
+ # method: code
113
+ # :call-seq: code -> ResponseCode or nil
114
+ #
115
+ # Returns a ResponseCode, if the response contains one
116
+
117
+ ##
118
+ # method: text
119
+ # :call-seq: text -> string
120
+ #
121
+ # Returns the response text, not including any response code
93
122
  end
94
123
 
95
- # Net::IMAP::ResponseCode represents response codes.
96
- #
97
- # resp_text_code ::= "ALERT" /
98
- # "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
99
- # capability_data / "PARSE" /
100
- # "PERMANENTFLAGS" SP "("
101
- # [flag_perm *(SP flag_perm)] ")" /
102
- # "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
103
- # "UIDNEXT" SP nz_number / "UIDVALIDITY" SP nz_number /
104
- # "UNSEEN" SP nz_number /
105
- # atom [SP 1*<any TEXT-CHAR except "]">]
106
- #
107
- # ==== Fields:
108
- #
109
- # name:: Returns the name, such as "ALERT", "PERMANENTFLAGS", or "UIDVALIDITY".
110
- #
111
- # data:: Returns the data, if it exists.
124
+ # Net::IMAP::ResponseCode represents response codes. Response codes can be
125
+ # retrieved from ResponseText#code and can be included in any "condition"
126
+ # response: any TaggedResponse and UntaggedResponse when the response type
127
+ # is a "condition" ("OK", "NO", "BAD", "PREAUTH", or "BYE").
128
+ #
129
+ # Some response codes come with additional data which will be parsed by
130
+ # Net::IMAP. Others return +nil+ for #data, but are used as a
131
+ # machine-readable annotation for the human-readable ResponseText#text in
132
+ # the same response. When Net::IMAP does not know how to parse response
133
+ # code text, #data returns the unparsed string.
134
+ #
135
+ # Untagged response code #data is pushed directly onto Net::IMAP#responses,
136
+ # keyed by #name, unless it is removed by the command that generated it.
137
+ # Use Net::IMAP#add_response_handler to view tagged response codes for
138
+ # command methods that do not return their TaggedResponse.
139
+ #
140
+ # \IMAP extensions may define new codes and the data that comes with them.
141
+ # The IANA {IMAP Response
142
+ # Codes}[https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml]
143
+ # registry has links to specifications for all standard response codes.
144
+ # Response codes are backwards compatible: Servers are allowed to send new
145
+ # response codes even if the client has not enabled the extension that
146
+ # defines them. When unknown response code data is encountered, #data
147
+ # will return an unparsed string.
148
+ #
149
+ # See [IMAP4rev1[https://www.rfc-editor.org/rfc/rfc3501]] {§7.1, "Server
150
+ # Responses - Status
151
+ # Responses"}[https://www.rfc-editor.org/rfc/rfc3501#section-7.1] for full
152
+ # definitions of the basic set of IMAP4rev1 response codes:
153
+ # * +ALERT+, the ResponseText#text contains a special alert that MUST be
154
+ # brought to the user's attention.
155
+ # * +BADCHARSET+, #data will be an array of charset strings, or +nil+.
156
+ # * +CAPABILITY+, #data will be an array of capability strings.
157
+ # * +PARSE+, the ResponseText#text presents an error parsing a message's
158
+ # \[RFC5322] or [MIME-IMB] headers.
159
+ # * +PERMANENTFLAGS+, followed by an array of flags. System flags will be
160
+ # symbols, and keyword flags will be strings. See
161
+ # rdoc-ref:Net::IMAP@System+flags
162
+ # * +READ-ONLY+, the mailbox was selected read-only, or changed to read-only
163
+ # * +READ-WRITE+, the mailbox was selected read-write, or changed to
164
+ # read-write
165
+ # * +TRYCREATE+, when #append or #copy fail because the target mailbox
166
+ # doesn't exist.
167
+ # * +UIDNEXT+, #data is an Integer, the next UID value of the mailbox. See
168
+ # [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501]],
169
+ # {§2.3.1.1, "Unique Identifier (UID) Message
170
+ # Attribute}[https://www.rfc-editor.org/rfc/rfc3501#section-2.3.1.1].
171
+ # * +UIDVALIDITY+, #data is an Integer, the UID validity value of the
172
+ # mailbox See [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501]],
173
+ # {§2.3.1.1, "Unique Identifier (UID) Message
174
+ # Attribute}[https://www.rfc-editor.org/rfc/rfc3501#section-2.3.1.1].
175
+ # * +UNSEEN+, #data is an Integer, the number of messages which do not have
176
+ # the <tt>\Seen</tt> flag set.
177
+ #
178
+ # See RFC5530[https://www.rfc-editor.org/rfc/rfc5530], "IMAP Response
179
+ # Codes" for the definition of the following response codes, which are all
180
+ # machine-readable annotations for the human-readable ResponseText#text, and
181
+ # have +nil+ #data of their own:
182
+ # * +UNAVAILABLE+
183
+ # * +AUTHENTICATIONFAILED+
184
+ # * +AUTHORIZATIONFAILED+
185
+ # * +EXPIRED+
186
+ # * +PRIVACYREQUIRED+
187
+ # * +CONTACTADMIN+
188
+ # * +NOPERM+
189
+ # * +INUSE+
190
+ # * +EXPUNGEISSUED+
191
+ # * +CORRUPTION+
192
+ # * +SERVERBUG+
193
+ # * +CLIENTBUG+
194
+ # * +CANNOT+
195
+ # * +LIMIT+
196
+ # * +OVERQUOTA+
197
+ # * +ALREADYEXISTS+
198
+ # * +NONEXISTENT+
112
199
  #
113
200
  class ResponseCode < Struct.new(:name, :data)
201
+ ##
202
+ # method: name
203
+ # :call-seq: name -> string
204
+ #
205
+ # Returns the response code name, such as "ALERT", "PERMANENTFLAGS", or
206
+ # "UIDVALIDITY".
207
+
208
+ ##
209
+ # method: data
210
+ # :call-seq: data -> object or nil
211
+ #
212
+ # Returns the parsed response code data, e.g: an array of capabilities
213
+ # strings, an array of character set strings, a list of permanent flags,
214
+ # an Integer, etc. The response #code determines what form the response
215
+ # code data can take.
114
216
  end
115
217
 
116
- # Net::IMAP::MailboxList represents contents of the LIST response.
117
- #
118
- # mailbox_list ::= "(" #("\Marked" / "\Noinferiors" /
119
- # "\Noselect" / "\Unmarked" / flag_extension) ")"
120
- # SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox
121
- #
122
- # ==== Fields:
123
- #
124
- # attr:: Returns the name attributes. Each name attribute is a symbol
125
- # capitalized by String#capitalize, such as :Noselect (not :NoSelect).
126
- #
127
- # delim:: Returns the hierarchy delimiter.
218
+ # Net::IMAP::UIDPlusData represents the ResponseCode#data that accompanies
219
+ # the +APPENDUID+ and +COPYUID+ response codes.
220
+ #
221
+ # See [[UIDPLUS[https://www.rfc-editor.org/rfc/rfc4315.html]].
222
+ #
223
+ # ==== Capability requirement
224
+ #
225
+ # The +UIDPLUS+ capability[rdoc-ref:Net::IMAP#capability] must be supported.
226
+ # A server that supports +UIDPLUS+ should send a UIDPlusData object inside
227
+ # every TaggedResponse returned by the append[rdoc-ref:Net::IMAP#append],
228
+ # copy[rdoc-ref:Net::IMAP#copy], move[rdoc-ref:Net::IMAP#move], {uid
229
+ # copy}[rdoc-ref:Net::IMAP#uid_copy], and {uid
230
+ # move}[rdoc-ref:Net::IMAP#uid_move] commands---unless the destination
231
+ # mailbox reports +UIDNOTSTICKY+.
232
+ #
233
+ #--
234
+ # TODO: support MULTIAPPEND
235
+ #++
236
+ #
237
+ class UIDPlusData < Struct.new(:uidvalidity, :source_uids, :assigned_uids)
238
+ ##
239
+ # method: uidvalidity
240
+ # :call-seq: uidvalidity -> nonzero uint32
241
+ #
242
+ # The UIDVALIDITY of the destination mailbox.
243
+
244
+ ##
245
+ # method: source_uids
246
+ # :call-seq: source_uids -> nil or an array of nonzero uint32
247
+ #
248
+ # The UIDs of the copied or moved messages.
249
+ #
250
+ # Note:: Returns +nil+ for Net::IMAP#append.
251
+
252
+ ##
253
+ # method: assigned_uids
254
+ # :call-seq: assigned_uids -> an array of nonzero uint32
255
+ #
256
+ # The newly assigned UIDs of the copied, moved, or appended messages.
257
+ #
258
+ # Note:: This always returns an array, even when it contains only one UID.
259
+
260
+ ##
261
+ # :call-seq: uid_mapping -> nil or a hash
262
+ #
263
+ # Returns a hash mapping each source UID to the newly assigned destination
264
+ # UID.
265
+ #
266
+ # Note:: Returns +nil+ for Net::IMAP#append.
267
+ def uid_mapping
268
+ source_uids&.zip(assigned_uids)&.to_h
269
+ end
270
+ end
271
+
272
+ # Net::IMAP::MailboxList represents contents of the LIST response,
273
+ # representing a single mailbox path.
128
274
  #
129
- # name:: Returns the mailbox name.
275
+ # Net::IMAP#list returns an array of MailboxList objects.
130
276
  #
131
277
  class MailboxList < Struct.new(:attr, :delim, :name)
278
+ ##
279
+ # method: attr
280
+ # :call-seq: attr -> array of Symbols
281
+ #
282
+ # Returns the name attributes. Each name attribute is a symbol capitalized
283
+ # by String#capitalize, such as :Noselect (not :NoSelect). For the
284
+ # semantics of each attribute, see:
285
+ # * rdoc-ref:Net::IMAP@Basic+Mailbox+Attributes
286
+ # * rdoc-ref:Net::IMAP@Mailbox+role+Attributes
287
+ # * Net::IMAP@SPECIAL-USE
288
+ # * The IANA {IMAP Mailbox Name Attributes
289
+ # registry}[https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml]
290
+
291
+ ##
292
+ # method: delim
293
+ # :call-seq: delim -> single character string
294
+ #
295
+ # Returns the hierarchy delimiter for the mailbox path.
296
+
297
+ ##
298
+ # method: name
299
+ # :call-seq: name -> string
300
+ #
301
+ # Returns the mailbox name.
132
302
  end
133
303
 
134
304
  # Net::IMAP::MailboxQuota represents contents of GETQUOTA response.
@@ -136,276 +306,743 @@ module Net
136
306
  # specification below, the delimiter used with the "#" construct is a
137
307
  # single space (SPACE).
138
308
  #
139
- # quota_list ::= "(" #quota_resource ")"
140
- #
141
- # quota_resource ::= atom SPACE number SPACE number
142
- #
143
- # quota_response ::= "QUOTA" SPACE astring SPACE quota_list
144
- #
145
- # ==== Fields:
146
- #
147
- # mailbox:: The mailbox with the associated quota.
309
+ # Net:IMAP#getquota returns an array of MailboxQuota objects.
148
310
  #
149
- # usage:: Current storage usage of the mailbox.
150
- #
151
- # quota:: Quota limit imposed on the mailbox.
311
+ # Net::IMAP#getquotaroot returns an array containing both MailboxQuotaRoot
312
+ # and MailboxQuota objects.
152
313
  #
153
314
  class MailboxQuota < Struct.new(:mailbox, :usage, :quota)
315
+ ##
316
+ # method: mailbox
317
+ # :call-seq: mailbox -> string
318
+ #
319
+ # The mailbox with the associated quota.
320
+
321
+ ##
322
+ # method: usage
323
+ # :call-seq: usage -> Integer
324
+ #
325
+ # Current storage usage of the mailbox.
326
+
327
+ ##
328
+ # method: quota
329
+ # :call-seq: quota -> Integer
330
+ #
331
+ # Quota limit imposed on the mailbox.
332
+ #
154
333
  end
155
334
 
156
335
  # Net::IMAP::MailboxQuotaRoot represents part of the GETQUOTAROOT
157
336
  # response. (GETQUOTAROOT can also return Net::IMAP::MailboxQuota.)
158
337
  #
159
- # quotaroot_response ::= "QUOTAROOT" SPACE astring *(SPACE astring)
160
- #
161
- # ==== Fields:
162
- #
163
- # mailbox:: The mailbox with the associated quota.
164
- #
165
- # quotaroots:: Zero or more quotaroots that affect the quota on the
166
- # specified mailbox.
338
+ # Net::IMAP#getquotaroot returns an array containing both MailboxQuotaRoot
339
+ # and MailboxQuota objects.
167
340
  #
168
341
  class MailboxQuotaRoot < Struct.new(:mailbox, :quotaroots)
342
+ ##
343
+ # method: mailbox
344
+ # :call-seq: mailbox -> string
345
+ #
346
+ # The mailbox with the associated quota.
347
+
348
+ ##
349
+ # method: mailbox
350
+ # :call-seq: quotaroots -> array of strings
351
+ #
352
+ # Zero or more quotaroots that affect the quota on the specified mailbox.
169
353
  end
170
354
 
171
355
  # Net::IMAP::MailboxACLItem represents the response from GETACL.
172
356
  #
173
- # acl_data ::= "ACL" SPACE mailbox *(SPACE identifier SPACE rights)
174
- #
175
- # identifier ::= astring
176
- #
177
- # rights ::= astring
178
- #
179
- # ==== Fields:
180
- #
181
- # user:: Login name that has certain rights to the mailbox
182
- # that was specified with the getacl command.
183
- #
184
- # rights:: The access rights the indicated user has to the
185
- # mailbox.
357
+ # Net::IMAP#getacl returns an array of MailboxACLItem objects.
186
358
  #
359
+ # ==== Required capability
360
+ # +ACL+ - described in [ACL[https://tools.ietf.org/html/rfc4314]]
187
361
  class MailboxACLItem < Struct.new(:user, :rights, :mailbox)
362
+ ##
363
+ # method: mailbox
364
+ # :call-seq: mailbox -> string
365
+ #
366
+ # The mailbox to which the indicated #user has the specified #rights.
367
+
368
+ ##
369
+ # method: user
370
+ # :call-seq: user -> string
371
+ #
372
+ # Login name that has certain #rights to the #mailbox that was specified
373
+ # with the getacl command.
374
+
375
+ ##
376
+ # method: rights
377
+ # :call-seq: rights -> string
378
+ #
379
+ # The access rights the indicated #user has to the #mailbox.
188
380
  end
189
381
 
190
- # Net::IMAP::Namespace represents a single [RFC-2342] namespace.
191
- #
192
- # Namespace = nil / "(" 1*( "(" string SP (<"> QUOTED_CHAR <"> /
193
- # nil) *(Namespace_Response_Extension) ")" ) ")"
382
+ # Net::IMAP::Namespace represents a single namespace contained inside a
383
+ # NAMESPACE response.
194
384
  #
195
- # Namespace_Response_Extension = SP string SP "(" string *(SP string)
196
- # ")"
197
- #
198
- # ==== Fields:
199
- #
200
- # prefix:: Returns the namespace prefix string.
201
- # delim:: Returns nil or the hierarchy delimiter character.
202
- # extensions:: Returns a hash of extension names to extension flag arrays.
385
+ # Returned by Net::IMAP#namespace, contained inside a Namespaces object.
203
386
  #
204
387
  class Namespace < Struct.new(:prefix, :delim, :extensions)
388
+ ##
389
+ # method: prefix
390
+ # :call-seq: prefix -> string
391
+ #
392
+ # Returns the namespace prefix string.
393
+
394
+ ##
395
+ # method: delim
396
+ # :call-seq: delim -> single character string or nil
397
+ #
398
+ # Returns a hierarchy delimiter character, if it exists.
399
+
400
+ ##
401
+ # method: extensions
402
+ # :call-seq: extensions -> Hash[String, Array[String]]
403
+ #
404
+ # A hash of parameters mapped to arrays of strings, for extensibility.
405
+ # Extension parameter semantics would be defined by the extension.
205
406
  end
206
407
 
207
- # Net::IMAP::Namespaces represents the response from [RFC-2342] NAMESPACE.
208
- #
209
- # Namespace_Response = "*" SP "NAMESPACE" SP Namespace SP Namespace SP
210
- # Namespace
211
- #
212
- # ; The first Namespace is the Personal Namespace(s)
213
- # ; The second Namespace is the Other Users' Namespace(s)
214
- # ; The third Namespace is the Shared Namespace(s)
408
+ # Net::IMAP::Namespaces represents a +NAMESPACE+ server response, which
409
+ # contains lists of #personal, #shared, and #other namespaces.
215
410
  #
216
- # ==== Fields:
217
- #
218
- # personal:: Returns an array of Personal Net::IMAP::Namespace objects.
219
- # other:: Returns an array of Other Users' Net::IMAP::Namespace objects.
220
- # shared:: Returns an array of Shared Net::IMAP::Namespace objects.
411
+ # Net::IMAP#namespace returns a Namespaces object.
221
412
  #
222
413
  class Namespaces < Struct.new(:personal, :other, :shared)
414
+ ##
415
+ # method: personal
416
+ # :call-seq: personal -> array of Namespace
417
+ #
418
+ # Returns an array of Personal Namespace objects.
419
+
420
+ ##
421
+ # method: other
422
+ # :call-seq: other -> array of Namespace
423
+ #
424
+ # Returns an array of Other Users' Namespace objects.
425
+
426
+ ##
427
+ # method: shared
428
+ # :call-seq: shared -> array of Namespace
429
+ #
430
+ # Returns an array of Shared Namespace objects.
223
431
  end
224
432
 
225
433
  # Net::IMAP::StatusData represents the contents of the STATUS response.
226
434
  #
227
- # ==== Fields:
228
- #
229
- # mailbox:: Returns the mailbox name.
230
- #
231
- # attr:: Returns a hash. Each key is one of "MESSAGES", "RECENT", "UIDNEXT",
232
- # "UIDVALIDITY", "UNSEEN". Each value is a number.
233
- #
435
+ # Net::IMAP#status returns the contents of #attr.
234
436
  class StatusData < Struct.new(:mailbox, :attr)
437
+ ##
438
+ # method: mailbox
439
+ # :call-seq: mailbox -> string
440
+ #
441
+ # The mailbox name.
442
+
443
+ ##
444
+ # method: attr
445
+ # :call-seq: attr -> Hash[String, Integer]
446
+ #
447
+ # A hash. Each key is one of "MESSAGES", "RECENT", "UIDNEXT",
448
+ # "UIDVALIDITY", "UNSEEN". Each value is a number.
235
449
  end
236
450
 
237
- # Net::IMAP::FetchData represents the contents of the FETCH response.
238
- #
239
- # ==== Fields:
240
- #
241
- # seqno:: Returns the message sequence number.
242
- # (Note: not the unique identifier, even for the UID command response.)
243
- #
244
- # attr:: Returns a hash. Each key is a data item name, and each value is
245
- # its value.
246
- #
247
- # The current data items are:
248
- #
249
- # [BODY]
250
- # A form of BODYSTRUCTURE without extension data.
251
- # [BODY[<section>]<<origin_octet>>]
252
- # A string expressing the body contents of the specified section.
253
- # [BODYSTRUCTURE]
254
- # An object that describes the [MIME-IMB] body structure of a message.
255
- # See Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText,
256
- # Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart.
257
- # [ENVELOPE]
258
- # A Net::IMAP::Envelope object that describes the envelope
259
- # structure of a message.
260
- # [FLAGS]
261
- # A array of flag symbols that are set for this message. Flag symbols
262
- # are capitalized by String#capitalize.
263
- # [INTERNALDATE]
264
- # A string representing the internal date of the message.
265
- # [RFC822]
266
- # Equivalent to +BODY[]+.
267
- # [RFC822.HEADER]
268
- # Equivalent to +BODY.PEEK[HEADER]+.
269
- # [RFC822.SIZE]
270
- # A number expressing the [RFC-822] size of the message.
271
- # [RFC822.TEXT]
272
- # Equivalent to +BODY[TEXT]+.
273
- # [UID]
274
- # A number expressing the unique identifier of the message.
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
+ #++
275
631
  #
276
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.
277
653
  end
278
654
 
279
655
  # Net::IMAP::Envelope represents envelope structures of messages.
280
656
  #
281
- # ==== Fields:
282
- #
283
- # date:: Returns a string that represents the date.
284
- #
285
- # subject:: Returns a string that represents the subject.
286
- #
287
- # from:: Returns an array of Net::IMAP::Address that represents the from.
288
- #
289
- # sender:: Returns an array of Net::IMAP::Address that represents the sender.
290
- #
291
- # reply_to:: Returns an array of Net::IMAP::Address that represents the reply-to.
292
- #
293
- # to:: Returns an array of Net::IMAP::Address that represents the to.
294
- #
295
- # cc:: Returns an array of Net::IMAP::Address that represents the cc.
657
+ # [Note]
658
+ # When the #sender and #reply_to fields are absent or empty, they will
659
+ # return the same value as #from. Also, fields may return values that are
660
+ # invalid for well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]]
661
+ # messages when the message is malformed or a draft message.
296
662
  #
297
- # bcc:: Returns an array of Net::IMAP::Address that represents the bcc.
298
- #
299
- # in_reply_to:: Returns a string that represents the in-reply-to.
300
- #
301
- # message_id:: Returns a string that represents the message-id.
663
+ # See [{IMAP4rev1 §7.4.2}[https://www.rfc-editor.org/rfc/rfc3501.html#section-7.4.2]]
664
+ # and [{IMAP4rev2 §7.5.2}[https://www.rfc-editor.org/rfc/rfc9051.html#section-7.5.2]]
665
+ # for full description of the envelope fields, and
666
+ # Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs.
302
667
  #
303
668
  class Envelope < Struct.new(:date, :subject, :from, :sender, :reply_to,
304
669
  :to, :cc, :bcc, :in_reply_to, :message_id)
670
+ ##
671
+ # method: date
672
+ # call-seq: date -> string
673
+ #
674
+ # Returns a string that represents the +Date+ header.
675
+ #
676
+ # [Note]
677
+ # For a well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]]
678
+ # message, the #date field must not be +nil+. However it can be +nil+
679
+ # for a malformed or draft message.
680
+
681
+ ##
682
+ # method: subject
683
+ # call-seq: subject -> string or nil
684
+ #
685
+ # Returns a string that represents the +Subject+ header, if it is present.
686
+ #
687
+ # [Note]
688
+ # Servers should return +nil+ when the header is absent and an empty
689
+ # string when it is present but empty. Some servers may return a +nil+
690
+ # envelope member in the "present but empty" case. Clients should treat
691
+ # +nil+ and empty string as identical.
692
+
693
+ ##
694
+ # method: from
695
+ # call-seq: from -> array of Net::IMAP::Address or nil
696
+ #
697
+ # Returns an array of Address that represents the +From+ header.
698
+ #
699
+ # If the +From+ header is absent, or is present but empty, the server
700
+ # returns +nil+ for this envelope field.
701
+ #
702
+ # [Note]
703
+ # For a well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]]
704
+ # message, the #from field must not be +nil+. However it can be +nil+
705
+ # for a malformed or draft message.
706
+
707
+ ##
708
+ # method: sender
709
+ # call-seq: sender -> array of Net::IMAP::Address or nil
710
+ #
711
+ # Returns an array of Address that represents the +Sender+ header.
712
+ #
713
+ # [Note]
714
+ # If the <tt>Sender</tt> header is absent, or is present but empty, the
715
+ # server sets this field to be the same value as #from. Therefore, in a
716
+ # well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]] message,
717
+ # the #sender envelope field must not be +nil+. However it can be
718
+ # +nil+ for a malformed or draft message.
719
+
720
+ ##
721
+ # method: reply_to
722
+ # call-seq: reply_to -> array of Net::IMAP::Address or nil
723
+ #
724
+ # Returns an array of Address that represents the <tt>Reply-To</tt>
725
+ # header.
726
+ #
727
+ # [Note]
728
+ # If the <tt>Reply-To</tt> header is absent, or is present but empty,
729
+ # the server sets this field to be the same value as #from. Therefore,
730
+ # in a well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]]
731
+ # message, the #reply_to envelope field must not be +nil+. However it
732
+ # can be +nil+ for a malformed or draft message.
733
+
734
+ ##
735
+ # method: to
736
+ # call-seq: to -> array of Net::IMAP::Address
737
+ #
738
+ # Returns an array of Address that represents the +To+ header.
739
+
740
+ ##
741
+ # method: cc
742
+ # call-seq: cc -> array of Net::IMAP::Address
743
+ #
744
+ # Returns an array of Address that represents the +Cc+ header.
745
+
746
+ ##
747
+ # method: bcc
748
+ # call-seq: bcc -> array of Net::IMAP::Address
749
+ #
750
+ # Returns an array of Address that represents the +Bcc+ header.
751
+
752
+ ##
753
+ # method: in_reply_to
754
+ # call-seq: in_reply_to -> string
755
+ #
756
+ # Returns a string that represents the <tt>In-Reply-To</tt> header.
757
+ #
758
+ # [Note]
759
+ # For a well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]]
760
+ # message, the #in_reply_to field, if present, must not be empty. But
761
+ # it can still return an empty string for malformed messages.
762
+ #
763
+ # Servers should return +nil+ when the header is absent and an empty
764
+ # string when it is present but empty. Some servers may return a +nil+
765
+ # envelope member in the "present but empty" case. Clients should treat
766
+ # +nil+ and empty string as identical.
767
+
768
+ ##
769
+ # method: message_id
770
+ # call-seq: message_id -> string
771
+ #
772
+ # Returns a string that represents the <tt>Message-ID</tt>.
773
+ #
774
+ # [Note]
775
+ # For a well-formed [RFC5322[https://tools.ietf.org/html/rfc5322]]
776
+ # message, the #message_id field, if present, must not be empty. But it
777
+ # can still return an empty string for malformed messages.
778
+ #
779
+ # Servers should return +nil+ when the header is absent and an empty
780
+ # string when it is present but empty. Some servers may return a +nil+
781
+ # envelope member in the "present but empty" case. Clients should treat
782
+ # +nil+ and empty string as identical.
305
783
  end
306
784
 
307
- #
308
- # Net::IMAP::Address represents electronic mail addresses.
309
- #
310
- # ==== Fields:
311
- #
312
- # name:: Returns the phrase from [RFC-822] mailbox.
313
- #
314
- # route:: Returns the route from [RFC-822] route-addr.
315
- #
316
- # mailbox:: nil indicates end of [RFC-822] group.
317
- # If non-nil and host is nil, returns [RFC-822] group name.
318
- # Otherwise, returns [RFC-822] local-part.
319
- #
320
- # host:: nil indicates [RFC-822] group syntax.
321
- # Otherwise, returns [RFC-822] domain name.
322
- #
785
+ # Net::IMAP::Address represents an electronic mail address, which has been
786
+ # parsed into its component parts by the server. Address objects are
787
+ # returned within Envelope fields.
788
+ #
789
+ # === Group syntax
790
+ #
791
+ # When the #host field is +nil+, this is a special form of address structure
792
+ # that indicates the [RFC5322[https://tools.ietf.org/html/rfc5322]] group
793
+ # syntax. If the #mailbox name field is also +nil+, this is an end-of-group
794
+ # marker (semicolon in RFC-822 syntax). If the #mailbox name field is
795
+ # non-+NIL+, this is the start of a group marker, and the mailbox #name
796
+ # field holds the group name phrase.
323
797
  class Address < Struct.new(:name, :route, :mailbox, :host)
798
+ ##
799
+ # method: name
800
+ # :call-seq: name -> string or nil
801
+ #
802
+ # Returns the [RFC5322[https://tools.ietf.org/html/rfc5322]] address
803
+ # +display-name+ (or the mailbox +phrase+ in the RFC-822 grammar).
804
+
805
+ ##
806
+ # method: route
807
+ # :call-seq: route -> string or nil
808
+ #
809
+ # Returns the route from RFC-822 route-addr.
810
+ #
811
+ # Note:: Generating this obsolete route addressing syntax is not allowed
812
+ # by [RFC5322[https://tools.ietf.org/html/rfc5322]]. However,
813
+ # addresses with this syntax must still be accepted and parsed.
814
+
815
+ ##
816
+ # method: mailbox
817
+ # :call-seq: mailbox -> string or nil
818
+ #
819
+ # Returns the [RFC5322[https://tools.ietf.org/html/rfc5322]] address
820
+ # +local-part+, if #host is not +nil+.
821
+ #
822
+ # When #host is +nil+, this returns
823
+ # an [RFC5322[https://tools.ietf.org/html/rfc5322]] group name and a +nil+
824
+ # mailbox indicates the end of a group.
825
+
826
+ ##
827
+ # method: host
828
+ # :call-seq: host -> string or nil
829
+ #
830
+ # Returns the [RFC5322[https://tools.ietf.org/html/rfc5322]] addr-spec
831
+ # +domain+ name.
832
+ #
833
+ # +nil+ indicates [RFC5322[https://tools.ietf.org/html/rfc5322]] group
834
+ # syntax.
324
835
  end
325
836
 
326
- #
327
837
  # Net::IMAP::ContentDisposition represents Content-Disposition fields.
328
838
  #
329
- # ==== Fields:
330
- #
331
- # dsp_type:: Returns the disposition type.
332
- #
333
- # param:: Returns a hash that represents parameters of the Content-Disposition
334
- # field.
335
- #
336
839
  class ContentDisposition < Struct.new(:dsp_type, :param)
840
+ ##
841
+ # method: dsp_type
842
+ # :call-seq: dsp_type -> string
843
+ #
844
+ # Returns the content disposition type, as defined by
845
+ # [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
846
+
847
+ ##
848
+ # method: param
849
+ # :call-seq: param -> hash
850
+ #
851
+ # Returns a hash representing parameters of the Content-Disposition
852
+ # field, as defined by [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
337
853
  end
338
854
 
339
855
  # Net::IMAP::ThreadMember represents a thread-node returned
340
856
  # by Net::IMAP#thread.
341
857
  #
342
- # ==== Fields:
343
- #
344
- # seqno:: The sequence number of this message.
345
- #
346
- # children:: An array of Net::IMAP::ThreadMember objects for mail
347
- # items that are children of this in the thread.
348
- #
349
858
  class ThreadMember < Struct.new(:seqno, :children)
859
+ ##
860
+ # method: seqno
861
+ # :call-seq: seqno -> Integer
862
+ #
863
+ # The message sequence number.
864
+
865
+ ##
866
+ # method: children
867
+ # :call-seq: children -> array of ThreadMember
868
+ #
869
+ # An array of Net::IMAP::ThreadMember objects for mail items that are
870
+ # children of this in the thread.
350
871
  end
351
872
 
352
- # Net::IMAP::BodyTypeBasic represents basic body structures of messages.
353
- #
354
- # ==== Fields:
355
- #
356
- # media_type:: Returns the content media type name as defined in [MIME-IMB].
357
- #
358
- # subtype:: Returns the content subtype name as defined in [MIME-IMB].
359
- #
360
- # param:: Returns a hash that represents parameters as defined in [MIME-IMB].
361
- #
362
- # content_id:: Returns a string giving the content id as defined in [MIME-IMB].
363
- #
364
- # description:: Returns a string giving the content description as defined in
365
- # [MIME-IMB].
366
- #
367
- # encoding:: Returns a string giving the content transfer encoding as defined in
368
- # [MIME-IMB].
369
- #
370
- # size:: Returns a number giving the size of the body in octets.
371
- #
372
- # md5:: Returns a string giving the body MD5 value as defined in [MD5].
373
- #
374
- # disposition:: Returns a Net::IMAP::ContentDisposition object giving
375
- # the content disposition.
376
- #
377
- # language:: Returns a string or an array of strings giving the body
378
- # language value as defined in [LANGUAGE-TAGS].
379
- #
380
- # extension:: Returns extension data.
873
+ # Net::IMAP::BodyStructure is included by all of the structs that can be
874
+ # returned from a <tt>"BODYSTRUCTURE"</tt> or <tt>"BODY"</tt>
875
+ # FetchData#attr value. Although these classes don't share a base class,
876
+ # this module can be used to pattern match all of them.
877
+ #
878
+ # See {[IMAP4rev1] §7.4.2}[https://www.rfc-editor.org/rfc/rfc3501.html#section-7.4.2]
879
+ # and {[IMAP4rev2] §7.5.2}[https://www.rfc-editor.org/rfc/rfc9051.html#section-7.5.2-4.9]
880
+ # for full description of all +BODYSTRUCTURE+ fields, and also
881
+ # Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs.
882
+ #
883
+ # === Classes that include BodyStructure
884
+ # BodyTypeBasic:: Represents any message parts that are not handled by
885
+ # BodyTypeText, BodyTypeMessage, or BodyTypeMultipart.
886
+ # BodyTypeText:: Used by <tt>text/*</tt> parts. Contains all of the
887
+ # BodyTypeBasic fields.
888
+ # BodyTypeMessage:: Used by <tt>message/rfc822</tt> and
889
+ # <tt>message/global</tt> parts. Contains all of the
890
+ # BodyTypeBasic fields. Other <tt>message/*</tt> types
891
+ # should use BodyTypeBasic.
892
+ # BodyTypeMultipart:: for <tt>multipart/*</tt> parts
893
+ #
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
+ module BodyStructure
902
+ end
903
+
904
+ # Net::IMAP::BodyTypeBasic represents basic body structures of messages and
905
+ # message parts, unless they have a <tt>Content-Type</tt> that is handled by
906
+ # BodyTypeText, BodyTypeMessage, or BodyTypeMultipart.
381
907
  #
382
- # multipart?:: Returns false.
908
+ # See {[IMAP4rev1] §7.4.2}[https://www.rfc-editor.org/rfc/rfc3501.html#section-7.4.2]
909
+ # and {[IMAP4rev2] §7.5.2}[https://www.rfc-editor.org/rfc/rfc9051.html#section-7.5.2-4.9]
910
+ # for full description of all +BODYSTRUCTURE+ fields, and also
911
+ # Net::IMAP@Message+envelope+and+body+structure for other relevant RFCs.
383
912
  #
384
913
  class BodyTypeBasic < Struct.new(:media_type, :subtype,
385
914
  :param, :content_id,
386
915
  :description, :encoding, :size,
387
916
  :md5, :disposition, :language,
388
917
  :extension)
918
+ include BodyStructure
919
+
920
+ ##
921
+ # method: media_type
922
+ # :call-seq: media_type -> string
923
+ #
924
+ # The top-level media type as defined in
925
+ # [MIME-IMB[https://tools.ietf.org/html/rfc2045]].
926
+
927
+ ##
928
+ # method: subtype
929
+ # :call-seq: subtype -> string
930
+ #
931
+ # The media subtype name as defined in
932
+ # [MIME-IMB[https://tools.ietf.org/html/rfc2045]].
933
+
934
+ ##
935
+ # method: param
936
+ # :call-seq: param -> string
937
+ #
938
+ # Returns a hash that represents parameters as defined in
939
+ # [MIME-IMB[https://tools.ietf.org/html/rfc2045]].
940
+
941
+ ##
942
+ # method: content_id
943
+ # :call-seq: content_id -> string
944
+ #
945
+ # Returns a string giving the content id as defined
946
+ # in [MIME-IMB[https://tools.ietf.org/html/rfc2045]]
947
+ # {§7}[https://tools.ietf.org/html/rfc2045#section-7].
948
+
949
+ ##
950
+ # method: description
951
+ # :call-seq: description -> string
952
+ #
953
+ # Returns a string giving the content description as defined
954
+ # in [MIME-IMB[https://tools.ietf.org/html/rfc2045]]
955
+ # {§8}[https://tools.ietf.org/html/rfc2045#section-8].
956
+
957
+ ##
958
+ # method: encoding
959
+ # :call-seq: encoding -> string
960
+ #
961
+ # Returns a string giving the content transfer encoding as defined
962
+ # in [MIME-IMB[https://tools.ietf.org/html/rfc2045]]
963
+ # {§6}[https://tools.ietf.org/html/rfc2045#section-6].
964
+
965
+ ##
966
+ # method: size
967
+ # :call-seq: size -> integer
968
+ #
969
+ # Returns a number giving the size of the body in octets.
970
+
971
+ ##
972
+ # method: md5
973
+ # :call-seq: md5 -> string
974
+ #
975
+ # Returns a string giving the body MD5 value as defined in
976
+ # [MD5[https://tools.ietf.org/html/rfc1864]].
977
+
978
+ ##
979
+ # method: disposition
980
+ # :call-seq: disposition -> ContentDisposition
981
+ #
982
+ # Returns a ContentDisposition object giving the content
983
+ # disposition, as defined by
984
+ # [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
985
+
986
+ ##
987
+ # method: language
988
+ # :call-seq: language -> string
989
+ #
990
+ # Returns a string or an array of strings giving the body
991
+ # language value as defined in
992
+ # [LANGUAGE-TAGS[https://www.rfc-editor.org/info/rfc3282]].
993
+
994
+ #--
995
+ ##
996
+ # method: location
997
+ # :call-seq: location -> string
998
+ #
999
+ # A string list giving the body content URI as defined in
1000
+ # [LOCATION[https://www.rfc-editor.org/info/rfc2557]].
1001
+ #++
1002
+
1003
+ ##
1004
+ # method: extension
1005
+ # :call-seq: extension -> string
1006
+ #
1007
+ # Returns extension data. The +BODYSTRUCTURE+ fetch attribute
1008
+ # contains extension data, but +BODY+ does not.
1009
+
1010
+ ##
1011
+ # :call-seq: multipart? -> false
1012
+ #
1013
+ # BodyTypeBasic is not used for multipart MIME parts.
389
1014
  def multipart?
390
1015
  return false
391
1016
  end
392
1017
 
393
- # Obsolete: use +subtype+ instead. Calling this will
394
- # generate a warning message to +stderr+, then return
395
- # the value of +subtype+.
1018
+ # :call-seq: media_subtype -> subtype
1019
+ #
1020
+ # >>>
1021
+ # [Obsolete]
1022
+ # Use +subtype+ instead. Calling this will generate a warning message
1023
+ # to +stderr+, then return the value of +subtype+.
1024
+ #--
1025
+ # TODO: why not just keep this as an alias? Would "media_subtype" be used
1026
+ # for something else?
1027
+ #++
396
1028
  def media_subtype
397
1029
  warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
398
1030
  return subtype
399
1031
  end
400
1032
  end
401
1033
 
402
- # Net::IMAP::BodyTypeText represents TEXT body structures of messages.
403
- #
404
- # ==== Fields:
405
- #
406
- # lines:: Returns the size of the body in text lines.
407
- #
408
- # And Net::IMAP::BodyTypeText has all fields of Net::IMAP::BodyTypeBasic.
1034
+ # Net::IMAP::BodyTypeText represents the body structures of messages and
1035
+ # message parts, when <tt>Content-Type</tt> is <tt>text/*</tt>.
1036
+ #
1037
+ # BodyTypeText contains all of the fields of BodyTypeBasic. See
1038
+ # BodyTypeBasic for documentation of the following:
1039
+ # * {media_type}[rdoc-ref:BodyTypeBasic#media_type]
1040
+ # * subtype[rdoc-ref:BodyTypeBasic#subtype]
1041
+ # * param[rdoc-ref:BodyTypeBasic#param]
1042
+ # * {content_id}[rdoc-ref:BodyTypeBasic#content_id]
1043
+ # * description[rdoc-ref:BodyTypeBasic#description]
1044
+ # * encoding[rdoc-ref:BodyTypeBasic#encoding]
1045
+ # * size[rdoc-ref:BodyTypeBasic#size]
409
1046
  #
410
1047
  class BodyTypeText < Struct.new(:media_type, :subtype,
411
1048
  :param, :content_id,
@@ -413,6 +1050,18 @@ module Net
413
1050
  :lines,
414
1051
  :md5, :disposition, :language,
415
1052
  :extension)
1053
+ include BodyStructure
1054
+
1055
+ ##
1056
+ # method: lines
1057
+ # :call-seq: lines -> Integer
1058
+ #
1059
+ # Returns the size of the body in text lines.
1060
+
1061
+ ##
1062
+ # :call-seq: multipart? -> false
1063
+ #
1064
+ # BodyTypeText is not used for multipart MIME parts.
416
1065
  def multipart?
417
1066
  return false
418
1067
  end
@@ -426,15 +1075,19 @@ module Net
426
1075
  end
427
1076
  end
428
1077
 
429
- # Net::IMAP::BodyTypeMessage represents MESSAGE/RFC822 body structures of messages.
430
- #
431
- # ==== Fields:
432
- #
433
- # envelope:: Returns a Net::IMAP::Envelope giving the envelope structure.
434
- #
435
- # body:: Returns an object giving the body structure.
436
- #
437
- # And Net::IMAP::BodyTypeMessage has all methods of Net::IMAP::BodyTypeText.
1078
+ # Net::IMAP::BodyTypeMessage represents the body structures of messages and
1079
+ # message parts, when <tt>Content-Type</tt> is <tt>message/rfc822</tt> or
1080
+ # <tt>message/global</tt>.
1081
+ #
1082
+ # BodyTypeMessage contains all of the fields of BodyTypeBasic. See
1083
+ # BodyTypeBasic for documentation of the following fields:
1084
+ # * {media_type}[rdoc-ref:BodyTypeBasic#media_type]
1085
+ # * subtype[rdoc-ref:BodyTypeBasic#subtype]
1086
+ # * param[rdoc-ref:BodyTypeBasic#param]
1087
+ # * {content_id}[rdoc-ref:BodyTypeBasic#content_id]
1088
+ # * description[rdoc-ref:BodyTypeBasic#description]
1089
+ # * encoding[rdoc-ref:BodyTypeBasic#encoding]
1090
+ # * size[rdoc-ref:BodyTypeBasic#size]
438
1091
  #
439
1092
  class BodyTypeMessage < Struct.new(:media_type, :subtype,
440
1093
  :param, :content_id,
@@ -442,6 +1095,24 @@ module Net
442
1095
  :envelope, :body, :lines,
443
1096
  :md5, :disposition, :language,
444
1097
  :extension)
1098
+ include BodyStructure
1099
+
1100
+ ##
1101
+ # method: envelope
1102
+ # :call-seq: envelope -> Envelope
1103
+ #
1104
+ # Returns a Net::IMAP::Envelope giving the envelope structure.
1105
+
1106
+ ##
1107
+ # method: body
1108
+ # :call-seq: body -> BodyStructure
1109
+ #
1110
+ # Returns a Net::IMAP::BodyStructure for the message's body structure.
1111
+
1112
+ ##
1113
+ # :call-seq: multipart? -> false
1114
+ #
1115
+ # BodyTypeMessage is not used for multipart MIME parts.
445
1116
  def multipart?
446
1117
  return false
447
1118
  end
@@ -455,57 +1126,136 @@ module Net
455
1126
  end
456
1127
  end
457
1128
 
458
- # Net::IMAP::BodyTypeAttachment represents attachment body structures
459
- # of messages.
460
- #
461
- # ==== Fields:
462
- #
463
- # media_type:: Returns the content media type name.
464
- #
465
- # subtype:: Returns +nil+.
466
- #
467
- # param:: Returns a hash that represents parameters.
468
- #
469
- # multipart?:: Returns false.
470
- #
471
- class BodyTypeAttachment < Struct.new(:media_type, :subtype,
472
- :param)
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.
1133
+ #
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.
1155
+ #
1156
+ class BodyTypeAttachment < Struct.new(:dsp_type, :_unused_, :param)
1157
+ include BodyStructure
1158
+
1159
+ # *invalid for BodyTypeAttachment*
1160
+ def media_type
1161
+ warn(<<~WARN, uplevel: 1)
1162
+ BodyTypeAttachment#media_type is obsolete. Use dsp_type instead.
1163
+ WARN
1164
+ dsp_type
1165
+ end
1166
+
1167
+ # *invalid for BodyTypeAttachment*
1168
+ def subtype
1169
+ warn("BodyTypeAttachment#subtype is obsolete.\n", uplevel: 1)
1170
+ nil
1171
+ end
1172
+
1173
+ ##
1174
+ # method: dsp_type
1175
+ # :call-seq: dsp_type -> string
1176
+ #
1177
+ # Returns the content disposition type, as defined by
1178
+ # [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
1179
+
1180
+ ##
1181
+ # method: param
1182
+ # :call-seq: param -> hash
1183
+ #
1184
+ # Returns a hash representing parameters of the Content-Disposition
1185
+ # field, as defined by [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
1186
+
1187
+ ##
473
1188
  def multipart?
474
1189
  return false
475
1190
  end
476
1191
  end
477
1192
 
478
- # Net::IMAP::BodyTypeMultipart represents multipart body structures
479
- # of messages.
480
- #
481
- # ==== Fields:
482
- #
483
- # media_type:: Returns the content media type name as defined in [MIME-IMB].
484
- #
485
- # subtype:: Returns the content subtype name as defined in [MIME-IMB].
486
- #
487
- # parts:: Returns multiple parts.
488
- #
489
- # param:: Returns a hash that represents parameters as defined in [MIME-IMB].
490
- #
491
- # disposition:: Returns a Net::IMAP::ContentDisposition object giving
492
- # the content disposition.
493
- #
494
- # language:: Returns a string or an array of strings giving the body
495
- # language value as defined in [LANGUAGE-TAGS].
496
- #
497
- # extension:: Returns extension data.
498
- #
499
- # multipart?:: Returns true.
500
- #
1193
+ # Net::IMAP::BodyTypeMultipart represents body structures of messages and
1194
+ # message parts, when <tt>Content-Type</tt> is <tt>multipart/*</tt>.
501
1195
  class BodyTypeMultipart < Struct.new(:media_type, :subtype,
502
1196
  :parts,
503
1197
  :param, :disposition, :language,
504
1198
  :extension)
1199
+ include BodyStructure
1200
+
1201
+ ##
1202
+ # method: media_type
1203
+ # call-seq: media_type -> "multipart"
1204
+ #
1205
+ # BodyTypeMultipart is only used with <tt>multipart/*</tt> media types.
1206
+
1207
+ ##
1208
+ # method: subtype
1209
+ # call-seq: subtype -> string
1210
+ #
1211
+ # Returns the content subtype name
1212
+ # as defined in [MIME-IMB[https://tools.ietf.org/html/rfc2045]].
1213
+
1214
+ ##
1215
+ # method: parts
1216
+ # call-seq: parts -> array of BodyStructure objects
1217
+ #
1218
+ # Returns an array with a BodyStructure object for each part contained in
1219
+ # this part.
1220
+
1221
+ ##
1222
+ # method: param
1223
+ # call-seq: param -> hash
1224
+ #
1225
+ # Returns a hash that represents parameters
1226
+ # as defined in [MIME-IMB[https://tools.ietf.org/html/rfc2045]].
1227
+
1228
+ ##
1229
+ # method: disposition
1230
+ # call-seq: disposition -> ContentDisposition
1231
+ #
1232
+ # Returns a Net::IMAP::ContentDisposition object giving the content
1233
+ # disposition.
1234
+
1235
+ ##
1236
+ # method: language
1237
+ # :call-seq: language -> string
1238
+ #
1239
+ # Returns a string or an array of strings giving the body
1240
+ # language value as defined in
1241
+ # [LANGUAGE-TAGS[https://www.rfc-editor.org/info/rfc3282]].
1242
+
1243
+ ##
1244
+ # method: extension
1245
+ # call-seq: extension -> array
1246
+ #
1247
+ # Returns extension data as an array of numbers strings, and nested
1248
+ # arrays (of numbers, strings, etc).
1249
+
1250
+ ##
1251
+ # :call-seq: multipart? -> true
1252
+ #
1253
+ # BodyTypeMultipart is used for multipart MIME parts.
505
1254
  def multipart?
506
1255
  return true
507
1256
  end
508
1257
 
1258
+ ##
509
1259
  # Obsolete: use +subtype+ instead. Calling this will
510
1260
  # generate a warning message to +stderr+, then return
511
1261
  # the value of +subtype+.
@@ -515,9 +1265,19 @@ module Net
515
1265
  end
516
1266
  end
517
1267
 
1268
+ # === WARNING:
1269
+ # >>>
1270
+ # BodyTypeExtension is (incorrectly) used for <tt>message/*</tt> parts
1271
+ # (besides <tt>message/rfc822</tt>, which correctly uses BodyTypeMessage).
1272
+ #
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>
518
1276
  class BodyTypeExtension < Struct.new(:media_type, :subtype,
519
1277
  :params, :content_id,
520
1278
  :description, :encoding, :size)
1279
+ include BodyStructure
1280
+
521
1281
  def multipart?
522
1282
  return false
523
1283
  end