mail 2.4.4 → 2.5.5
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 +140 -1
- data/CONTRIBUTING.md +4 -4
- data/Gemfile +14 -8
- data/MIT-LICENSE +20 -0
- data/README.md +24 -23
- data/Rakefile +3 -22
- data/lib/VERSION +2 -2
- data/lib/load_parsers.rb +35 -0
- data/lib/mail/attachments_list.rb +2 -2
- data/lib/mail/body.rb +5 -5
- data/lib/mail/check_delivery_params.rb +57 -0
- data/lib/mail/configuration.rb +1 -1
- 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 +4 -4
- data/lib/mail/elements/address.rb +13 -5
- data/lib/mail/elements/envelope_from_element.rb +15 -2
- data/lib/mail/elements.rb +12 -12
- data/lib/mail/encodings/quoted_printable.rb +4 -3
- data/lib/mail/encodings.rb +66 -35
- data/lib/mail/field.rb +76 -99
- 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 +19 -4
- data/lib/mail/fields/common/common_field.rb +8 -2
- data/lib/mail/fields/common/common_message_id.rb +9 -5
- 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 -2
- 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 +2 -2
- data/lib/mail/fields/resent_to_field.rb +2 -2
- data/lib/mail/fields/sender_field.rb +7 -7
- data/lib/mail/fields/to_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +34 -27
- data/lib/mail/fields.rb +32 -32
- data/lib/mail/header.rb +37 -14
- data/lib/mail/message.rb +140 -45
- data/lib/mail/multibyte/chars.rb +4 -4
- data/lib/mail/multibyte/unicode.rb +8 -0
- data/lib/mail/network/delivery_methods/exim.rb +6 -11
- data/lib/mail/network/delivery_methods/file_delivery.rb +7 -6
- data/lib/mail/network/delivery_methods/sendmail.rb +40 -11
- data/lib/mail/network/delivery_methods/smtp.rb +33 -47
- data/lib/mail/network/delivery_methods/smtp_connection.rb +7 -24
- data/lib/mail/network/delivery_methods/test_mailer.rb +9 -8
- data/lib/mail/network/retriever_methods/imap.rb +14 -6
- 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/content_transfer_encoding.rb +81 -42
- data/lib/mail/parsers/content_transfer_encoding.treetop +4 -6
- data/lib/mail/parsers/content_type.rb +16 -12
- data/lib/mail/parsers/content_type.treetop +2 -2
- data/lib/mail/parsers/rfc2045.rb +12 -55
- data/lib/mail/parsers/rfc2045.treetop +1 -2
- data/lib/mail/parsers/rfc2822.rb +127 -71
- data/lib/mail/parsers/rfc2822.treetop +22 -24
- data/lib/mail/part.rb +6 -2
- data/lib/mail/parts_list.rb +1 -1
- data/lib/mail/patterns.rb +1 -1
- data/lib/mail/utilities.rb +25 -17
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version_specific/ruby_1_8.rb +23 -2
- data/lib/mail/version_specific/ruby_1_9.rb +55 -21
- data/lib/mail.rb +18 -18
- metadata +89 -37
- data/Gemfile.lock +0 -36
- data/lib/mail/core_extensions/shell_escape.rb +0 -56
@@ -22,7 +22,7 @@ module Mail
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def to_s
|
25
|
-
decoded
|
25
|
+
decoded.to_s
|
26
26
|
end
|
27
27
|
|
28
28
|
def default
|
@@ -34,7 +34,7 @@ module Mail
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def responsible_for?( val )
|
37
|
-
name.to_s.
|
37
|
+
name.to_s.casecmp(val.to_s) == 0
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
@@ -47,5 +47,11 @@ module Mail
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
FILENAME_RE = /\b(filename|name)=([^;"\r\n]+\s[^;"\r\n]+)/
|
51
|
+
def ensure_filename_quoted(value)
|
52
|
+
if value.is_a?(String)
|
53
|
+
value.sub! FILENAME_RE, '\1="\2"'
|
54
|
+
end
|
55
|
+
end
|
50
56
|
end
|
51
57
|
end
|
@@ -31,14 +31,18 @@ module Mail
|
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
|
-
|
34
|
+
|
35
35
|
def do_encode(field_name)
|
36
|
-
%Q{#{field_name}: #{
|
36
|
+
%Q{#{field_name}: #{formated_message_ids("\r\n ")}\r\n}
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def do_decode
|
40
|
-
|
40
|
+
formated_message_ids(' ')
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
|
+
def formated_message_ids(join)
|
44
|
+
message_ids.map{ |m| "<#{m}>" }.join(join) if message_ids
|
45
|
+
end
|
46
|
+
|
43
47
|
end
|
44
48
|
end
|
@@ -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
|
@@ -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
|
@@ -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
|
|
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,7 +138,7 @@ 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
|
@@ -139,13 +146,13 @@ module Mail
|
|
139
146
|
line = ""
|
140
147
|
while !words.empty?
|
141
148
|
break unless word = words.first.dup
|
142
|
-
word.encode!(charset) if
|
149
|
+
word.encode!(charset) if charset && word.respond_to?(:encode!)
|
143
150
|
word = encode(word) if should_encode
|
144
151
|
word = encode_crlf(word)
|
145
152
|
# Skip to next line if we're going to go past the limit
|
146
153
|
# Unless this is the first word, in which case we're going to add it anyway
|
147
154
|
# 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
|
155
|
+
# (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
156
|
# the linebreak will be ignored)
|
150
157
|
break if !line.empty? && (line.length + word.length + 1 > limit)
|
151
158
|
# Remove the word from the queue ...
|
@@ -153,7 +160,7 @@ module Mail
|
|
153
160
|
# Add word separator
|
154
161
|
line << " " unless (line.empty? || should_encode)
|
155
162
|
# ... add it in encoded form to the current line
|
156
|
-
line << word
|
163
|
+
line << word
|
157
164
|
end
|
158
165
|
# Encode the line if necessary
|
159
166
|
line = "=?#{encoding}?Q?#{line}?=" if should_encode
|
@@ -163,7 +170,7 @@ module Mail
|
|
163
170
|
end
|
164
171
|
folded_lines
|
165
172
|
end
|
166
|
-
|
173
|
+
|
167
174
|
def encode(value)
|
168
175
|
value = [value].pack("M").gsub("=\n", '')
|
169
176
|
value.gsub!(/"/, '=22')
|