mail 2.7.0.rc1 → 2.7.0.rc2
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/README.md +71 -98
- data/lib/mail.rb +1 -6
- data/lib/mail/attachments_list.rb +5 -2
- data/lib/mail/body.rb +39 -33
- data/lib/mail/check_delivery_params.rb +8 -6
- data/lib/mail/configuration.rb +2 -0
- data/lib/mail/elements/address.rb +19 -18
- data/lib/mail/encodings.rb +89 -31
- data/lib/mail/encodings/7bit.rb +5 -15
- data/lib/mail/encodings/8bit.rb +2 -21
- data/lib/mail/encodings/base64.rb +11 -12
- data/lib/mail/encodings/binary.rb +3 -22
- data/lib/mail/encodings/identity.rb +24 -0
- data/lib/mail/encodings/quoted_printable.rb +6 -6
- data/lib/mail/encodings/transfer_encoding.rb +38 -29
- data/lib/mail/encodings/unix_to_unix.rb +2 -1
- data/lib/mail/envelope.rb +1 -1
- data/lib/mail/field.rb +93 -61
- data/lib/mail/fields/bcc_field.rb +2 -2
- data/lib/mail/fields/cc_field.rb +1 -1
- data/lib/mail/fields/comments_field.rb +1 -1
- data/lib/mail/fields/common/common_address.rb +32 -7
- data/lib/mail/fields/common/common_field.rb +1 -10
- data/lib/mail/fields/content_description_field.rb +1 -1
- data/lib/mail/fields/content_disposition_field.rb +3 -3
- data/lib/mail/fields/content_id_field.rb +2 -2
- data/lib/mail/fields/content_location_field.rb +1 -1
- data/lib/mail/fields/content_transfer_encoding_field.rb +1 -1
- data/lib/mail/fields/content_type_field.rb +1 -1
- data/lib/mail/fields/date_field.rb +2 -3
- data/lib/mail/fields/from_field.rb +1 -1
- data/lib/mail/fields/in_reply_to_field.rb +1 -1
- data/lib/mail/fields/keywords_field.rb +1 -1
- data/lib/mail/fields/message_id_field.rb +1 -1
- data/lib/mail/fields/mime_version_field.rb +1 -1
- data/lib/mail/fields/optional_field.rb +4 -1
- data/lib/mail/fields/received_field.rb +1 -1
- data/lib/mail/fields/references_field.rb +1 -1
- data/lib/mail/fields/reply_to_field.rb +1 -1
- data/lib/mail/fields/resent_bcc_field.rb +1 -1
- data/lib/mail/fields/resent_cc_field.rb +1 -1
- data/lib/mail/fields/resent_date_field.rb +0 -1
- data/lib/mail/fields/resent_from_field.rb +1 -1
- data/lib/mail/fields/resent_message_id_field.rb +1 -1
- data/lib/mail/fields/resent_sender_field.rb +1 -1
- data/lib/mail/fields/resent_to_field.rb +1 -1
- data/lib/mail/fields/return_path_field.rb +1 -1
- data/lib/mail/fields/sender_field.rb +1 -1
- data/lib/mail/fields/subject_field.rb +1 -1
- data/lib/mail/fields/to_field.rb +1 -1
- data/lib/mail/fields/unstructured_field.rb +19 -2
- data/lib/mail/header.rb +9 -8
- data/lib/mail/mail.rb +2 -10
- data/lib/mail/matchers/has_sent_mail.rb +21 -1
- data/lib/mail/message.rb +64 -51
- data/lib/mail/multibyte.rb +14 -16
- data/lib/mail/multibyte/chars.rb +2 -1
- data/lib/mail/network.rb +1 -0
- data/lib/mail/network/delivery_methods/exim.rb +6 -10
- data/lib/mail/network/delivery_methods/logger_delivery.rb +37 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +8 -4
- data/lib/mail/network/delivery_methods/smtp.rb +56 -55
- data/lib/mail/network/delivery_methods/smtp_connection.rb +9 -1
- data/lib/mail/network/retriever_methods/imap.rb +18 -5
- data/lib/mail/network/retriever_methods/pop3.rb +3 -1
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +30462 -12597
- data/lib/mail/parsers/address_lists_parser.rl +18 -12
- data/lib/mail/parsers/content_disposition_parser.rb +405 -215
- data/lib/mail/parsers/content_disposition_parser.rl +11 -5
- data/lib/mail/parsers/content_location_parser.rb +443 -208
- data/lib/mail/parsers/content_location_parser.rl +9 -3
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +180 -80
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +8 -2
- data/lib/mail/parsers/content_type_parser.rb +436 -245
- data/lib/mail/parsers/content_type_parser.rl +12 -6
- data/lib/mail/parsers/date_time_parser.rb +172 -72
- data/lib/mail/parsers/date_time_parser.rl +10 -4
- data/lib/mail/parsers/envelope_from_parser.rb +2833 -1320
- data/lib/mail/parsers/envelope_from_parser.rl +9 -3
- data/lib/mail/parsers/message_ids_parser.rb +2325 -976
- data/lib/mail/parsers/message_ids_parser.rl +9 -3
- data/lib/mail/parsers/mime_version_parser.rb +164 -64
- data/lib/mail/parsers/mime_version_parser.rl +9 -3
- data/lib/mail/parsers/phrase_lists_parser.rb +582 -237
- data/lib/mail/parsers/phrase_lists_parser.rl +9 -3
- data/lib/mail/parsers/received_parser.rb +7036 -3004
- data/lib/mail/parsers/received_parser.rl +11 -5
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +1 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +1 -0
- data/lib/mail/parsers/rfc2045_mime.rl +1 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +1 -0
- data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +7 -1
- data/lib/mail/parsers/rfc5322.rl +3 -1
- data/lib/mail/parsers/rfc5322_address.rl +3 -1
- data/lib/mail/parsers/rfc5322_date_time.rl +1 -0
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +9 -5
- data/lib/mail/part.rb +1 -1
- data/lib/mail/utilities.rb +44 -15
- data/lib/mail/version.rb +1 -1
- data/lib/mail/version_specific/ruby_1_8.rb +12 -1
- data/lib/mail/version_specific/ruby_1_9.rb +13 -1
- metadata +7 -13
- data/CHANGELOG.rdoc +0 -822
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -1
- data/Gemfile +0 -11
- data/Rakefile +0 -23
- data/TODO.rdoc +0 -9
- data/lib/mail/multibyte/exceptions.rb +0 -9
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'mail/encodings/transfer_encoding'
|
4
|
+
|
5
|
+
module Mail
|
6
|
+
module Encodings
|
7
|
+
# Identity encodings do no encoding/decoding and have a fixed cost:
|
8
|
+
# 1 byte in -> 1 byte out.
|
9
|
+
class Identity < TransferEncoding #:nodoc:
|
10
|
+
def self.decode(str)
|
11
|
+
str
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.encode(str)
|
15
|
+
str
|
16
|
+
end
|
17
|
+
|
18
|
+
# 1 output byte per input byte.
|
19
|
+
def self.cost(str)
|
20
|
+
1.0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -6,27 +6,27 @@ module Mail
|
|
6
6
|
module Encodings
|
7
7
|
class QuotedPrintable < SevenBit
|
8
8
|
NAME='quoted-printable'
|
9
|
-
|
9
|
+
|
10
10
|
PRIORITY = 2
|
11
11
|
|
12
|
-
def self.can_encode?(
|
13
|
-
EightBit.can_encode?
|
12
|
+
def self.can_encode?(enc)
|
13
|
+
EightBit.can_encode? enc
|
14
14
|
end
|
15
15
|
|
16
16
|
# Decode the string from Quoted-Printable. Cope with hard line breaks
|
17
17
|
# that were incorrectly encoded as hex instead of literal CRLF.
|
18
18
|
def self.decode(str)
|
19
|
-
|
19
|
+
str.gsub(/(?:=0D=0A|=0D|=0A)\r\n/, "\r\n").unpack("M*").first
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.encode(str)
|
23
|
-
|
23
|
+
[str].pack("M")
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.cost(str)
|
27
27
|
# These bytes probably do not need encoding
|
28
28
|
c = str.count("\x9\xA\xD\x20-\x3C\x3E-\x7E")
|
29
|
-
# Everything else turns into =XX where XX is a
|
29
|
+
# Everything else turns into =XX where XX is a
|
30
30
|
# two digit hex number (taking 3 bytes)
|
31
31
|
total = (str.bytesize - c)*3 + c
|
32
32
|
total.to_f/str.bytesize
|
@@ -7,17 +7,17 @@ module Mail
|
|
7
7
|
|
8
8
|
PRIORITY = -1
|
9
9
|
|
10
|
+
# And encoding's superclass can always transport it since the
|
11
|
+
# class hierarchy is arranged e.g. Base64 < 7bit < 8bit < Binary.
|
10
12
|
def self.can_transport?(enc)
|
11
|
-
enc
|
12
|
-
if Encodings.defined? enc
|
13
|
-
Encodings.get_encoding(enc).new.is_a? self
|
14
|
-
else
|
15
|
-
false
|
16
|
-
end
|
13
|
+
enc && enc <= self
|
17
14
|
end
|
18
15
|
|
16
|
+
# Override in subclasses to indicate that they can encode text
|
17
|
+
# that couldn't be directly transported, e.g. Base64 has 7bit output,
|
18
|
+
# but it can encode binary.
|
19
19
|
def self.can_encode?(enc)
|
20
|
-
can_transport? enc
|
20
|
+
can_transport? enc
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.cost(str)
|
@@ -32,36 +32,45 @@ module Mail
|
|
32
32
|
self::NAME
|
33
33
|
end
|
34
34
|
|
35
|
-
def self.
|
36
|
-
|
35
|
+
def self.negotiate(message_encoding, source_encoding, str, allowed_encodings = nil)
|
36
|
+
message_encoding = Encodings.get_encoding(message_encoding || '8bit')
|
37
|
+
source_encoding = Encodings.get_encoding(source_encoding)
|
38
|
+
|
39
|
+
if message_encoding && source_encoding && message_encoding.can_transport?(source_encoding) && source_encoding.compatible_input?(str)
|
37
40
|
source_encoding
|
38
41
|
else
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
renegotiate(message_encoding, source_encoding, str, allowed_encodings)
|
43
|
+
end
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
|
46
|
+
def self.renegotiate(message_encoding, source_encoding, str, allowed_encodings = nil)
|
47
|
+
encodings = Encodings.get_all.select do |enc|
|
48
|
+
(allowed_encodings.nil? || allowed_encodings.include?(enc)) &&
|
49
|
+
message_encoding.can_transport?(enc) &&
|
50
|
+
enc.can_encode?(source_encoding)
|
51
|
+
end
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
# give priority to other choices but allow it to be used as a fallback.
|
49
|
-
this_cost = enc.cost(str) if enc.compatible_input?(str)
|
53
|
+
lowest_cost(str, encodings)
|
54
|
+
end
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
elsif this_cost == best_cost
|
55
|
-
best = enc if enc::PRIORITY < best::PRIORITY
|
56
|
-
end
|
57
|
-
end
|
56
|
+
def self.lowest_cost(str, encodings)
|
57
|
+
best = nil
|
58
|
+
best_cost = nil
|
58
59
|
|
59
|
-
|
60
|
+
encodings.each do |enc|
|
61
|
+
# If the current choice cannot be transported safely, give priority
|
62
|
+
# to other choices but allow it to be used as a fallback.
|
63
|
+
this_cost = enc.cost(str) if enc.compatible_input?(str)
|
64
|
+
|
65
|
+
if !best_cost || (this_cost && this_cost < best_cost)
|
66
|
+
best_cost = this_cost
|
67
|
+
best = enc
|
68
|
+
elsif this_cost == best_cost
|
69
|
+
best = enc if enc::PRIORITY < best::PRIORITY
|
70
|
+
end
|
60
71
|
end
|
61
|
-
end
|
62
72
|
|
63
|
-
|
64
|
-
self.class.to_s
|
73
|
+
best
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Mail
|
3
3
|
module Encodings
|
4
|
-
|
4
|
+
class UnixToUnix < TransferEncoding
|
5
5
|
NAME = "x-uuencode"
|
6
6
|
|
7
7
|
def self.decode(str)
|
@@ -13,6 +13,7 @@ module Mail
|
|
13
13
|
end
|
14
14
|
|
15
15
|
Encodings.register(NAME, self)
|
16
|
+
Encodings.register("uuencode", self)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
data/lib/mail/envelope.rb
CHANGED
data/lib/mail/field.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'mail/fields'
|
3
|
+
require 'mail/constants'
|
3
4
|
|
4
5
|
# encoding: utf-8
|
5
6
|
module Mail
|
@@ -83,9 +84,31 @@ module Mail
|
|
83
84
|
|
84
85
|
def initialize(element, value, reason)
|
85
86
|
@element = element
|
86
|
-
@value = value
|
87
|
-
@reason = reason
|
88
|
-
super("#{element} can not parse |#{value}
|
87
|
+
@value = to_utf8(value)
|
88
|
+
@reason = to_utf8(reason)
|
89
|
+
super("#{@element} can not parse |#{@value}|: #{@reason}")
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
def to_utf8(text)
|
94
|
+
if text.respond_to?(:force_encoding)
|
95
|
+
text.dup.force_encoding(Encoding::UTF_8)
|
96
|
+
else
|
97
|
+
text
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class NilParseError < ParseError #:nodoc:
|
103
|
+
def initialize(element)
|
104
|
+
super element, nil, 'nil is invalid'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class IncompleteParseError < ParseError #:nodoc:
|
109
|
+
def initialize(element, original_text, unparsed_index)
|
110
|
+
parsed_text = to_utf8(original_text[0...unparsed_index])
|
111
|
+
super element, original_text, "Only able to parse up to #{parsed_text.inspect}"
|
89
112
|
end
|
90
113
|
end
|
91
114
|
|
@@ -93,41 +116,62 @@ module Mail
|
|
93
116
|
class SyntaxError < FieldError #:nodoc:
|
94
117
|
end
|
95
118
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
119
|
+
class << self
|
120
|
+
# Parse a field from a raw header line:
|
121
|
+
#
|
122
|
+
# Mail::Field.parse("field-name: field data")
|
123
|
+
# # => #<Mail::Field …>
|
124
|
+
def parse(field, charset = nil)
|
125
|
+
name, value = split(field)
|
126
|
+
if name && value
|
127
|
+
new name, value, charset
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def split(raw_field) #:nodoc:
|
132
|
+
if raw_field.index(Constants::COLON)
|
133
|
+
name, value = raw_field.split(Constants::COLON, 2)
|
134
|
+
name.rstrip!
|
135
|
+
if name =~ /\A#{Constants::FIELD_NAME}\z/
|
136
|
+
[ name.rstrip, value.strip ]
|
137
|
+
else
|
138
|
+
Kernel.warn "WARNING: Ignoring unparsable header #{raw_field.inspect}: invalid header name syntax: #{name.inspect}"
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
else
|
142
|
+
raw_field.strip
|
143
|
+
end
|
144
|
+
rescue => error
|
145
|
+
warn "WARNING: Ignoring unparsable header #{raw_field.inspect}: #{error.class}: #{error.message}"
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Create a field by name and optional value:
|
103
151
|
#
|
104
|
-
#
|
152
|
+
# Mail::Field.new("field-name", "value")
|
153
|
+
# # => #<Mail::Field …>
|
105
154
|
#
|
106
|
-
#
|
155
|
+
# Values that aren't strings or arrays are coerced to Strings with `#to_s`.
|
107
156
|
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
# it will be passed through as is, for example, content-type
|
111
|
-
# field can accept an array with the type and a hash of
|
112
|
-
# parameters:
|
157
|
+
# Mail::Field.new("field-name", 1234)
|
158
|
+
# # => #<Mail::Field …>
|
113
159
|
#
|
114
|
-
# Field.new('content-type', ['text', 'plain', {:charset => 'UTF-8'}])
|
160
|
+
# Mail::Field.new('content-type', ['text', 'plain', {:charset => 'UTF-8'}])
|
161
|
+
# # => #<Mail::Field …>
|
115
162
|
def initialize(name, value = nil, charset = 'utf-8')
|
116
163
|
case
|
117
|
-
when name.index(COLON)
|
164
|
+
when name.index(COLON)
|
165
|
+
Kernel.warn 'Passing an unparsed header field to Mail::Field.new is deprecated and will be removed in Mail 2.8.0. Use Mail::Field.parse instead.'
|
166
|
+
@name, @unparsed_value = self.class.split(name)
|
118
167
|
@charset = Utilities.blank?(value) ? charset : value
|
119
|
-
|
120
|
-
@raw_value = name
|
121
|
-
@value = nil
|
122
|
-
when Utilities.blank?(value) # Field.new("field-name")
|
168
|
+
when Utilities.blank?(value)
|
123
169
|
@name = name
|
124
|
-
@
|
125
|
-
@raw_value = nil
|
170
|
+
@unparsed_value = nil
|
126
171
|
@charset = charset
|
127
|
-
else
|
172
|
+
else
|
128
173
|
@name = name
|
129
|
-
@
|
130
|
-
@raw_value = nil
|
174
|
+
@unparsed_value = value
|
131
175
|
@charset = charset
|
132
176
|
end
|
133
177
|
@name = FIELD_NAME_MAP[@name.to_s.downcase] || @name
|
@@ -138,8 +182,7 @@ module Mail
|
|
138
182
|
end
|
139
183
|
|
140
184
|
def field
|
141
|
-
|
142
|
-
@field ||= create_field(@name, @value, @charset)
|
185
|
+
@field ||= create_field(@name, @unparsed_value, @charset)
|
143
186
|
end
|
144
187
|
|
145
188
|
def name
|
@@ -217,14 +260,26 @@ module Mail
|
|
217
260
|
|
218
261
|
private
|
219
262
|
|
220
|
-
def
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
263
|
+
def create_field(name, value, charset)
|
264
|
+
new_field(name, value, charset)
|
265
|
+
rescue Mail::Field::ParseError => e
|
266
|
+
field = Mail::UnstructuredField.new(name, value)
|
267
|
+
field.errors << [name, value, e]
|
268
|
+
field
|
269
|
+
end
|
270
|
+
|
271
|
+
def new_field(name, value, charset)
|
272
|
+
value = unfold(value) if value.is_a?(String)
|
273
|
+
|
274
|
+
if klass = field_class_for(name)
|
275
|
+
klass.new(value, charset)
|
276
|
+
else
|
277
|
+
OptionalField.new(name, value, charset)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def field_class_for(name)
|
282
|
+
FIELDS_MAP[name.to_s.downcase]
|
228
283
|
end
|
229
284
|
|
230
285
|
# 2.2.3. Long Header Fields
|
@@ -238,28 +293,5 @@ module Mail
|
|
238
293
|
def unfold(string)
|
239
294
|
string.gsub(/#{CRLF}(#{WSP})/m, '\1')
|
240
295
|
end
|
241
|
-
|
242
|
-
def create_field(name, value, charset)
|
243
|
-
value = unfold(value) if value.is_a?(String)
|
244
|
-
|
245
|
-
begin
|
246
|
-
new_field(name, value, charset)
|
247
|
-
rescue Mail::Field::ParseError => e
|
248
|
-
field = Mail::UnstructuredField.new(name, value)
|
249
|
-
field.errors << [name, value, e]
|
250
|
-
field
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
def new_field(name, value, charset)
|
255
|
-
lower_case_name = name.to_s.downcase
|
256
|
-
if field_klass = FIELDS_MAP[lower_case_name]
|
257
|
-
field_klass.new(value, charset)
|
258
|
-
else
|
259
|
-
OptionalField.new(name, value, charset)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
296
|
end
|
264
|
-
|
265
297
|
end
|
@@ -37,9 +37,9 @@ module Mail
|
|
37
37
|
FIELD_NAME = 'bcc'
|
38
38
|
CAPITALIZED_FIELD = 'Bcc'
|
39
39
|
|
40
|
-
def initialize(value =
|
40
|
+
def initialize(value = nil, charset = 'utf-8')
|
41
41
|
@charset = charset
|
42
|
-
super(CAPITALIZED_FIELD,
|
42
|
+
super(CAPITALIZED_FIELD, value, charset)
|
43
43
|
self
|
44
44
|
end
|
45
45
|
|
data/lib/mail/fields/cc_field.rb
CHANGED
@@ -4,7 +4,6 @@ require 'mail/fields/common/address_container'
|
|
4
4
|
|
5
5
|
module Mail
|
6
6
|
module CommonAddress # :nodoc:
|
7
|
-
|
8
7
|
def parse(val = value)
|
9
8
|
unless Utilities.blank?(val)
|
10
9
|
@address_list = AddressList.new(encode_if_needed(val))
|
@@ -12,15 +11,22 @@ module Mail
|
|
12
11
|
nil
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
14
|
+
|
16
15
|
def charset
|
17
16
|
@charset
|
18
17
|
end
|
19
|
-
|
20
|
-
def encode_if_needed(val)
|
21
|
-
|
18
|
+
|
19
|
+
def encode_if_needed(val) #:nodoc:
|
20
|
+
# Need to join arrays of addresses into a single value
|
21
|
+
if val.kind_of?(Array)
|
22
|
+
val.compact.map { |a| encode_if_needed a }.join(', ')
|
23
|
+
|
24
|
+
# Pass through UTF-8; encode non-UTF-8.
|
25
|
+
else
|
26
|
+
utf8_if_needed(val) || Encodings.encode_non_usascii(val, charset)
|
27
|
+
end
|
22
28
|
end
|
23
|
-
|
29
|
+
|
24
30
|
# Allows you to iterate through each address object in the address_list
|
25
31
|
def each
|
26
32
|
address_list.addresses.each do |address|
|
@@ -98,7 +104,26 @@ module Mail
|
|
98
104
|
end
|
99
105
|
|
100
106
|
private
|
101
|
-
|
107
|
+
|
108
|
+
if 'string'.respond_to?(:encoding)
|
109
|
+
# Pass through UTF-8 addresses
|
110
|
+
def utf8_if_needed(val)
|
111
|
+
if charset =~ /\AUTF-?8\z/i
|
112
|
+
val
|
113
|
+
elsif val.encoding == Encoding::UTF_8
|
114
|
+
val
|
115
|
+
elsif (utf8 = val.dup.force_encoding(Encoding::UTF_8)).valid_encoding?
|
116
|
+
utf8
|
117
|
+
end
|
118
|
+
end
|
119
|
+
else
|
120
|
+
def utf8_if_needed(val)
|
121
|
+
if charset =~ /\AUTF-?8\z/i
|
122
|
+
val
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
102
127
|
def do_encode(field_name)
|
103
128
|
return '' if Utilities.blank?(value)
|
104
129
|
address_array = address_list.addresses.reject { |a| encoded_group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
|