net-imap 0.4.17 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +8 -1
- data/README.md +10 -4
- data/docs/styles.css +75 -14
- data/lib/net/imap/authenticators.rb +2 -2
- data/lib/net/imap/command_data.rb +59 -46
- data/lib/net/imap/config.rb +109 -13
- data/lib/net/imap/data_encoding.rb +3 -3
- data/lib/net/imap/data_lite.rb +226 -0
- data/lib/net/imap/deprecated_client_options.rb +6 -3
- data/lib/net/imap/errors.rb +6 -0
- data/lib/net/imap/esearch_result.rb +180 -0
- data/lib/net/imap/fetch_data.rb +126 -47
- data/lib/net/imap/response_data.rb +124 -237
- data/lib/net/imap/response_parser/parser_utils.rb +5 -0
- data/lib/net/imap/response_parser.rb +183 -34
- data/lib/net/imap/sasl/anonymous_authenticator.rb +3 -3
- data/lib/net/imap/sasl/authentication_exchange.rb +52 -20
- data/lib/net/imap/sasl/authenticators.rb +8 -4
- data/lib/net/imap/sasl/client_adapter.rb +77 -26
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +4 -4
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +218 -56
- data/lib/net/imap/sasl/external_authenticator.rb +2 -2
- data/lib/net/imap/sasl/gs2_header.rb +7 -7
- data/lib/net/imap/sasl/login_authenticator.rb +4 -3
- data/lib/net/imap/sasl/oauthbearer_authenticator.rb +6 -6
- data/lib/net/imap/sasl/plain_authenticator.rb +7 -7
- data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
- data/lib/net/imap/sasl/scram_authenticator.rb +8 -8
- data/lib/net/imap/sasl.rb +7 -4
- data/lib/net/imap/sasl_adapter.rb +0 -1
- data/lib/net/imap/search_result.rb +2 -2
- data/lib/net/imap/sequence_set.rb +211 -81
- data/lib/net/imap/stringprep/nameprep.rb +1 -1
- data/lib/net/imap/stringprep/trace.rb +4 -4
- data/lib/net/imap/uidplus_data.rb +244 -0
- data/lib/net/imap/vanished_data.rb +56 -0
- data/lib/net/imap.rb +831 -279
- data/net-imap.gemspec +1 -1
- data/rakelib/rfcs.rake +2 -0
- data/rakelib/string_prep_tables_generator.rb +2 -0
- metadata +8 -7
data/lib/net/imap/fetch_data.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
module Net
|
4
4
|
class IMAP < Protocol
|
5
5
|
|
6
|
-
# Net::IMAP::
|
7
|
-
# Net::IMAP#fetch
|
8
|
-
#
|
6
|
+
# Net::IMAP::FetchStruct is the superclass for FetchData and UIDFetchData.
|
7
|
+
# Net::IMAP#fetch, Net::IMAP#uid_fetch, Net::IMAP#store, and
|
8
|
+
# Net::IMAP#uid_store all return arrays of FetchStruct objects.
|
9
9
|
#
|
10
10
|
# === Fetch attributes
|
11
11
|
#
|
@@ -63,8 +63,7 @@ module Net
|
|
63
63
|
# * <b><tt>"X-GM-MSGID"</tt></b> --- unique message ID. Access via #attr.
|
64
64
|
# * <b><tt>"X-GM-THRID"</tt></b> --- Thread ID. Access via #attr.
|
65
65
|
#
|
66
|
-
# [
|
67
|
-
# >>>
|
66
|
+
# [NOTE:]
|
68
67
|
# Additional static fields are defined in other \IMAP extensions, but
|
69
68
|
# Net::IMAP can't parse them yet.
|
70
69
|
#
|
@@ -87,34 +86,23 @@ module Net
|
|
87
86
|
# extension]}[https://developers.google.com/gmail/imap/imap-extensions]
|
88
87
|
# * <b><tt>"X-GM-LABELS"</tt></b> --- Gmail labels. Access via #attr.
|
89
88
|
#
|
90
|
-
# [
|
91
|
-
# >>>
|
89
|
+
# [NOTE:]
|
92
90
|
# Additional dynamic fields are defined in other \IMAP extensions, but
|
93
91
|
# Net::IMAP can't parse them yet.
|
94
92
|
#
|
95
93
|
# === Implicitly setting <tt>\Seen</tt> and using +PEEK+
|
96
94
|
#
|
97
|
-
# Unless the mailbox
|
95
|
+
# Unless the mailbox has been opened as read-only, fetching
|
98
96
|
# <tt>BODY[#{section}]</tt> or <tt>BINARY[#{section}]</tt>
|
99
97
|
# will implicitly set the <tt>\Seen</tt> flag. To avoid this, fetch using
|
100
98
|
# <tt>BODY.PEEK[#{section}]</tt> or <tt>BINARY.PEEK[#{section}]</tt>
|
101
99
|
# instead.
|
102
100
|
#
|
103
|
-
#
|
104
|
-
# <tt>
|
101
|
+
# [NOTE:]
|
102
|
+
# The data will always be _returned_ without the <tt>".PEEK"</tt> suffix,
|
103
|
+
# as <tt>BODY[#{specifier}]</tt> or <tt>BINARY[#{section}]</tt>.
|
105
104
|
#
|
106
|
-
class
|
107
|
-
##
|
108
|
-
# method: seqno
|
109
|
-
# :call-seq: seqno -> Integer
|
110
|
-
#
|
111
|
-
# The message sequence number.
|
112
|
-
#
|
113
|
-
# [Note]
|
114
|
-
# This is never the unique identifier (UID), not even for the
|
115
|
-
# Net::IMAP#uid_fetch result. The UID is available from #uid, if it was
|
116
|
-
# returned.
|
117
|
-
|
105
|
+
class FetchStruct < Struct
|
118
106
|
##
|
119
107
|
# method: attr
|
120
108
|
# :call-seq: attr -> hash
|
@@ -123,9 +111,6 @@ module Net
|
|
123
111
|
# corresponding data item. Standard data items have corresponding
|
124
112
|
# accessor methods. The definitions of each attribute type is documented
|
125
113
|
# on its accessor.
|
126
|
-
#
|
127
|
-
# >>>
|
128
|
-
# *Note:* #seqno is not a message attribute.
|
129
114
|
|
130
115
|
# :call-seq: attr_upcase -> hash
|
131
116
|
#
|
@@ -142,7 +127,7 @@ module Net
|
|
142
127
|
#
|
143
128
|
# This is the same as getting the value for <tt>"BODY"</tt> from #attr.
|
144
129
|
#
|
145
|
-
# [
|
130
|
+
# [NOTE:]
|
146
131
|
# Use #message, #part, #header, #header_fields, #header_fields_not,
|
147
132
|
# #text, or #mime to retrieve <tt>BODY[#{section_spec}]</tt> attributes.
|
148
133
|
def body; attr["BODY"] end
|
@@ -235,7 +220,7 @@ module Net
|
|
235
220
|
fields && except and
|
236
221
|
raise ArgumentError, "conflicting 'fields' and 'except' arguments"
|
237
222
|
if fields
|
238
|
-
text = "HEADER.FIELDS (%s)"
|
223
|
+
text = "HEADER.FIELDS (%s)" % [fields.join(" ").upcase]
|
239
224
|
attr_upcase[body_section_attr(part_nums, text, offset: offset)]
|
240
225
|
elsif except
|
241
226
|
text = "HEADER.FIELDS.NOT (%s)" % [except.join(" ").upcase]
|
@@ -308,6 +293,7 @@ module Net
|
|
308
293
|
# This is the same as getting the value for <tt>"BODYSTRUCTURE"</tt> from
|
309
294
|
# #attr.
|
310
295
|
def bodystructure; attr["BODYSTRUCTURE"] end
|
296
|
+
|
311
297
|
alias body_structure bodystructure
|
312
298
|
|
313
299
|
# :call-seq: envelope -> Envelope or nil
|
@@ -320,7 +306,7 @@ module Net
|
|
320
306
|
# #attr.
|
321
307
|
def envelope; attr["ENVELOPE"] end
|
322
308
|
|
323
|
-
# :call-seq: flags -> array of Symbols and Strings
|
309
|
+
# :call-seq: flags -> array of Symbols and Strings, or nil
|
324
310
|
#
|
325
311
|
# A array of flags that are set for this message. System flags are
|
326
312
|
# symbols that have been capitalized by String#capitalize. Keyword flags
|
@@ -328,7 +314,7 @@ module Net
|
|
328
314
|
#
|
329
315
|
# This is the same as getting the value for <tt>"FLAGS"</tt> from #attr.
|
330
316
|
#
|
331
|
-
# [
|
317
|
+
# [NOTE:]
|
332
318
|
# The +FLAGS+ field is dynamic, and can change for a uniquely identified
|
333
319
|
# message.
|
334
320
|
def flags; attr["FLAGS"] end
|
@@ -336,40 +322,41 @@ module Net
|
|
336
322
|
# :call-seq: internaldate -> Time or nil
|
337
323
|
#
|
338
324
|
# The internal date and time of the message on the server. This is not
|
339
|
-
# the date and time in the [RFC5322[https://
|
325
|
+
# the date and time in the [RFC5322[https://www.rfc-editor.org/rfc/rfc5322]]
|
340
326
|
# header, but rather a date and time which reflects when the message was
|
341
327
|
# received.
|
342
328
|
#
|
343
329
|
# This is similar to getting the value for <tt>"INTERNALDATE"</tt> from
|
344
330
|
# #attr.
|
345
331
|
#
|
346
|
-
# [
|
332
|
+
# [NOTE:]
|
347
333
|
# <tt>attr["INTERNALDATE"]</tt> returns a string, and this method
|
348
334
|
# returns a Time object.
|
349
335
|
def internaldate
|
350
336
|
attr["INTERNALDATE"]&.then { IMAP.decode_time _1 }
|
351
337
|
end
|
338
|
+
|
352
339
|
alias internal_date internaldate
|
353
340
|
|
354
|
-
# :call-seq: rfc822 -> String
|
341
|
+
# :call-seq: rfc822 -> String or nil
|
355
342
|
#
|
356
343
|
# Semantically equivalent to #message with no arguments.
|
357
344
|
#
|
358
345
|
# This is the same as getting the value for <tt>"RFC822"</tt> from #attr.
|
359
346
|
#
|
360
|
-
# [
|
347
|
+
# [NOTE:]
|
361
348
|
# +IMAP4rev2+ deprecates <tt>RFC822</tt>.
|
362
349
|
def rfc822; attr["RFC822"] end
|
363
350
|
|
364
|
-
# :call-seq: rfc822_size -> Integer
|
351
|
+
# :call-seq: rfc822_size -> Integer or nil
|
365
352
|
#
|
366
|
-
# A number expressing the [RFC5322[https://
|
353
|
+
# A number expressing the [RFC5322[https://www.rfc-editor.org/rfc/rfc5322]]
|
367
354
|
# size of the message.
|
368
355
|
#
|
369
356
|
# This is the same as getting the value for <tt>"RFC822.SIZE"</tt> from
|
370
357
|
# #attr.
|
371
358
|
#
|
372
|
-
# [
|
359
|
+
# [NOTE:]
|
373
360
|
# \IMAP was originally developed for the older
|
374
361
|
# RFC822[https://www.rfc-editor.org/rfc/rfc822.html] standard, and as a
|
375
362
|
# consequence several fetch items in \IMAP incorporate "RFC822" in their
|
@@ -379,34 +366,45 @@ module Net
|
|
379
366
|
# interpreted as a reference to the updated
|
380
367
|
# RFC5322[https://www.rfc-editor.org/rfc/rfc5322.html] standard.
|
381
368
|
def rfc822_size; attr["RFC822.SIZE"] end
|
382
|
-
alias size rfc822_size
|
383
369
|
|
384
|
-
# :call-seq
|
370
|
+
# NOTE: a bug in rdoc 6.7 prevents us from adding a call-seq to
|
371
|
+
# rfc822_size _and_ aliasing size => rfc822_size. Is it because this
|
372
|
+
# class inherits from Struct?
|
373
|
+
|
374
|
+
# Alias for: rfc822_size
|
375
|
+
def size; rfc822_size end
|
376
|
+
|
377
|
+
|
378
|
+
# :call-seq: rfc822_header -> String or nil
|
385
379
|
#
|
386
380
|
# Semantically equivalent to #header, with no arguments.
|
387
381
|
#
|
388
382
|
# This is the same as getting the value for <tt>"RFC822.HEADER"</tt> from #attr.
|
389
383
|
#
|
390
|
-
# [
|
384
|
+
# [NOTE:]
|
391
385
|
# +IMAP4rev2+ deprecates <tt>RFC822.HEADER</tt>.
|
392
386
|
def rfc822_header; attr["RFC822.HEADER"] end
|
393
387
|
|
394
|
-
# :call-seq: rfc822_text -> String
|
388
|
+
# :call-seq: rfc822_text -> String or nil
|
395
389
|
#
|
396
390
|
# Semantically equivalent to #text, with no arguments.
|
397
391
|
#
|
398
392
|
# This is the same as getting the value for <tt>"RFC822.TEXT"</tt> from
|
399
393
|
# #attr.
|
400
394
|
#
|
401
|
-
# [
|
395
|
+
# [NOTE:]
|
402
396
|
# +IMAP4rev2+ deprecates <tt>RFC822.TEXT</tt>.
|
403
397
|
def rfc822_text; attr["RFC822.TEXT"] end
|
404
398
|
|
405
|
-
# :call-seq: uid -> Integer
|
399
|
+
# :call-seq: uid -> Integer or nil
|
406
400
|
#
|
407
401
|
# A number expressing the unique identifier of the message.
|
408
402
|
#
|
409
403
|
# This is the same as getting the value for <tt>"UID"</tt> from #attr.
|
404
|
+
#
|
405
|
+
# [NOTE:]
|
406
|
+
# For UIDFetchData, this returns the uniqueid at the beginning of the
|
407
|
+
# +UIDFETCH+ response, _not_ the value from #attr.
|
410
408
|
def uid; attr["UID"] end
|
411
409
|
|
412
410
|
# :call-seq:
|
@@ -452,7 +450,7 @@ module Net
|
|
452
450
|
attr[section_attr("BINARY.SIZE", part_nums)]
|
453
451
|
end
|
454
452
|
|
455
|
-
# :call-seq: modseq -> Integer
|
453
|
+
# :call-seq: modseq -> Integer or nil
|
456
454
|
#
|
457
455
|
# The modification sequence number associated with this IMAP message.
|
458
456
|
#
|
@@ -461,7 +459,7 @@ module Net
|
|
461
459
|
# The server must support the +CONDSTORE+ extension
|
462
460
|
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
463
461
|
#
|
464
|
-
# [
|
462
|
+
# [NOTE:]
|
465
463
|
# The +MODSEQ+ field is dynamic, and can change for a uniquely
|
466
464
|
# identified message.
|
467
465
|
def modseq; attr["MODSEQ"] end
|
@@ -508,11 +506,92 @@ module Net
|
|
508
506
|
spec = Array(part).flatten.map { Integer(_1) }
|
509
507
|
spec << text if text
|
510
508
|
spec = spec.join(".")
|
511
|
-
if offset then "%s[%s]<%d>" % [attr, spec, Integer(offset)]
|
512
|
-
else "%s[%s]" % [attr, spec]
|
513
|
-
end
|
509
|
+
if offset then "%s[%s]<%d>" % [attr, spec, Integer(offset)] else "%s[%s]" % [attr, spec] end
|
514
510
|
end
|
511
|
+
end
|
515
512
|
|
513
|
+
# Net::IMAP::FetchData represents the contents of a +FETCH+ response.
|
514
|
+
# Net::IMAP#fetch, Net::IMAP#uid_fetch, Net::IMAP#store, and
|
515
|
+
# Net::IMAP#uid_store all return arrays of FetchData objects, except when
|
516
|
+
# the +UIDONLY+ extension is enabled.
|
517
|
+
#
|
518
|
+
# See FetchStruct documentation for a list of standard message attributes.
|
519
|
+
class FetchData < FetchStruct.new(:seqno, :attr)
|
520
|
+
##
|
521
|
+
# method: seqno
|
522
|
+
# :call-seq: seqno -> Integer
|
523
|
+
#
|
524
|
+
# The message sequence number.
|
525
|
+
#
|
526
|
+
# [NOTE:]
|
527
|
+
# This is not the same as the unique identifier (UID), not even for the
|
528
|
+
# Net::IMAP#uid_fetch result. The UID is available from #uid, if it was
|
529
|
+
# returned.
|
530
|
+
#
|
531
|
+
# [NOTE:]
|
532
|
+
# UIDFetchData will raise a NoMethodError.
|
533
|
+
|
534
|
+
##
|
535
|
+
# method: attr
|
536
|
+
# :call-seq: attr -> hash
|
537
|
+
#
|
538
|
+
# Each key specifies a message attribute, and the value is the
|
539
|
+
# corresponding data item. Standard data items have corresponding
|
540
|
+
# accessor methods. The definitions of each attribute type is documented
|
541
|
+
# on its accessor.
|
542
|
+
#
|
543
|
+
# See FetchStruct documentation for message attribute accessors.
|
544
|
+
#
|
545
|
+
# [NOTE:]
|
546
|
+
# #seqno is not a message attribute.
|
547
|
+
end
|
548
|
+
|
549
|
+
# Net::IMAP::UIDFetchData represents the contents of a +UIDFETCH+ response,
|
550
|
+
# When the +UIDONLY+ extension has been enabled, Net::IMAP#uid_fetch and
|
551
|
+
# Net::IMAP#uid_store will both return an array of UIDFetchData objects.
|
552
|
+
#
|
553
|
+
# UIDFetchData contains the same message attributes as FetchData. However,
|
554
|
+
# +UIDFETCH+ responses return the UID at the beginning of the response,
|
555
|
+
# replacing FetchData#seqno. UIDFetchData never contains a message sequence
|
556
|
+
# number.
|
557
|
+
#
|
558
|
+
# See FetchStruct documentation for a list of standard message attributes.
|
559
|
+
class UIDFetchData < FetchStruct.new(:uid, :attr)
|
560
|
+
##
|
561
|
+
# method: uid
|
562
|
+
# call-seq: uid -> Integer
|
563
|
+
#
|
564
|
+
# A number expressing the unique identifier of the message.
|
565
|
+
#
|
566
|
+
# [NOTE:]
|
567
|
+
# Although #attr may _also_ have a redundant +UID+ attribute, #uid
|
568
|
+
# returns the uniqueid at the beginning of the +UIDFETCH+ response.
|
569
|
+
|
570
|
+
##
|
571
|
+
# method: attr
|
572
|
+
# call-seq: attr -> hash
|
573
|
+
#
|
574
|
+
# Each key specifies a message attribute, and the value is the
|
575
|
+
# corresponding data item. Standard data items have corresponding
|
576
|
+
# accessor methods. The definitions of each attribute type is documented
|
577
|
+
# on its accessor.
|
578
|
+
#
|
579
|
+
# See FetchStruct documentation for message attribute accessors.
|
580
|
+
#
|
581
|
+
# [NOTE:]
|
582
|
+
# #uid is not a message attribute. Although the server may return a
|
583
|
+
# +UID+ message attribute, it is not required to. #uid is taken from
|
584
|
+
# its corresponding +UIDFETCH+ field.
|
585
|
+
|
586
|
+
# UIDFetchData will print a warning if <tt>#attr["UID"]</tt> is present
|
587
|
+
# but not identical to #uid.
|
588
|
+
def initialize(...)
|
589
|
+
super
|
590
|
+
attr and
|
591
|
+
attr_uid = attr["UID"] and
|
592
|
+
attr_uid != uid and
|
593
|
+
warn "#{self.class} UIDs do not match (#{attr_uid} != #{uid})"
|
594
|
+
end
|
516
595
|
end
|
517
596
|
end
|
518
597
|
end
|