mail 2.4.4 → 2.6.3
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 +7 -0
- data/CHANGELOG.rdoc +156 -0
- data/CONTRIBUTING.md +21 -6
- data/Dependencies.txt +0 -1
- data/Gemfile +10 -21
- data/MIT-LICENSE +20 -0
- data/README.md +52 -32
- data/Rakefile +11 -22
- data/lib/mail/attachments_list.rb +2 -2
- data/lib/mail/body.rb +33 -9
- data/lib/mail/check_delivery_params.rb +20 -0
- data/lib/mail/configuration.rb +1 -1
- data/lib/mail/{patterns.rb → constants.rb} +26 -6
- data/lib/mail/core_extensions/nil.rb +4 -2
- data/lib/mail/core_extensions/object.rb +8 -8
- data/lib/mail/core_extensions/smtp.rb +12 -13
- data/lib/mail/core_extensions/string.rb +19 -6
- data/lib/mail/elements/address.rb +82 -141
- data/lib/mail/elements/address_list.rb +9 -42
- data/lib/mail/elements/content_disposition_element.rb +3 -7
- data/lib/mail/elements/content_location_element.rb +2 -6
- data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
- data/lib/mail/elements/content_type_element.rb +4 -8
- data/lib/mail/elements/date_time_element.rb +3 -7
- data/lib/mail/elements/envelope_from_element.rb +18 -13
- data/lib/mail/elements/message_ids_element.rb +1 -6
- data/lib/mail/elements/mime_version_element.rb +3 -7
- data/lib/mail/elements/phrase_list.rb +2 -7
- data/lib/mail/elements/received_element.rb +3 -7
- data/lib/mail/elements.rb +12 -12
- data/lib/mail/encodings/quoted_printable.rb +4 -3
- data/lib/mail/encodings/unix_to_unix.rb +17 -0
- data/lib/mail/encodings.rb +53 -38
- data/lib/mail/envelope.rb +0 -5
- data/lib/mail/field.rb +131 -118
- data/lib/mail/field_list.rb +18 -18
- data/lib/mail/fields/bcc_field.rb +2 -2
- data/lib/mail/fields/cc_field.rb +2 -2
- data/lib/mail/fields/comments_field.rb +1 -1
- data/lib/mail/fields/common/common_address.rb +32 -22
- data/lib/mail/fields/common/common_date.rb +0 -7
- data/lib/mail/fields/common/common_field.rb +10 -3
- data/lib/mail/fields/common/common_message_id.rb +9 -5
- data/lib/mail/fields/common/parameter_hash.rb +3 -3
- data/lib/mail/fields/content_disposition_field.rb +1 -0
- data/lib/mail/fields/content_id_field.rb +1 -2
- data/lib/mail/fields/content_transfer_encoding_field.rb +2 -8
- data/lib/mail/fields/content_type_field.rb +5 -2
- data/lib/mail/fields/date_field.rb +14 -14
- data/lib/mail/fields/from_field.rb +2 -2
- data/lib/mail/fields/in_reply_to_field.rb +2 -1
- data/lib/mail/fields/keywords_field.rb +1 -1
- data/lib/mail/fields/message_id_field.rb +2 -3
- data/lib/mail/fields/references_field.rb +2 -1
- data/lib/mail/fields/reply_to_field.rb +2 -2
- data/lib/mail/fields/resent_bcc_field.rb +2 -2
- data/lib/mail/fields/resent_cc_field.rb +2 -2
- data/lib/mail/fields/resent_from_field.rb +2 -2
- data/lib/mail/fields/resent_sender_field.rb +3 -3
- data/lib/mail/fields/resent_to_field.rb +2 -2
- data/lib/mail/fields/sender_field.rb +8 -8
- data/lib/mail/fields/to_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +44 -31
- data/lib/mail/fields.rb +32 -32
- data/lib/mail/header.rb +47 -37
- data/lib/mail/mail.rb +15 -1
- data/lib/mail/matchers/has_sent_mail.rb +36 -3
- data/lib/mail/message.rb +164 -57
- data/lib/mail/multibyte/chars.rb +4 -4
- data/lib/mail/multibyte/unicode.rb +9 -1
- data/lib/mail/network/delivery_methods/exim.rb +2 -3
- data/lib/mail/network/delivery_methods/file_delivery.rb +5 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +35 -8
- data/lib/mail/network/delivery_methods/smtp.rb +34 -45
- data/lib/mail/network/delivery_methods/smtp_connection.rb +9 -22
- data/lib/mail/network/delivery_methods/test_mailer.rb +6 -2
- data/lib/mail/network/retriever_methods/imap.rb +32 -19
- data/lib/mail/network/retriever_methods/pop3.rb +2 -2
- data/lib/mail/network/retriever_methods/test_retriever.rb +11 -15
- data/lib/mail/network.rb +9 -9
- data/lib/mail/parsers/address_lists_parser.rb +132 -0
- data/lib/mail/parsers/content_disposition_parser.rb +67 -0
- data/lib/mail/parsers/content_location_parser.rb +35 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
- data/lib/mail/parsers/content_type_parser.rb +66 -0
- data/lib/mail/parsers/date_time_parser.rb +36 -0
- data/lib/mail/parsers/envelope_from_parser.rb +45 -0
- data/lib/mail/parsers/message_ids_parser.rb +39 -0
- data/lib/mail/parsers/mime_version_parser.rb +41 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
- data/lib/mail/parsers/ragel/common.rl +185 -0
- data/lib/mail/parsers/ragel/date_time.rl +30 -0
- data/lib/mail/parsers/ragel/parser_info.rb +61 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2149 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
- data/lib/mail/parsers/ragel/ruby.rb +40 -0
- data/lib/mail/parsers/ragel.rb +17 -0
- data/lib/mail/parsers/received_parser.rb +47 -0
- data/lib/mail/parsers.rb +26 -0
- data/lib/mail/part.rb +6 -2
- data/lib/mail/parts_list.rb +5 -3
- data/lib/mail/utilities.rb +70 -60
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +7 -15
- data/lib/mail/version_specific/ruby_1_8.rb +25 -4
- data/lib/mail/version_specific/ruby_1_9.rb +110 -30
- data/lib/mail.rb +20 -19
- metadata +129 -73
- data/Gemfile.lock +0 -36
- data/lib/VERSION +0 -4
- data/lib/mail/core_extensions/shell_escape.rb +0 -56
- data/lib/mail/parsers/address_lists.rb +0 -64
- data/lib/mail/parsers/address_lists.treetop +0 -19
- data/lib/mail/parsers/content_disposition.rb +0 -535
- data/lib/mail/parsers/content_disposition.treetop +0 -46
- data/lib/mail/parsers/content_location.rb +0 -139
- data/lib/mail/parsers/content_location.treetop +0 -20
- data/lib/mail/parsers/content_transfer_encoding.rb +0 -162
- data/lib/mail/parsers/content_transfer_encoding.treetop +0 -20
- data/lib/mail/parsers/content_type.rb +0 -967
- data/lib/mail/parsers/content_type.treetop +0 -68
- data/lib/mail/parsers/date_time.rb +0 -114
- data/lib/mail/parsers/date_time.treetop +0 -11
- data/lib/mail/parsers/envelope_from.rb +0 -194
- data/lib/mail/parsers/envelope_from.treetop +0 -32
- data/lib/mail/parsers/message_ids.rb +0 -45
- data/lib/mail/parsers/message_ids.treetop +0 -15
- data/lib/mail/parsers/mime_version.rb +0 -144
- data/lib/mail/parsers/mime_version.treetop +0 -19
- data/lib/mail/parsers/phrase_lists.rb +0 -45
- data/lib/mail/parsers/phrase_lists.treetop +0 -15
- data/lib/mail/parsers/received.rb +0 -71
- data/lib/mail/parsers/received.treetop +0 -11
- data/lib/mail/parsers/rfc2045.rb +0 -464
- data/lib/mail/parsers/rfc2045.treetop +0 -36
- data/lib/mail/parsers/rfc2822.rb +0 -5341
- data/lib/mail/parsers/rfc2822.treetop +0 -410
- data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
- data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
- data/lib/tasks/corpus.rake +0 -125
- data/lib/tasks/treetop.rake +0 -10
|
@@ -10,8 +10,8 @@ module Mail
|
|
|
10
10
|
|
|
11
11
|
def initialize(value = nil, charset = 'utf-8')
|
|
12
12
|
self.charset = charset
|
|
13
|
-
value = '7bit' if value.to_s =~ /7
|
|
14
|
-
value = '8bit' if value.to_s =~ /8
|
|
13
|
+
value = '7bit' if value.to_s =~ /7-?bits?/i
|
|
14
|
+
value = '8bit' if value.to_s =~ /8-?bits?/i
|
|
15
15
|
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
|
16
16
|
self.parse
|
|
17
17
|
self
|
|
@@ -23,12 +23,6 @@ module Mail
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def tree
|
|
27
|
-
STDERR.puts("tree is deprecated. Please use encoding to get parse result\n#{caller}")
|
|
28
|
-
@element ||= Mail::ContentTransferEncodingElement.new(value)
|
|
29
|
-
@tree ||= @element.tree
|
|
30
|
-
end
|
|
31
|
-
|
|
32
26
|
def element
|
|
33
27
|
@element ||= Mail::ContentTransferEncodingElement.new(value)
|
|
34
28
|
end
|
|
@@ -19,6 +19,7 @@ module Mail
|
|
|
19
19
|
@parameters = nil
|
|
20
20
|
value = strip_field(FIELD_NAME, value)
|
|
21
21
|
end
|
|
22
|
+
ensure_filename_quoted(value)
|
|
22
23
|
super(CAPITALIZED_FIELD, value, charset)
|
|
23
24
|
self.parse
|
|
24
25
|
self
|
|
@@ -141,7 +142,9 @@ module Mail
|
|
|
141
142
|
def sanatize( val )
|
|
142
143
|
|
|
143
144
|
# TODO: check if there are cases where whitespace is not a separator
|
|
144
|
-
val = val.
|
|
145
|
+
val = val.
|
|
146
|
+
gsub(/\s*=\s*/,'='). # remove whitespaces around equal sign
|
|
147
|
+
tr(' ',';').
|
|
145
148
|
squeeze(';').
|
|
146
149
|
gsub(';', '; '). #use '; ' as a separator (or EOL)
|
|
147
150
|
gsub(/;\s*$/,'') #remove trailing to keep examples below
|
|
@@ -177,7 +180,7 @@ module Mail
|
|
|
177
180
|
params = $2.to_s.split(/\s+/)
|
|
178
181
|
params = params.map { |i| i.to_s.chomp.strip }
|
|
179
182
|
params = params.map { |i| i.split(/\s*\=\s*/) }
|
|
180
|
-
params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s)}" }.join('; ')
|
|
183
|
+
params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
|
|
181
184
|
"#{type}; #{params}"
|
|
182
185
|
when val =~ /^\s*$/
|
|
183
186
|
'text/plain'
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
#
|
|
2
|
+
#
|
|
3
3
|
# = Date Field
|
|
4
|
-
#
|
|
4
|
+
#
|
|
5
5
|
# The Date field inherits from StructuredField and handles the Date: header
|
|
6
6
|
# field in the email.
|
|
7
|
-
#
|
|
7
|
+
#
|
|
8
8
|
# Sending date to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a DateField as
|
|
9
|
+
# has a DateField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance methods.
|
|
11
|
-
#
|
|
11
|
+
#
|
|
12
12
|
# There must be excatly one Date field in an RFC2822 email.
|
|
13
|
-
#
|
|
13
|
+
#
|
|
14
14
|
# == Examples:
|
|
15
|
-
#
|
|
15
|
+
#
|
|
16
16
|
# mail = Mail.new
|
|
17
17
|
# mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
18
18
|
# mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
|
|
@@ -20,17 +20,17 @@
|
|
|
20
20
|
# mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
21
21
|
# mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
22
22
|
# mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
23
|
-
#
|
|
23
|
+
#
|
|
24
24
|
require 'mail/fields/common/common_date'
|
|
25
25
|
|
|
26
26
|
module Mail
|
|
27
27
|
class DateField < StructuredField
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
include Mail::CommonDate
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
FIELD_NAME = 'date'
|
|
32
32
|
CAPITALIZED_FIELD = "Date"
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
def initialize(value = nil, charset = 'utf-8')
|
|
35
35
|
self.charset = charset
|
|
36
36
|
if value.blank?
|
|
@@ -44,14 +44,14 @@ module Mail
|
|
|
44
44
|
rescue ArgumentError => e
|
|
45
45
|
raise e unless "invalid date"==e.message
|
|
46
46
|
end
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
def encoded
|
|
49
49
|
do_encode(CAPITALIZED_FIELD)
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
def decoded
|
|
53
53
|
do_decode
|
|
54
54
|
end
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
end
|
|
57
57
|
end
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending from to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a FromField as
|
|
9
|
+
# has a FromField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one From field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.from #=> ['
|
|
19
|
+
# mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
21
21
|
# mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
22
22
|
# mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# In-Reply-To: header field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending in_reply_to to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a InReplyToField as
|
|
9
|
+
# has a InReplyToField as its field type. This includes all Mail::CommonMessageId
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Note that, the #message_ids method will return an array of message IDs without the
|
|
@@ -38,6 +38,7 @@ module Mail
|
|
|
38
38
|
|
|
39
39
|
def initialize(value = nil, charset = 'utf-8')
|
|
40
40
|
self.charset = charset
|
|
41
|
+
value = value.join("\r\n\s") if value.is_a?(Array)
|
|
41
42
|
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
|
42
43
|
self.parse
|
|
43
44
|
self
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Message-ID: header field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending message_id to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a MessageIdField as
|
|
9
|
+
# has a MessageIdField as its field type. This includes all Mail::CommonMessageId
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one MessageId field can appear in a header, and syntactically it can only have
|
|
@@ -75,8 +75,7 @@ module Mail
|
|
|
75
75
|
private
|
|
76
76
|
|
|
77
77
|
def generate_message_id
|
|
78
|
-
|
|
79
|
-
"<#{Mail.random_tag}@#{fqdn}.mail>"
|
|
78
|
+
"<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
|
|
80
79
|
end
|
|
81
80
|
|
|
82
81
|
end
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending references to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ReferencesField as
|
|
9
|
+
# has a ReferencesField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Note that, the #message_ids method will return an array of message IDs without the
|
|
@@ -38,6 +38,7 @@ module Mail
|
|
|
38
38
|
|
|
39
39
|
def initialize(value = nil, charset = 'utf-8')
|
|
40
40
|
self.charset = charset
|
|
41
|
+
value = value.join("\r\n\s") if value.is_a?(Array)
|
|
41
42
|
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
|
42
43
|
self.parse
|
|
43
44
|
self
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending reply_to to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ReplyToField as
|
|
9
|
+
# has a ReplyToField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Reply-To field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.reply_to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.reply_to #=> ['
|
|
19
|
+
# mail.reply_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ReplyToField:0x180e1c4
|
|
21
21
|
# mail['reply-to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ReplyToField:0x180e1c4
|
|
22
22
|
# mail['Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ReplyToField:0x180e1c4
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Resent-Bcc: header field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending resent_bcc to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ResentBccField as
|
|
9
|
+
# has a ResentBccField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Resent-Bcc field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.resent_bcc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.resent_bcc #=> ['
|
|
19
|
+
# mail.resent_bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:resent_bcc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentBccField:0x180e1c4
|
|
21
21
|
# mail['resent-bcc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentBccField:0x180e1c4
|
|
22
22
|
# mail['Resent-Bcc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentBccField:0x180e1c4
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending resent_cc to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ResentCcField as
|
|
9
|
+
# has a ResentCcField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Resent-Cc field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.resent_cc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.resent_cc #=> ['
|
|
19
|
+
# mail.resent_cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:resent_cc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentCcField:0x180e1c4
|
|
21
21
|
# mail['resent-cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentCcField:0x180e1c4
|
|
22
22
|
# mail['Resent-Cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentCcField:0x180e1c4
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending resent_from to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ResentFromField as
|
|
9
|
+
# has a ResentFromField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Resent-From field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.resent_from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.resent_from #=> ['
|
|
19
|
+
# mail.resent_from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:resent_from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
|
|
21
21
|
# mail['resent-from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
|
|
22
22
|
# mail['Resent-From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending resent_sender to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ResentSenderField as
|
|
9
|
+
# has a ResentSenderField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Resent-Sender field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.resent_sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.resent_sender #=> '
|
|
19
|
+
# mail.resent_sender #=> ['mikel@test.lindsaar.net']
|
|
20
20
|
# mail[:resent_sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
21
21
|
# mail['resent-sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
22
22
|
# mail['Resent-Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
|
|
@@ -47,7 +47,7 @@ module Mail
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def address
|
|
50
|
-
|
|
50
|
+
address_list.addresses.first
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def encoded
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending resent_to to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ResentToField as
|
|
9
|
+
# has a ResentToField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Resent-To field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.resent_to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.resent_to #=> ['
|
|
19
|
+
# mail.resent_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:resent_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
|
|
21
21
|
# mail['resent-to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
|
|
22
22
|
# mail['Resent-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending sender to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a SenderField as
|
|
9
|
+
# has a SenderField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one Sender field can appear in a header, though it can have multiple
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
# == Examples:
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
|
-
# mail.sender = 'Mikel Lindsaar <mikel@test.lindsaar.net
|
|
19
|
-
# mail.sender #=>
|
|
18
|
+
# mail.sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>'
|
|
19
|
+
# mail.sender #=> 'mikel@test.lindsaar.net'
|
|
20
20
|
# mail[:sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
|
|
21
21
|
# mail['sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
|
|
22
22
|
# mail['Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
|
|
23
23
|
#
|
|
24
|
-
# mail[:sender].encoded #=>
|
|
25
|
-
# mail[:sender].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net
|
|
26
|
-
# mail[:sender].addresses #=> ['mikel@test.lindsaar.net'
|
|
27
|
-
# mail[:sender].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>'
|
|
24
|
+
# mail[:sender].encoded #=> "Sender: Mikel Lindsaar <mikel@test.lindsaar.net>\r\n"
|
|
25
|
+
# mail[:sender].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>'
|
|
26
|
+
# mail[:sender].addresses #=> ['mikel@test.lindsaar.net']
|
|
27
|
+
# mail[:sender].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>']
|
|
28
28
|
#
|
|
29
29
|
require 'mail/fields/common/common_address'
|
|
30
30
|
|
|
@@ -48,7 +48,7 @@ module Mail
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def address
|
|
51
|
-
|
|
51
|
+
address_list.addresses.first
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def encoded
|
data/lib/mail/fields/to_field.rb
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# field in the email.
|
|
7
7
|
#
|
|
8
8
|
# Sending to to a mail message will instantiate a Mail::Field object that
|
|
9
|
-
# has a ToField as
|
|
9
|
+
# has a ToField as its field type. This includes all Mail::CommonAddress
|
|
10
10
|
# module instance metods.
|
|
11
11
|
#
|
|
12
12
|
# Only one To field can appear in a header, though it can have multiple
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# mail = Mail.new
|
|
18
18
|
# mail.to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
-
# mail.to #=> ['
|
|
19
|
+
# mail.to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
20
20
|
# mail[:to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
|
|
21
21
|
# mail['to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
|
|
22
22
|
# mail['To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
|
|
@@ -6,7 +6,7 @@ module Mail
|
|
|
6
6
|
#
|
|
7
7
|
# ===Per RFC 2822:
|
|
8
8
|
# 2.2.1. Unstructured Header Field Bodies
|
|
9
|
-
#
|
|
9
|
+
#
|
|
10
10
|
# Some field bodies in this standard are defined simply as
|
|
11
11
|
# "unstructured" (which is specified below as any US-ASCII characters,
|
|
12
12
|
# except for CR and LF) with no further restrictions. These are
|
|
@@ -15,20 +15,29 @@ module Mail
|
|
|
15
15
|
# with no further processing (except for header "folding" and
|
|
16
16
|
# "unfolding" as described in section 2.2.3).
|
|
17
17
|
class UnstructuredField
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
include Mail::CommonField
|
|
20
20
|
include Mail::Utilities
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
attr_accessor :charset
|
|
23
23
|
attr_reader :errors
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
def initialize(name, value, charset = nil)
|
|
26
26
|
@errors = []
|
|
27
|
+
|
|
28
|
+
if value.is_a?(Array)
|
|
29
|
+
# Probably has arrived here from a failed parse of an AddressList Field
|
|
30
|
+
value = value.join(', ')
|
|
31
|
+
else
|
|
32
|
+
# Ensure we are dealing with a string
|
|
33
|
+
value = value.to_s
|
|
34
|
+
end
|
|
35
|
+
|
|
27
36
|
if charset
|
|
28
37
|
self.charset = charset
|
|
29
38
|
else
|
|
30
|
-
if value.
|
|
31
|
-
self.charset = value.
|
|
39
|
+
if value.respond_to?(:encoding)
|
|
40
|
+
self.charset = value.encoding
|
|
32
41
|
else
|
|
33
42
|
self.charset = $KCODE
|
|
34
43
|
end
|
|
@@ -37,11 +46,11 @@ module Mail
|
|
|
37
46
|
self.value = value
|
|
38
47
|
self
|
|
39
48
|
end
|
|
40
|
-
|
|
49
|
+
|
|
41
50
|
def encoded
|
|
42
51
|
do_encode
|
|
43
52
|
end
|
|
44
|
-
|
|
53
|
+
|
|
45
54
|
def decoded
|
|
46
55
|
do_decode
|
|
47
56
|
end
|
|
@@ -49,25 +58,23 @@ module Mail
|
|
|
49
58
|
def default
|
|
50
59
|
decoded
|
|
51
60
|
end
|
|
52
|
-
|
|
61
|
+
|
|
53
62
|
def parse # An unstructured field does not parse
|
|
54
63
|
self
|
|
55
64
|
end
|
|
56
65
|
|
|
57
66
|
private
|
|
58
|
-
|
|
67
|
+
|
|
59
68
|
def do_encode
|
|
60
69
|
value.nil? ? '' : "#{wrapped_value}\r\n"
|
|
61
70
|
end
|
|
62
|
-
|
|
71
|
+
|
|
63
72
|
def do_decode
|
|
64
|
-
|
|
65
|
-
result.encode!(value.encoding || "UTF-8") if RUBY_VERSION >= '1.9' && !result.blank?
|
|
66
|
-
result
|
|
73
|
+
value.blank? ? nil : Encodings.decode_encode(value, :decode)
|
|
67
74
|
end
|
|
68
|
-
|
|
75
|
+
|
|
69
76
|
# 2.2.3. Long Header Fields
|
|
70
|
-
#
|
|
77
|
+
#
|
|
71
78
|
# Each header field is logically a single line of characters comprising
|
|
72
79
|
# the field name, the colon, and the field body. For convenience
|
|
73
80
|
# however, and to deal with the 998/78 character limitations per line,
|
|
@@ -76,14 +83,14 @@ module Mail
|
|
|
76
83
|
# that wherever this standard allows for folding white space (not
|
|
77
84
|
# simply WSP characters), a CRLF may be inserted before any WSP. For
|
|
78
85
|
# example, the header field:
|
|
79
|
-
#
|
|
86
|
+
#
|
|
80
87
|
# Subject: This is a test
|
|
81
|
-
#
|
|
88
|
+
#
|
|
82
89
|
# can be represented as:
|
|
83
|
-
#
|
|
90
|
+
#
|
|
84
91
|
# Subject: This
|
|
85
92
|
# is a test
|
|
86
|
-
#
|
|
93
|
+
#
|
|
87
94
|
# Note: Though structured field bodies are defined in such a way that
|
|
88
95
|
# folding can take place between many of the lexical tokens (and even
|
|
89
96
|
# within some of the lexical tokens), folding SHOULD be limited to
|
|
@@ -95,9 +102,9 @@ module Mail
|
|
|
95
102
|
def wrapped_value # :nodoc:
|
|
96
103
|
wrap_lines(name, fold("#{name}: ".length))
|
|
97
104
|
end
|
|
98
|
-
|
|
105
|
+
|
|
99
106
|
# 6.2. Display of 'encoded-word's
|
|
100
|
-
#
|
|
107
|
+
#
|
|
101
108
|
# When displaying a particular header field that contains multiple
|
|
102
109
|
# 'encoded-word's, any 'linear-white-space' that separates a pair of
|
|
103
110
|
# adjacent 'encoded-word's is ignored. (This is to allow the use of
|
|
@@ -131,29 +138,35 @@ module Mail
|
|
|
131
138
|
else
|
|
132
139
|
words = decoded_string.split(/[ \t]/)
|
|
133
140
|
end
|
|
134
|
-
|
|
141
|
+
|
|
135
142
|
folded_lines = []
|
|
136
143
|
while !words.empty?
|
|
137
144
|
limit = 78 - prepend
|
|
138
145
|
limit = limit - 7 - encoding.length if should_encode
|
|
139
146
|
line = ""
|
|
147
|
+
first_word = true
|
|
140
148
|
while !words.empty?
|
|
141
149
|
break unless word = words.first.dup
|
|
142
|
-
word.encode!(charset) if
|
|
150
|
+
word.encode!(charset) if charset && word.respond_to?(:encode!)
|
|
143
151
|
word = encode(word) if should_encode
|
|
144
152
|
word = encode_crlf(word)
|
|
145
153
|
# Skip to next line if we're going to go past the limit
|
|
146
154
|
# Unless this is the first word, in which case we're going to add it anyway
|
|
147
155
|
# Note: This means that a word that's longer than 998 characters is going to break the spec. Please fix if this is a problem for you.
|
|
148
|
-
# (The fix, it seems, would be to use encoded-word encoding on it, because that way you can break it across multiple lines and
|
|
156
|
+
# (The fix, it seems, would be to use encoded-word encoding on it, because that way you can break it across multiple lines and
|
|
149
157
|
# the linebreak will be ignored)
|
|
150
158
|
break if !line.empty? && (line.length + word.length + 1 > limit)
|
|
151
159
|
# Remove the word from the queue ...
|
|
152
160
|
words.shift
|
|
153
161
|
# Add word separator
|
|
154
|
-
|
|
162
|
+
if first_word
|
|
163
|
+
first_word = false
|
|
164
|
+
else
|
|
165
|
+
line << " " if !should_encode
|
|
166
|
+
end
|
|
167
|
+
|
|
155
168
|
# ... add it in encoded form to the current line
|
|
156
|
-
line << word
|
|
169
|
+
line << word
|
|
157
170
|
end
|
|
158
171
|
# Encode the line if necessary
|
|
159
172
|
line = "=?#{encoding}?Q?#{line}?=" if should_encode
|
|
@@ -163,9 +176,9 @@ module Mail
|
|
|
163
176
|
end
|
|
164
177
|
folded_lines
|
|
165
178
|
end
|
|
166
|
-
|
|
179
|
+
|
|
167
180
|
def encode(value)
|
|
168
|
-
value = [value].pack(
|
|
181
|
+
value = [value].pack(CAPITAL_M).gsub(EQUAL_LF, EMPTY)
|
|
169
182
|
value.gsub!(/"/, '=22')
|
|
170
183
|
value.gsub!(/\(/, '=28')
|
|
171
184
|
value.gsub!(/\)/, '=29')
|
|
@@ -176,8 +189,8 @@ module Mail
|
|
|
176
189
|
end
|
|
177
190
|
|
|
178
191
|
def encode_crlf(value)
|
|
179
|
-
value.gsub!(
|
|
180
|
-
value.gsub!(
|
|
192
|
+
value.gsub!(CR, CR_ENCODED)
|
|
193
|
+
value.gsub!(LF, LF_ENCODED)
|
|
181
194
|
value
|
|
182
195
|
end
|
|
183
196
|
|
data/lib/mail/fields.rb
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
module Mail
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
register_autoload :UnstructuredField, 'mail/fields/unstructured_field'
|
|
3
|
+
register_autoload :StructuredField, 'mail/fields/structured_field'
|
|
4
|
+
register_autoload :OptionalField, 'mail/fields/optional_field'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
6
|
+
register_autoload :BccField, 'mail/fields/bcc_field'
|
|
7
|
+
register_autoload :CcField, 'mail/fields/cc_field'
|
|
8
|
+
register_autoload :CommentsField, 'mail/fields/comments_field'
|
|
9
|
+
register_autoload :ContentDescriptionField, 'mail/fields/content_description_field'
|
|
10
|
+
register_autoload :ContentDispositionField, 'mail/fields/content_disposition_field'
|
|
11
|
+
register_autoload :ContentIdField, 'mail/fields/content_id_field'
|
|
12
|
+
register_autoload :ContentLocationField, 'mail/fields/content_location_field'
|
|
13
|
+
register_autoload :ContentTransferEncodingField, 'mail/fields/content_transfer_encoding_field'
|
|
14
|
+
register_autoload :ContentTypeField, 'mail/fields/content_type_field'
|
|
15
|
+
register_autoload :DateField, 'mail/fields/date_field'
|
|
16
|
+
register_autoload :FromField, 'mail/fields/from_field'
|
|
17
|
+
register_autoload :InReplyToField, 'mail/fields/in_reply_to_field'
|
|
18
|
+
register_autoload :KeywordsField, 'mail/fields/keywords_field'
|
|
19
|
+
register_autoload :MessageIdField, 'mail/fields/message_id_field'
|
|
20
|
+
register_autoload :MimeVersionField, 'mail/fields/mime_version_field'
|
|
21
|
+
register_autoload :ReceivedField, 'mail/fields/received_field'
|
|
22
|
+
register_autoload :ReferencesField, 'mail/fields/references_field'
|
|
23
|
+
register_autoload :ReplyToField, 'mail/fields/reply_to_field'
|
|
24
|
+
register_autoload :ResentBccField, 'mail/fields/resent_bcc_field'
|
|
25
|
+
register_autoload :ResentCcField, 'mail/fields/resent_cc_field'
|
|
26
|
+
register_autoload :ResentDateField, 'mail/fields/resent_date_field'
|
|
27
|
+
register_autoload :ResentFromField, 'mail/fields/resent_from_field'
|
|
28
|
+
register_autoload :ResentMessageIdField, 'mail/fields/resent_message_id_field'
|
|
29
|
+
register_autoload :ResentSenderField, 'mail/fields/resent_sender_field'
|
|
30
|
+
register_autoload :ResentToField, 'mail/fields/resent_to_field'
|
|
31
|
+
register_autoload :ReturnPathField, 'mail/fields/return_path_field'
|
|
32
|
+
register_autoload :SenderField, 'mail/fields/sender_field'
|
|
33
|
+
register_autoload :SubjectField, 'mail/fields/subject_field'
|
|
34
|
+
register_autoload :ToField, 'mail/fields/to_field'
|
|
35
35
|
end
|