mail 2.6.6 → 2.7.0.rc1
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/CHANGELOG.rdoc +25 -6
- data/Dependencies.txt +0 -1
- data/Gemfile +5 -8
- data/MIT-LICENSE +1 -1
- data/README.md +22 -11
- data/Rakefile +0 -6
- data/lib/mail.rb +2 -10
- data/lib/mail/attachments_list.rb +3 -2
- data/lib/mail/body.rb +3 -3
- data/lib/mail/core_extensions/smtp.rb +19 -16
- data/lib/mail/core_extensions/string.rb +0 -4
- data/lib/mail/elements/address.rb +9 -4
- data/lib/mail/elements/address_list.rb +10 -18
- data/lib/mail/elements/content_disposition_element.rb +8 -15
- data/lib/mail/elements/content_location_element.rb +5 -10
- data/lib/mail/elements/content_transfer_encoding_element.rb +5 -10
- data/lib/mail/elements/content_type_element.rb +8 -19
- data/lib/mail/elements/date_time_element.rb +6 -14
- data/lib/mail/elements/envelope_from_element.rb +14 -21
- data/lib/mail/elements/message_ids_element.rb +8 -12
- data/lib/mail/elements/mime_version_element.rb +6 -14
- data/lib/mail/elements/phrase_list.rb +6 -9
- data/lib/mail/elements/received_element.rb +9 -15
- data/lib/mail/encodings.rb +12 -14
- data/lib/mail/field.rb +7 -4
- data/lib/mail/fields/common/parameter_hash.rb +1 -1
- data/lib/mail/fields/content_type_field.rb +2 -7
- data/lib/mail/fields/unstructured_field.rb +2 -2
- data/lib/mail/header.rb +1 -0
- data/lib/mail/message.rb +23 -25
- data/lib/mail/multibyte.rb +51 -0
- data/lib/mail/multibyte/chars.rb +27 -27
- data/lib/mail/network/delivery_methods/exim.rb +10 -6
- data/lib/mail/network/delivery_methods/sendmail.rb +2 -6
- data/lib/mail/network/delivery_methods/smtp.rb +14 -6
- data/lib/mail/parsers.rb +16 -24
- data/lib/mail/parsers/address_lists_parser.rb +15321 -112
- data/lib/mail/parsers/address_lists_parser.rl +166 -0
- data/lib/mail/parsers/content_disposition_parser.rb +698 -55
- data/lib/mail/parsers/content_disposition_parser.rl +76 -0
- data/lib/mail/parsers/content_location_parser.rb +565 -23
- data/lib/mail/parsers/content_location_parser.rl +65 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +410 -22
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +58 -0
- data/lib/mail/parsers/content_type_parser.rb +841 -54
- data/lib/mail/parsers/content_type_parser.rl +77 -0
- data/lib/mail/parsers/date_time_parser.rb +773 -26
- data/lib/mail/parsers/date_time_parser.rl +56 -0
- data/lib/mail/parsers/envelope_from_parser.rb +2051 -36
- data/lib/mail/parsers/envelope_from_parser.rl +76 -0
- data/lib/mail/parsers/message_ids_parser.rb +1494 -25
- data/lib/mail/parsers/message_ids_parser.rl +76 -0
- data/lib/mail/parsers/mime_version_parser.rb +393 -26
- data/lib/mail/parsers/mime_version_parser.rl +55 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +529 -19
- data/lib/mail/parsers/phrase_lists_parser.rl +77 -0
- data/lib/mail/parsers/received_parser.rb +4711 -38
- data/lib/mail/parsers/received_parser.rl +78 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +12 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +24 -0
- data/lib/mail/parsers/rfc2045_mime.rl +15 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +14 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +16 -0
- data/lib/mail/parsers/rfc5322.rl +57 -0
- data/lib/mail/parsers/rfc5322_address.rl +70 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +7 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +56 -0
- data/lib/mail/part.rb +1 -1
- data/lib/mail/parts_list.rb +5 -6
- data/lib/mail/utilities.rb +4 -2
- data/lib/mail/version.rb +3 -3
- data/lib/mail/version_specific/ruby_1_8.rb +28 -2
- data/lib/mail/version_specific/ruby_1_9.rb +48 -8
- metadata +28 -45
- data/lib/mail/core_extensions/string/access.rb +0 -146
- data/lib/mail/core_extensions/string/multibyte.rb +0 -79
- data/lib/mail/parsers/ragel.rb +0 -18
- data/lib/mail/parsers/ragel/common.rl +0 -185
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- data/lib/mail/parsers/ragel/ruby.rb +0 -40
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_transfer_encoding_parser'
|
|
4
|
+
|
|
3
5
|
module Mail
|
|
4
6
|
class ContentTransferEncodingElement
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
attr_reader :encoding
|
|
8
|
+
|
|
8
9
|
def initialize(string)
|
|
9
|
-
|
|
10
|
-
@encoding = content_transfer_encoding.encoding
|
|
10
|
+
@encoding = Mail::Parsers::ContentTransferEncodingParser.parse(string).encoding
|
|
11
11
|
end
|
|
12
|
-
|
|
13
|
-
def encoding
|
|
14
|
-
@encoding
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
end
|
|
18
13
|
end
|
|
@@ -1,32 +1,21 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_type_parser'
|
|
4
|
+
|
|
3
5
|
module Mail
|
|
4
6
|
class ContentTypeElement # :nodoc:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
content_type = Mail::Parsers::ContentTypeParser.new.parse(cleaned(string))
|
|
7
|
+
attr_reader :main_type, :sub_type, :parameters
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
content_type = Mail::Parsers::ContentTypeParser.parse(cleaned(string))
|
|
10
11
|
@main_type = content_type.main_type
|
|
11
12
|
@sub_type = content_type.sub_type
|
|
12
13
|
@parameters = content_type.parameters
|
|
13
14
|
end
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@main_type
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def sub_type
|
|
20
|
-
@sub_type
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def parameters
|
|
24
|
-
@parameters
|
|
25
|
-
end
|
|
26
|
-
|
|
15
|
+
|
|
16
|
+
private
|
|
27
17
|
def cleaned(string)
|
|
28
18
|
string =~ /(.+);\s*$/ ? $1 : string
|
|
29
19
|
end
|
|
30
|
-
|
|
31
20
|
end
|
|
32
21
|
end
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/date_time_parser'
|
|
4
|
+
|
|
3
5
|
module Mail
|
|
4
6
|
class DateTimeElement # :nodoc:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
date_time = Mail::Parsers::DateTimeParser.new.parse(string)
|
|
7
|
+
attr_reader :date_string, :time_string
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
date_time = Mail::Parsers::DateTimeParser.parse(string)
|
|
10
11
|
@date_string = date_time.date_string
|
|
11
12
|
@time_string = date_time.time_string
|
|
12
13
|
end
|
|
13
|
-
|
|
14
|
-
def date_string
|
|
15
|
-
@date_string
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def time_string
|
|
19
|
-
@time_string
|
|
20
|
-
end
|
|
21
|
-
|
|
22
14
|
end
|
|
23
15
|
end
|
|
@@ -1,40 +1,33 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/envelope_from_parser'
|
|
4
|
+
require 'date'
|
|
5
|
+
|
|
3
6
|
module Mail
|
|
4
7
|
class EnvelopeFromElement
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@
|
|
10
|
-
@
|
|
11
|
-
@date_time = ::DateTime.parse(@envelope_from.ctime_date)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def date_time
|
|
15
|
-
@date_time
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def address
|
|
19
|
-
@address
|
|
8
|
+
attr_reader :date_time, :address
|
|
9
|
+
|
|
10
|
+
def initialize(string)
|
|
11
|
+
envelope_from = Mail::Parsers::EnvelopeFromParser.parse(string)
|
|
12
|
+
@address = envelope_from.address
|
|
13
|
+
@date_time = ::DateTime.parse(envelope_from.ctime_date)
|
|
20
14
|
end
|
|
21
|
-
|
|
15
|
+
|
|
22
16
|
# RFC 4155:
|
|
23
17
|
# a timestamp indicating the UTC date and time when the message
|
|
24
18
|
# was originally received, conformant with the syntax of the
|
|
25
19
|
# traditional UNIX 'ctime' output sans timezone (note that the
|
|
26
20
|
# use of UTC precludes the need for a timezone indicator);
|
|
27
21
|
def formatted_date_time
|
|
28
|
-
if
|
|
29
|
-
|
|
22
|
+
if date_time.respond_to?(:ctime)
|
|
23
|
+
date_time.ctime
|
|
30
24
|
else
|
|
31
|
-
|
|
25
|
+
date_time.strftime '%a %b %e %T %Y'
|
|
32
26
|
end
|
|
33
27
|
end
|
|
34
28
|
|
|
35
29
|
def to_s
|
|
36
|
-
"#{
|
|
30
|
+
"#{address} #{formatted_date_time}"
|
|
37
31
|
end
|
|
38
|
-
|
|
39
32
|
end
|
|
40
33
|
end
|
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/message_ids_parser'
|
|
4
|
+
|
|
3
5
|
module Mail
|
|
4
6
|
class MessageIdsElement
|
|
5
|
-
|
|
6
|
-
include Mail::Utilities
|
|
7
|
+
attr_reader :message_ids
|
|
7
8
|
|
|
8
9
|
def initialize(string)
|
|
9
|
-
|
|
10
|
-
@message_ids = Mail::Parsers::MessageIdsParser.new.parse(string).message_ids.map { |msg_id| clean_msg_id(msg_id) }
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def message_ids
|
|
14
|
-
@message_ids
|
|
10
|
+
@message_ids = Mail::Parsers::MessageIdsParser.parse(string).message_ids.map { |msg_id| clean_msg_id(msg_id) }
|
|
15
11
|
end
|
|
16
12
|
|
|
17
13
|
def message_id
|
|
18
|
-
|
|
14
|
+
message_ids.first
|
|
19
15
|
end
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
private
|
|
18
|
+
def clean_msg_id(val)
|
|
19
|
+
val =~ /.*<(.*)>.*/ ? $1 : val
|
|
23
20
|
end
|
|
24
|
-
|
|
25
21
|
end
|
|
26
22
|
end
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/mime_version_parser'
|
|
4
|
+
|
|
3
5
|
module Mail
|
|
4
6
|
class MimeVersionElement
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
mime_version = Mail::Parsers::MimeVersionParser.new.parse(string)
|
|
7
|
+
attr_reader :major, :minor
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
mime_version = Mail::Parsers::MimeVersionParser.parse(string)
|
|
10
11
|
@major = mime_version.major
|
|
11
12
|
@minor = mime_version.minor
|
|
12
13
|
end
|
|
13
|
-
|
|
14
|
-
def major
|
|
15
|
-
@major
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def minor
|
|
19
|
-
@minor
|
|
20
|
-
end
|
|
21
|
-
|
|
22
14
|
end
|
|
23
15
|
end
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/phrase_lists_parser'
|
|
4
|
+
require 'mail/utilities'
|
|
5
|
+
|
|
3
6
|
module Mail
|
|
4
7
|
class PhraseList
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
attr_reader :phrases
|
|
9
|
+
|
|
8
10
|
def initialize(string)
|
|
9
|
-
@
|
|
11
|
+
@phrases = Mail::Parsers::PhraseListsParser.parse(string).phrases.map { |p| Mail::Utilities.unquote(p) }
|
|
10
12
|
end
|
|
11
|
-
|
|
12
|
-
def phrases
|
|
13
|
-
@phrase_lists.phrases.map { |p| unquote(p) }
|
|
14
|
-
end
|
|
15
|
-
|
|
16
13
|
end
|
|
17
14
|
end
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/received_parser'
|
|
4
|
+
require 'date'
|
|
5
|
+
|
|
3
6
|
module Mail
|
|
4
7
|
class ReceivedElement
|
|
5
|
-
|
|
6
8
|
include Mail::Utilities
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
attr_reader :date_time, :info
|
|
10
|
+
|
|
11
|
+
def initialize(string)
|
|
12
|
+
received = Mail::Parsers::ReceivedParser.parse(string)
|
|
10
13
|
@date_time = ::DateTime.parse("#{received.date} #{received.time}")
|
|
11
14
|
@info = received.info
|
|
12
15
|
end
|
|
13
|
-
|
|
14
|
-
def date_time
|
|
15
|
-
@date_time
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def info
|
|
19
|
-
@info
|
|
20
|
-
end
|
|
21
|
-
|
|
16
|
+
|
|
22
17
|
def to_s(*args)
|
|
23
|
-
"#{
|
|
18
|
+
"#{info}; #{date_time.to_s(*args)}"
|
|
24
19
|
end
|
|
25
|
-
|
|
26
20
|
end
|
|
27
21
|
end
|
data/lib/mail/encodings.rb
CHANGED
|
@@ -178,9 +178,8 @@ module Mail
|
|
|
178
178
|
|
|
179
179
|
def Encodings.encode_non_usascii(address, charset)
|
|
180
180
|
return address if address.ascii_only? or charset.nil?
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
address = address.gsub(/(".*?[^#{us_ascii}].*?")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
|
|
181
|
+
# Encode all strings embedded inside of quotes
|
|
182
|
+
address = address.gsub(/("[^"]*")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
|
|
184
183
|
# Then loop through all remaining items and encode as needed
|
|
185
184
|
tokens = address.split(/\s/)
|
|
186
185
|
map_with_index(tokens) do |word, i|
|
|
@@ -258,24 +257,23 @@ module Mail
|
|
|
258
257
|
str[ENCODED_VALUE, 1]
|
|
259
258
|
end
|
|
260
259
|
|
|
261
|
-
#
|
|
262
|
-
# encoding (Q or B) can be joined together.
|
|
260
|
+
# Split header line into proper encoded and unencoded parts.
|
|
263
261
|
#
|
|
264
262
|
# String has to be of the format =?<encoding>?[QB]?<string>?=
|
|
263
|
+
#
|
|
264
|
+
# Omit unencoded space after an encoded-word.
|
|
265
265
|
def Encodings.collapse_adjacent_encodings(str)
|
|
266
266
|
results = []
|
|
267
|
-
|
|
267
|
+
last_encoded = nil # Track whether to preserve or drop whitespace
|
|
268
|
+
|
|
268
269
|
lines = str.split(FULL_ENCODED_VALUE)
|
|
269
270
|
lines.each_slice(2) do |unencoded, encoded|
|
|
270
|
-
if encoded
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
results.last << encoded
|
|
274
|
-
else
|
|
275
|
-
results << unencoded unless unencoded == EMPTY
|
|
276
|
-
results << encoded
|
|
271
|
+
if last_encoded = encoded
|
|
272
|
+
if !Utilities.blank?(unencoded) || (!last_encoded && unencoded != EMPTY)
|
|
273
|
+
results << unencoded
|
|
277
274
|
end
|
|
278
|
-
|
|
275
|
+
|
|
276
|
+
results << encoded
|
|
279
277
|
else
|
|
280
278
|
results << unencoded
|
|
281
279
|
end
|
data/lib/mail/field.rb
CHANGED
|
@@ -218,10 +218,13 @@ module Mail
|
|
|
218
218
|
private
|
|
219
219
|
|
|
220
220
|
def split(raw_field)
|
|
221
|
-
match_data =
|
|
222
|
-
[
|
|
221
|
+
match_data = Mail::Multibyte.mb_chars(raw_field).match(FIELD_SPLIT)
|
|
222
|
+
[
|
|
223
|
+
Mail::Multibyte.mb_chars(match_data[1].to_s).strip,
|
|
224
|
+
Mail::Multibyte.mb_chars(match_data[2].to_s).strip.to_s
|
|
225
|
+
]
|
|
223
226
|
rescue
|
|
224
|
-
|
|
227
|
+
$stderr.puts "WARNING: Could not parse (and so ignoring) '#{raw_field}'"
|
|
225
228
|
end
|
|
226
229
|
|
|
227
230
|
# 2.2.3. Long Header Fields
|
|
@@ -233,7 +236,7 @@ module Mail
|
|
|
233
236
|
# treated in its unfolded form for further syntactic and semantic
|
|
234
237
|
# evaluation.
|
|
235
238
|
def unfold(string)
|
|
236
|
-
string.gsub(/
|
|
239
|
+
string.gsub(/#{CRLF}(#{WSP})/m, '\1')
|
|
237
240
|
end
|
|
238
241
|
|
|
239
242
|
def create_field(name, value, charset)
|
|
@@ -30,7 +30,7 @@ module Mail
|
|
|
30
30
|
super(exact || key_name)
|
|
31
31
|
else # Dealing with a multiple value pair or a single encoded value pair
|
|
32
32
|
string = pairs.sort { |a,b| a.first.to_s <=> b.first.to_s }.map { |v| v.last }.join('')
|
|
33
|
-
if mt = string.match(/([\w\-]+)'(\w\w)'(.*)/)
|
|
33
|
+
if mt = string.match(/([\w\-]+)?'(\w\w)?'(.*)/)
|
|
34
34
|
string = mt[3]
|
|
35
35
|
encoding = mt[1]
|
|
36
36
|
else
|
|
@@ -145,9 +145,7 @@ module Mail
|
|
|
145
145
|
# TODO: check if there are cases where whitespace is not a separator
|
|
146
146
|
val = val.
|
|
147
147
|
gsub(/\s*=\s*/,'='). # remove whitespaces around equal sign
|
|
148
|
-
|
|
149
|
-
squeeze(';').
|
|
150
|
-
gsub(';', '; '). #use '; ' as a separator (or EOL)
|
|
148
|
+
gsub(/[; ]+/, '; '). #use '; ' as a separator (or EOL)
|
|
151
149
|
gsub(/;\s*$/,'') #remove trailing to keep examples below
|
|
152
150
|
|
|
153
151
|
if val =~ /(boundary=(\S*))/i
|
|
@@ -157,9 +155,6 @@ module Mail
|
|
|
157
155
|
end
|
|
158
156
|
|
|
159
157
|
case
|
|
160
|
-
when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;;+(.*)$/i
|
|
161
|
-
# Handles 'text/plain;; format="flowed"' (double semi colon)
|
|
162
|
-
"#{$1}/#{$2}; #{$3}"
|
|
163
158
|
when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
|
|
164
159
|
# Microsoft helper:
|
|
165
160
|
# Handles 'type/subtype;ISO-8559-1'
|
|
@@ -186,7 +181,7 @@ module Mail
|
|
|
186
181
|
when val =~ /^\s*$/
|
|
187
182
|
'text/plain'
|
|
188
183
|
else
|
|
189
|
-
|
|
184
|
+
val
|
|
190
185
|
end
|
|
191
186
|
end
|
|
192
187
|
|
|
@@ -121,7 +121,7 @@ module Mail
|
|
|
121
121
|
def fold(prepend = 0) # :nodoc:
|
|
122
122
|
encoding = normalized_encoding
|
|
123
123
|
decoded_string = decoded.to_s
|
|
124
|
-
should_encode = decoded_string.
|
|
124
|
+
should_encode = !decoded_string.ascii_only?
|
|
125
125
|
if should_encode
|
|
126
126
|
first = true
|
|
127
127
|
words = decoded_string.split(/[ \t]/).map do |word|
|
|
@@ -130,7 +130,7 @@ module Mail
|
|
|
130
130
|
else
|
|
131
131
|
word = " #{word}"
|
|
132
132
|
end
|
|
133
|
-
if word.
|
|
133
|
+
if !word.ascii_only?
|
|
134
134
|
word
|
|
135
135
|
else
|
|
136
136
|
word.scan(/.{7}|.+$/)
|
data/lib/mail/header.rb
CHANGED
data/lib/mail/message.rb
CHANGED
|
@@ -213,7 +213,7 @@ module Mail
|
|
|
213
213
|
self.default_charset = 'UTF-8'
|
|
214
214
|
|
|
215
215
|
def register_for_delivery_notification(observer)
|
|
216
|
-
|
|
216
|
+
$stderr.puts("Message#register_for_delivery_notification is deprecated, please call Mail.register_observer instead")
|
|
217
217
|
Mail.register_observer(observer)
|
|
218
218
|
end
|
|
219
219
|
|
|
@@ -360,13 +360,8 @@ module Mail
|
|
|
360
360
|
if self.message_id && other.message_id
|
|
361
361
|
self.encoded == other.encoded
|
|
362
362
|
else
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
self.message_id, other.message_id = '<temp@test>', '<temp@test>'
|
|
366
|
-
self.encoded == other.encoded
|
|
367
|
-
ensure
|
|
368
|
-
self.message_id, other.message_id = self_message_id, other_message_id
|
|
369
|
-
end
|
|
363
|
+
dup.tap { |m| m.message_id = '<temp@test>' }.encoded ==
|
|
364
|
+
other.dup.tap { |m| m.message_id = '<temp@test>' }.encoded
|
|
370
365
|
end
|
|
371
366
|
end
|
|
372
367
|
|
|
@@ -1420,7 +1415,7 @@ module Mail
|
|
|
1420
1415
|
end
|
|
1421
1416
|
|
|
1422
1417
|
def has_transfer_encoding? # :nodoc:
|
|
1423
|
-
|
|
1418
|
+
$stderr.puts(":has_transfer_encoding? is deprecated in Mail 1.4.3. Please use has_content_transfer_encoding?\n#{caller}")
|
|
1424
1419
|
has_content_transfer_encoding?
|
|
1425
1420
|
end
|
|
1426
1421
|
|
|
@@ -1468,9 +1463,9 @@ module Mail
|
|
|
1468
1463
|
if !body.empty?
|
|
1469
1464
|
# Only give a warning if this isn't an attachment, has non US-ASCII and the user
|
|
1470
1465
|
# has not specified an encoding explicitly.
|
|
1471
|
-
if @defaulted_charset && body.raw_source.
|
|
1466
|
+
if @defaulted_charset && !body.raw_source.ascii_only? && !self.attachment?
|
|
1472
1467
|
warning = "Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.\n"
|
|
1473
|
-
|
|
1468
|
+
$stderr.puts(warning)
|
|
1474
1469
|
end
|
|
1475
1470
|
header[:content_type].parameters['charset'] = @charset
|
|
1476
1471
|
end
|
|
@@ -1484,18 +1479,18 @@ module Mail
|
|
|
1484
1479
|
header[:content_transfer_encoding] = '7bit'
|
|
1485
1480
|
else
|
|
1486
1481
|
warning = "Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect.\n"
|
|
1487
|
-
|
|
1482
|
+
$stderr.puts(warning)
|
|
1488
1483
|
header[:content_transfer_encoding] = '8bit'
|
|
1489
1484
|
end
|
|
1490
1485
|
end
|
|
1491
1486
|
|
|
1492
1487
|
def add_transfer_encoding # :nodoc:
|
|
1493
|
-
|
|
1488
|
+
$stderr.puts(":add_transfer_encoding is deprecated in Mail 1.4.3. Please use add_content_transfer_encoding\n#{caller}")
|
|
1494
1489
|
add_content_transfer_encoding
|
|
1495
1490
|
end
|
|
1496
1491
|
|
|
1497
1492
|
def transfer_encoding # :nodoc:
|
|
1498
|
-
|
|
1493
|
+
$stderr.puts(":transfer_encoding is deprecated in Mail 1.4.3. Please use content_transfer_encoding\n#{caller}")
|
|
1499
1494
|
content_transfer_encoding
|
|
1500
1495
|
end
|
|
1501
1496
|
|
|
@@ -1505,7 +1500,7 @@ module Mail
|
|
|
1505
1500
|
end
|
|
1506
1501
|
|
|
1507
1502
|
def message_content_type
|
|
1508
|
-
|
|
1503
|
+
$stderr.puts(":message_content_type is deprecated in Mail 1.4.3. Please use mime_type\n#{caller}")
|
|
1509
1504
|
mime_type
|
|
1510
1505
|
end
|
|
1511
1506
|
|
|
@@ -1537,7 +1532,7 @@ module Mail
|
|
|
1537
1532
|
|
|
1538
1533
|
# Returns the content type parameters
|
|
1539
1534
|
def mime_parameters
|
|
1540
|
-
|
|
1535
|
+
$stderr.puts(':mime_parameters is deprecated in Mail 1.4.3, please use :content_type_parameters instead')
|
|
1541
1536
|
content_type_parameters
|
|
1542
1537
|
end
|
|
1543
1538
|
|
|
@@ -1563,7 +1558,14 @@ module Mail
|
|
|
1563
1558
|
|
|
1564
1559
|
# returns the part in a multipart/report email that has the content-type delivery-status
|
|
1565
1560
|
def delivery_status_part
|
|
1566
|
-
|
|
1561
|
+
unless defined? @delivery_status_part
|
|
1562
|
+
@delivery_status_part =
|
|
1563
|
+
if delivery_status_report?
|
|
1564
|
+
parts.detect(&:delivery_status_report_part?)
|
|
1565
|
+
end
|
|
1566
|
+
end
|
|
1567
|
+
|
|
1568
|
+
@delivery_status_part
|
|
1567
1569
|
end
|
|
1568
1570
|
|
|
1569
1571
|
def bounced?
|
|
@@ -1798,7 +1800,6 @@ module Mail
|
|
|
1798
1800
|
# ready to send
|
|
1799
1801
|
def ready_to_send!
|
|
1800
1802
|
identify_and_set_transfer_encoding
|
|
1801
|
-
parts.sort!([ "text/plain", "text/enriched", "text/html", "multipart/alternative" ])
|
|
1802
1803
|
parts.each do |part|
|
|
1803
1804
|
part.transport_encoding = transport_encoding
|
|
1804
1805
|
part.ready_to_send!
|
|
@@ -1807,7 +1808,7 @@ module Mail
|
|
|
1807
1808
|
end
|
|
1808
1809
|
|
|
1809
1810
|
def encode!
|
|
1810
|
-
|
|
1811
|
+
$stderr.puts("Deprecated in 1.1.0 in favour of :ready_to_send! as it is less confusing with encoding and decoding.")
|
|
1811
1812
|
ready_to_send!
|
|
1812
1813
|
end
|
|
1813
1814
|
|
|
@@ -1975,7 +1976,7 @@ module Mail
|
|
|
1975
1976
|
|
|
1976
1977
|
private
|
|
1977
1978
|
|
|
1978
|
-
HEADER_SEPARATOR = /#{CRLF}#{CRLF}
|
|
1979
|
+
HEADER_SEPARATOR = /#{CRLF}#{CRLF}/
|
|
1979
1980
|
|
|
1980
1981
|
# 2.1. General Description
|
|
1981
1982
|
# A message consists of header fields (collectively called "the header
|
|
@@ -1984,9 +1985,6 @@ module Mail
|
|
|
1984
1985
|
# this standard. The body is simply a sequence of characters that
|
|
1985
1986
|
# follows the header and is separated from the header by an empty line
|
|
1986
1987
|
# (i.e., a line with nothing preceding the CRLF).
|
|
1987
|
-
#
|
|
1988
|
-
# Additionally, I allow for the case where someone might have put whitespace
|
|
1989
|
-
# on the "gap line"
|
|
1990
1988
|
def parse_message
|
|
1991
1989
|
header_part, body_part = raw_source.lstrip.split(HEADER_SEPARATOR, 2)
|
|
1992
1990
|
self.header = header_part
|
|
@@ -2130,10 +2128,10 @@ module Mail
|
|
|
2130
2128
|
content_disp_name = header[:content_disposition].filename rescue nil
|
|
2131
2129
|
content_loc_name = header[:content_location].location rescue nil
|
|
2132
2130
|
case
|
|
2133
|
-
when content_type && content_type_name
|
|
2134
|
-
filename = content_type_name
|
|
2135
2131
|
when content_disposition && content_disp_name
|
|
2136
2132
|
filename = content_disp_name
|
|
2133
|
+
when content_type && content_type_name
|
|
2134
|
+
filename = content_type_name
|
|
2137
2135
|
when content_location && content_loc_name
|
|
2138
2136
|
filename = content_loc_name
|
|
2139
2137
|
else
|