kbaum-mail 2.1.2.1
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.
- data/CHANGELOG.rdoc +289 -0
- data/README.rdoc +575 -0
- data/Rakefile +72 -0
- data/TODO.rdoc +19 -0
- data/lib/mail.rb +113 -0
- data/lib/mail/attachments_list.rb +76 -0
- data/lib/mail/body.rb +243 -0
- data/lib/mail/configuration.rb +69 -0
- data/lib/mail/core_extensions/nil.rb +11 -0
- data/lib/mail/core_extensions/string.rb +19 -0
- data/lib/mail/elements/address.rb +306 -0
- data/lib/mail/elements/address_list.rb +74 -0
- data/lib/mail/elements/content_disposition_element.rb +30 -0
- data/lib/mail/elements/content_location_element.rb +25 -0
- data/lib/mail/elements/content_transfer_encoding_element.rb +21 -0
- data/lib/mail/elements/content_type_element.rb +35 -0
- data/lib/mail/elements/date_time_element.rb +26 -0
- data/lib/mail/elements/envelope_from_element.rb +34 -0
- data/lib/mail/elements/message_ids_element.rb +29 -0
- data/lib/mail/elements/mime_version_element.rb +26 -0
- data/lib/mail/elements/phrase_list.rb +21 -0
- data/lib/mail/elements/received_element.rb +30 -0
- data/lib/mail/encodings/base64.rb +18 -0
- data/lib/mail/encodings/encodings.rb +201 -0
- data/lib/mail/encodings/quoted_printable.rb +26 -0
- data/lib/mail/envelope.rb +35 -0
- data/lib/mail/field.rb +219 -0
- data/lib/mail/field_list.rb +33 -0
- data/lib/mail/fields/bcc_field.rb +53 -0
- data/lib/mail/fields/cc_field.rb +52 -0
- data/lib/mail/fields/comments_field.rb +41 -0
- data/lib/mail/fields/common/address_container.rb +16 -0
- data/lib/mail/fields/common/common_address.rb +128 -0
- data/lib/mail/fields/common/common_date.rb +51 -0
- data/lib/mail/fields/common/common_field.rb +64 -0
- data/lib/mail/fields/common/common_message_id.rb +57 -0
- data/lib/mail/fields/common/parameter_hash.rb +39 -0
- data/lib/mail/fields/content_description_field.rb +19 -0
- data/lib/mail/fields/content_disposition_field.rb +60 -0
- data/lib/mail/fields/content_id_field.rb +63 -0
- data/lib/mail/fields/content_location_field.rb +42 -0
- data/lib/mail/fields/content_transfer_encoding_field.rb +45 -0
- data/lib/mail/fields/content_type_field.rb +175 -0
- data/lib/mail/fields/date_field.rb +53 -0
- data/lib/mail/fields/from_field.rb +53 -0
- data/lib/mail/fields/in_reply_to_field.rb +52 -0
- data/lib/mail/fields/keywords_field.rb +43 -0
- data/lib/mail/fields/message_id_field.rb +80 -0
- data/lib/mail/fields/mime_version_field.rb +54 -0
- data/lib/mail/fields/optional_field.rb +11 -0
- data/lib/mail/fields/received_field.rb +62 -0
- data/lib/mail/fields/references_field.rb +53 -0
- data/lib/mail/fields/reply_to_field.rb +53 -0
- data/lib/mail/fields/resent_bcc_field.rb +53 -0
- data/lib/mail/fields/resent_cc_field.rb +53 -0
- data/lib/mail/fields/resent_date_field.rb +33 -0
- data/lib/mail/fields/resent_from_field.rb +53 -0
- data/lib/mail/fields/resent_message_id_field.rb +32 -0
- data/lib/mail/fields/resent_sender_field.rb +60 -0
- data/lib/mail/fields/resent_to_field.rb +53 -0
- data/lib/mail/fields/return_path_field.rb +62 -0
- data/lib/mail/fields/sender_field.rb +65 -0
- data/lib/mail/fields/structured_field.rb +36 -0
- data/lib/mail/fields/subject_field.rb +15 -0
- data/lib/mail/fields/to_field.rb +53 -0
- data/lib/mail/fields/unstructured_field.rb +117 -0
- data/lib/mail/header.rb +235 -0
- data/lib/mail/mail.rb +194 -0
- data/lib/mail/message.rb +1780 -0
- data/lib/mail/network/delivery_methods/file_delivery.rb +40 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +62 -0
- data/lib/mail/network/delivery_methods/smtp.rb +110 -0
- data/lib/mail/network/delivery_methods/test_mailer.rb +40 -0
- data/lib/mail/network/retriever_methods/imap.rb +31 -0
- data/lib/mail/network/retriever_methods/pop3.rb +149 -0
- data/lib/mail/parsers/address_lists.rb +61 -0
- data/lib/mail/parsers/address_lists.treetop +19 -0
- data/lib/mail/parsers/content_disposition.rb +369 -0
- data/lib/mail/parsers/content_disposition.treetop +46 -0
- data/lib/mail/parsers/content_location.rb +133 -0
- data/lib/mail/parsers/content_location.treetop +20 -0
- data/lib/mail/parsers/content_transfer_encoding.rb +179 -0
- data/lib/mail/parsers/content_transfer_encoding.treetop +25 -0
- data/lib/mail/parsers/content_type.rb +512 -0
- data/lib/mail/parsers/content_type.treetop +58 -0
- data/lib/mail/parsers/date_time.rb +111 -0
- data/lib/mail/parsers/date_time.treetop +11 -0
- data/lib/mail/parsers/envelope_from.rb +188 -0
- data/lib/mail/parsers/envelope_from.treetop +32 -0
- data/lib/mail/parsers/message_ids.rb +42 -0
- data/lib/mail/parsers/message_ids.treetop +15 -0
- data/lib/mail/parsers/mime_version.rb +141 -0
- data/lib/mail/parsers/mime_version.treetop +19 -0
- data/lib/mail/parsers/phrase_lists.rb +42 -0
- data/lib/mail/parsers/phrase_lists.treetop +15 -0
- data/lib/mail/parsers/received.rb +68 -0
- data/lib/mail/parsers/received.treetop +11 -0
- data/lib/mail/parsers/rfc2045.rb +406 -0
- data/lib/mail/parsers/rfc2045.treetop +35 -0
- data/lib/mail/parsers/rfc2822.rb +5081 -0
- data/lib/mail/parsers/rfc2822.treetop +410 -0
- data/lib/mail/parsers/rfc2822_obsolete.rb +3607 -0
- data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
- data/lib/mail/part.rb +82 -0
- data/lib/mail/parts_list.rb +34 -0
- data/lib/mail/patterns.rb +43 -0
- data/lib/mail/utilities.rb +163 -0
- data/lib/mail/vendor/treetop.rb +4 -0
- data/lib/mail/version.rb +10 -0
- data/lib/mail/version_specific/ruby_1_8.rb +84 -0
- data/lib/mail/version_specific/ruby_1_9.rb +77 -0
- data/lib/tasks/corpus.rake +125 -0
- data/lib/tasks/treetop.rake +10 -0
- metadata +188 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = Resent-From Field
|
|
4
|
+
#
|
|
5
|
+
# The Resent-From field inherits resent-from StructuredField and handles the Resent-From: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending resent_from to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a ResentFromField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Only one Resent-From field can appear in a header, though it can have multiple
|
|
13
|
+
# addresses and groups of addresses.
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# mail = Mail.new
|
|
18
|
+
# mail.resent_from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
+
# mail.resent_from #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
20
|
+
# mail[:resent_from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
|
|
21
|
+
# mail['resent-from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
|
|
22
|
+
# mail['Resent-From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
# mail[:resent_from].encoded #=> 'Resent-From: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
25
|
+
# mail[:resent_from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
26
|
+
# mail[:resent_from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
27
|
+
# mail[:resent_from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
28
|
+
#
|
|
29
|
+
module Mail
|
|
30
|
+
class ResentFromField < StructuredField
|
|
31
|
+
|
|
32
|
+
include Mail::CommonAddress
|
|
33
|
+
|
|
34
|
+
FIELD_NAME = 'resent-from'
|
|
35
|
+
CAPITALIZED_FIELD = 'Resent-From'
|
|
36
|
+
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
39
|
+
self.parse
|
|
40
|
+
self
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def encoded
|
|
45
|
+
do_encode(CAPITALIZED_FIELD)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def decoded
|
|
49
|
+
do_decode
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# resent-msg-id = "Resent-Message-ID:" msg-id CRLF
|
|
4
|
+
module Mail
|
|
5
|
+
class ResentMessageIdField < StructuredField
|
|
6
|
+
|
|
7
|
+
include CommonMessageId
|
|
8
|
+
|
|
9
|
+
FIELD_NAME = 'resent-message-id'
|
|
10
|
+
CAPITALIZED_FIELD = 'Resent-Message-ID'
|
|
11
|
+
|
|
12
|
+
def initialize(*args)
|
|
13
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
14
|
+
self.parse
|
|
15
|
+
self
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name
|
|
20
|
+
'Resent-Message-ID'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def encoded
|
|
24
|
+
do_encode(CAPITALIZED_FIELD)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def decoded
|
|
28
|
+
do_decode
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = Resent-Sender Field
|
|
4
|
+
#
|
|
5
|
+
# The Resent-Sender field inherits resent-sender StructuredField and handles the Resent-Sender: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending resent_sender to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a ResentSenderField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Only one Resent-Sender field can appear in a header, though it can have multiple
|
|
13
|
+
# addresses and groups of addresses.
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# mail = Mail.new
|
|
18
|
+
# mail.resent_sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
+
# mail.resent_sender #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
20
|
+
# mail[:resent_sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
21
|
+
# mail['resent-sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
22
|
+
# mail['Resent-Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
# mail.resent_sender.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
25
|
+
# mail.resent_sender.addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
26
|
+
# mail.resent_sender.formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
27
|
+
#
|
|
28
|
+
module Mail
|
|
29
|
+
class ResentSenderField < StructuredField
|
|
30
|
+
|
|
31
|
+
include Mail::CommonAddress
|
|
32
|
+
|
|
33
|
+
FIELD_NAME = 'resent-sender'
|
|
34
|
+
CAPITALIZED_FIELD = 'Resent-Sender'
|
|
35
|
+
|
|
36
|
+
def initialize(*args)
|
|
37
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
38
|
+
self.parse
|
|
39
|
+
self
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def addresses
|
|
44
|
+
[address.address]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def address
|
|
48
|
+
result = tree.addresses.first
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def encoded
|
|
52
|
+
do_encode(CAPITALIZED_FIELD)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def decoded
|
|
56
|
+
do_decode
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = Resent-To Field
|
|
4
|
+
#
|
|
5
|
+
# The Resent-To field inherits resent-to StructuredField and handles the Resent-To: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending resent_to to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a ResentToField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Only one Resent-To field can appear in a header, though it can have multiple
|
|
13
|
+
# addresses and groups of addresses.
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# mail = Mail.new
|
|
18
|
+
# mail.resent_to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
+
# mail.resent_to #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
20
|
+
# mail[:resent_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
|
|
21
|
+
# mail['resent-to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
|
|
22
|
+
# mail['Resent-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
# mail[:resent_to].encoded #=> 'Resent-To: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
25
|
+
# mail[:resent_to].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
26
|
+
# mail[:resent_to].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
27
|
+
# mail[:resent_to].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
28
|
+
#
|
|
29
|
+
module Mail
|
|
30
|
+
class ResentToField < StructuredField
|
|
31
|
+
|
|
32
|
+
include Mail::CommonAddress
|
|
33
|
+
|
|
34
|
+
FIELD_NAME = 'resent-to'
|
|
35
|
+
CAPITALIZED_FIELD = 'Resent-To'
|
|
36
|
+
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
39
|
+
self.parse
|
|
40
|
+
self
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def encoded
|
|
45
|
+
do_encode(CAPITALIZED_FIELD)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def decoded
|
|
49
|
+
do_decode
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# 4.4.3. REPLY-TO / RESENT-REPLY-TO
|
|
4
|
+
#
|
|
5
|
+
# Note: The "Return-Path" field is added by the mail transport
|
|
6
|
+
# service, at the time of final deliver. It is intended
|
|
7
|
+
# to identify a path back to the orginator of the mes-
|
|
8
|
+
# sage. The "Reply-To" field is added by the message
|
|
9
|
+
# originator and is intended to direct replies.
|
|
10
|
+
#
|
|
11
|
+
# trace = [return]
|
|
12
|
+
# 1*received
|
|
13
|
+
#
|
|
14
|
+
# return = "Return-Path:" path CRLF
|
|
15
|
+
#
|
|
16
|
+
# path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
|
|
17
|
+
# obs-path
|
|
18
|
+
#
|
|
19
|
+
# received = "Received:" name-val-list ";" date-time CRLF
|
|
20
|
+
#
|
|
21
|
+
# name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
|
|
22
|
+
#
|
|
23
|
+
# name-val-pair = item-name CFWS item-value
|
|
24
|
+
#
|
|
25
|
+
# item-name = ALPHA *(["-"] (ALPHA / DIGIT))
|
|
26
|
+
#
|
|
27
|
+
# item-value = 1*angle-addr / addr-spec /
|
|
28
|
+
# atom / domain / msg-id
|
|
29
|
+
#
|
|
30
|
+
module Mail
|
|
31
|
+
class ReturnPathField < StructuredField
|
|
32
|
+
|
|
33
|
+
include Mail::CommonAddress
|
|
34
|
+
|
|
35
|
+
FIELD_NAME = 'return-path'
|
|
36
|
+
CAPITALIZED_FIELD = 'Return-Path'
|
|
37
|
+
|
|
38
|
+
def initialize(*args)
|
|
39
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
40
|
+
self.parse
|
|
41
|
+
self
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def encoded
|
|
46
|
+
"#{CAPITALIZED_FIELD}: <#{address}>\r\n"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def decoded
|
|
50
|
+
do_decode
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def address
|
|
54
|
+
addresses.first
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def default
|
|
58
|
+
address
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = Sender Field
|
|
4
|
+
#
|
|
5
|
+
# The Sender field inherits sender StructuredField and handles the Sender: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending sender to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a SenderField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Only one Sender field can appear in a header, though it can have multiple
|
|
13
|
+
# addresses and groups of addresses.
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# mail = Mail.new
|
|
18
|
+
# mail.sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
+
# mail.sender #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
20
|
+
# mail[:sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
|
|
21
|
+
# mail['sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
|
|
22
|
+
# mail['Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
# mail[:sender].encoded #=> 'Sender: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
25
|
+
# mail[:sender].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
26
|
+
# mail[:sender].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
27
|
+
# mail[:sender].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
28
|
+
#
|
|
29
|
+
module Mail
|
|
30
|
+
class SenderField < StructuredField
|
|
31
|
+
|
|
32
|
+
include Mail::CommonAddress
|
|
33
|
+
|
|
34
|
+
FIELD_NAME = 'sender'
|
|
35
|
+
CAPITALIZED_FIELD = 'Sender'
|
|
36
|
+
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
39
|
+
self.parse
|
|
40
|
+
self
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def addresses
|
|
45
|
+
[address.address]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def address
|
|
49
|
+
result = tree.addresses.first
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def encoded
|
|
53
|
+
do_encode(CAPITALIZED_FIELD)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def decoded
|
|
57
|
+
do_decode
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def default
|
|
61
|
+
address.address
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mail
|
|
3
|
+
# Provides access to a structured header field
|
|
4
|
+
#
|
|
5
|
+
# ===Per RFC 2822:
|
|
6
|
+
# 2.2.2. Structured Header Field Bodies
|
|
7
|
+
#
|
|
8
|
+
# Some field bodies in this standard have specific syntactical
|
|
9
|
+
# structure more restrictive than the unstructured field bodies
|
|
10
|
+
# described above. These are referred to as "structured" field bodies.
|
|
11
|
+
# Structured field bodies are sequences of specific lexical tokens as
|
|
12
|
+
# described in sections 3 and 4 of this standard. Many of these tokens
|
|
13
|
+
# are allowed (according to their syntax) to be introduced or end with
|
|
14
|
+
# comments (as described in section 3.2.3) as well as the space (SP,
|
|
15
|
+
# ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters
|
|
16
|
+
# (together known as the white space characters, WSP), and those WSP
|
|
17
|
+
# characters are subject to header "folding" and "unfolding" as
|
|
18
|
+
# described in section 2.2.3. Semantic analysis of structured field
|
|
19
|
+
# bodies is given along with their syntax.
|
|
20
|
+
class StructuredField
|
|
21
|
+
|
|
22
|
+
include Mail::CommonField
|
|
23
|
+
include Mail::Utilities
|
|
24
|
+
|
|
25
|
+
def initialize(*args)
|
|
26
|
+
self.name = args.first
|
|
27
|
+
self.value = args.last
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def default
|
|
32
|
+
decoded
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# subject = "Subject:" unstructured CRLF
|
|
4
|
+
module Mail
|
|
5
|
+
class SubjectField < UnstructuredField
|
|
6
|
+
|
|
7
|
+
FIELD_NAME = 'subject'
|
|
8
|
+
CAPITALIZED_FIELD = "Subject"
|
|
9
|
+
|
|
10
|
+
def initialize(*args)
|
|
11
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = To Field
|
|
4
|
+
#
|
|
5
|
+
# The To field inherits to StructuredField and handles the To: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending to to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a ToField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Only one To field can appear in a header, though it can have multiple
|
|
13
|
+
# addresses and groups of addresses.
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# mail = Mail.new
|
|
18
|
+
# mail.to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
+
# mail.to #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
20
|
+
# mail[:to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
|
|
21
|
+
# mail['to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
|
|
22
|
+
# mail['To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
# mail[:to].encoded #=> 'To: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
25
|
+
# mail[:to].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
26
|
+
# mail[:to].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
27
|
+
# mail[:to].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
28
|
+
#
|
|
29
|
+
module Mail
|
|
30
|
+
class ToField < StructuredField
|
|
31
|
+
|
|
32
|
+
include Mail::CommonAddress
|
|
33
|
+
|
|
34
|
+
FIELD_NAME = 'to'
|
|
35
|
+
CAPITALIZED_FIELD = 'To'
|
|
36
|
+
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
39
|
+
self.parse
|
|
40
|
+
self
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def encoded
|
|
45
|
+
do_encode(CAPITALIZED_FIELD)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def decoded
|
|
49
|
+
do_decode
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mail
|
|
3
|
+
# Provides access to an unstructured header field
|
|
4
|
+
#
|
|
5
|
+
# ===Per RFC 2822:
|
|
6
|
+
# 2.2.1. Unstructured Header Field Bodies
|
|
7
|
+
#
|
|
8
|
+
# Some field bodies in this standard are defined simply as
|
|
9
|
+
# "unstructured" (which is specified below as any US-ASCII characters,
|
|
10
|
+
# except for CR and LF) with no further restrictions. These are
|
|
11
|
+
# referred to as unstructured field bodies. Semantically, unstructured
|
|
12
|
+
# field bodies are simply to be treated as a single line of characters
|
|
13
|
+
# with no further processing (except for header "folding" and
|
|
14
|
+
# "unfolding" as described in section 2.2.3).
|
|
15
|
+
class UnstructuredField
|
|
16
|
+
|
|
17
|
+
include Mail::CommonField
|
|
18
|
+
include Mail::Utilities
|
|
19
|
+
|
|
20
|
+
def initialize(*args)
|
|
21
|
+
self.name = args.first
|
|
22
|
+
self.value = args.last
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def encoded
|
|
27
|
+
do_encode(self.name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def decoded
|
|
31
|
+
do_decode
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def default
|
|
35
|
+
decoded
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def parse # An unstructured field does not parse
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def do_encode(name)
|
|
45
|
+
value.nil? ? '' : "#{wrapped_value}\r\n"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def do_decode
|
|
49
|
+
value.blank? ? nil : Encodings.decode_encode(value, :decode)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# 2.2.3. Long Header Fields
|
|
53
|
+
#
|
|
54
|
+
# Each header field is logically a single line of characters comprising
|
|
55
|
+
# the field name, the colon, and the field body. For convenience
|
|
56
|
+
# however, and to deal with the 998/78 character limitations per line,
|
|
57
|
+
# the field body portion of a header field can be split into a multiple
|
|
58
|
+
# line representation; this is called "folding". The general rule is
|
|
59
|
+
# that wherever this standard allows for folding white space (not
|
|
60
|
+
# simply WSP characters), a CRLF may be inserted before any WSP. For
|
|
61
|
+
# example, the header field:
|
|
62
|
+
#
|
|
63
|
+
# Subject: This is a test
|
|
64
|
+
#
|
|
65
|
+
# can be represented as:
|
|
66
|
+
#
|
|
67
|
+
# Subject: This
|
|
68
|
+
# is a test
|
|
69
|
+
#
|
|
70
|
+
# Note: Though structured field bodies are defined in such a way that
|
|
71
|
+
# folding can take place between many of the lexical tokens (and even
|
|
72
|
+
# within some of the lexical tokens), folding SHOULD be limited to
|
|
73
|
+
# placing the CRLF at higher-level syntactic breaks. For instance, if
|
|
74
|
+
# a field body is defined as comma-separated values, it is recommended
|
|
75
|
+
# that folding occur after the comma separating the structured items in
|
|
76
|
+
# preference to other places where the field could be folded, even if
|
|
77
|
+
# it is allowed elsewhere.
|
|
78
|
+
def wrapped_value # :nodoc:
|
|
79
|
+
case
|
|
80
|
+
when decoded.to_s.ascii_only? && field_length <= 78
|
|
81
|
+
"#{name}: #{value}"
|
|
82
|
+
when field_length <= 40 # Allow for =?ISO-8859-1?B?=...=
|
|
83
|
+
"#{name}: #{encode(value)}"
|
|
84
|
+
else
|
|
85
|
+
@folded_line = []
|
|
86
|
+
@unfolded_line = value.clone
|
|
87
|
+
fold("#{name}: ".length)
|
|
88
|
+
folded = @folded_line.map { |l| l unless l.blank? }.compact.join("\r\n\t")
|
|
89
|
+
"#{name}: #{folded}"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def fold(prepend = 0) # :nodoc:
|
|
94
|
+
# Get the last whitespace character, OR we'll just choose
|
|
95
|
+
# 78 if there is no whitespace
|
|
96
|
+
@unfolded_line.ascii_only? ? (limit = 78 - prepend) : (limit = 40 - prepend)
|
|
97
|
+
wspp = @unfolded_line.slice(0..limit) =~ /[ \t][^ \T]*$/ || limit
|
|
98
|
+
wspp = limit if wspp == 0
|
|
99
|
+
@folded_line << encode(@unfolded_line.slice!(0...wspp))
|
|
100
|
+
if @unfolded_line.length > limit
|
|
101
|
+
fold
|
|
102
|
+
else
|
|
103
|
+
@folded_line << encode(@unfolded_line)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def encode(value)
|
|
108
|
+
if value.ascii_only?
|
|
109
|
+
value
|
|
110
|
+
else
|
|
111
|
+
RUBY_VERSION < '1.9' ? encoding = $KCODE : encoding = @value.encoding
|
|
112
|
+
Encodings.b_value_encode(value, encoding)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|