mail 2.6.1 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +150 -107
- data/lib/mail/attachments_list.rb +13 -10
- data/lib/mail/body.rb +104 -90
- data/lib/mail/check_delivery_params.rb +55 -10
- data/lib/mail/configuration.rb +3 -0
- data/lib/mail/constants.rb +79 -0
- data/lib/mail/elements/address.rb +96 -108
- data/lib/mail/elements/address_list.rb +13 -30
- data/lib/mail/elements/content_disposition_element.rb +10 -16
- data/lib/mail/elements/content_location_element.rb +9 -13
- data/lib/mail/elements/content_transfer_encoding_element.rb +7 -11
- data/lib/mail/elements/content_type_element.rb +17 -23
- data/lib/mail/elements/date_time_element.rb +8 -15
- data/lib/mail/elements/envelope_from_element.rb +23 -23
- data/lib/mail/elements/message_ids_element.rb +22 -15
- data/lib/mail/elements/mime_version_element.rb +8 -15
- data/lib/mail/elements/phrase_list.rb +13 -10
- data/lib/mail/elements/received_element.rb +28 -19
- data/lib/mail/elements.rb +1 -0
- data/lib/mail/encodings/7bit.rb +10 -14
- data/lib/mail/encodings/8bit.rb +5 -18
- data/lib/mail/encodings/base64.rb +15 -10
- data/lib/mail/encodings/binary.rb +4 -22
- data/lib/mail/encodings/identity.rb +24 -0
- data/lib/mail/encodings/quoted_printable.rb +13 -7
- data/lib/mail/encodings/transfer_encoding.rb +47 -28
- data/lib/mail/encodings/unix_to_unix.rb +20 -0
- data/lib/mail/encodings.rb +102 -92
- data/lib/mail/envelope.rb +12 -14
- data/lib/mail/field.rb +121 -85
- data/lib/mail/field_list.rb +62 -8
- data/lib/mail/fields/bcc_field.rb +42 -48
- data/lib/mail/fields/cc_field.rb +29 -50
- data/lib/mail/fields/comments_field.rb +28 -37
- data/lib/mail/fields/common_address_field.rb +170 -0
- data/lib/mail/fields/common_date_field.rb +58 -0
- data/lib/mail/fields/common_field.rb +77 -0
- data/lib/mail/fields/common_message_id_field.rb +42 -0
- data/lib/mail/fields/content_description_field.rb +8 -14
- data/lib/mail/fields/content_disposition_field.rb +20 -44
- data/lib/mail/fields/content_id_field.rb +25 -51
- data/lib/mail/fields/content_location_field.rb +12 -25
- data/lib/mail/fields/content_transfer_encoding_field.rb +32 -31
- data/lib/mail/fields/content_type_field.rb +51 -80
- data/lib/mail/fields/date_field.rb +24 -52
- data/lib/mail/fields/from_field.rb +29 -50
- data/lib/mail/fields/in_reply_to_field.rb +39 -49
- data/lib/mail/fields/keywords_field.rb +19 -32
- data/lib/mail/fields/message_id_field.rb +26 -71
- data/lib/mail/fields/mime_version_field.rb +20 -30
- data/lib/mail/fields/named_structured_field.rb +11 -0
- data/lib/mail/fields/named_unstructured_field.rb +11 -0
- data/lib/mail/fields/optional_field.rb +10 -7
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +16 -13
- data/lib/mail/fields/received_field.rb +44 -57
- data/lib/mail/fields/references_field.rb +36 -49
- data/lib/mail/fields/reply_to_field.rb +29 -50
- data/lib/mail/fields/resent_bcc_field.rb +29 -50
- data/lib/mail/fields/resent_cc_field.rb +29 -50
- data/lib/mail/fields/resent_date_field.rb +6 -30
- data/lib/mail/fields/resent_from_field.rb +29 -50
- data/lib/mail/fields/resent_message_id_field.rb +6 -29
- data/lib/mail/fields/resent_sender_field.rb +28 -57
- data/lib/mail/fields/resent_to_field.rb +29 -50
- data/lib/mail/fields/return_path_field.rb +51 -55
- data/lib/mail/fields/sender_field.rb +35 -56
- data/lib/mail/fields/structured_field.rb +4 -30
- data/lib/mail/fields/subject_field.rb +10 -11
- data/lib/mail/fields/to_field.rb +29 -50
- data/lib/mail/fields/unstructured_field.rb +36 -50
- data/lib/mail/fields.rb +1 -0
- data/lib/mail/header.rb +73 -110
- data/lib/mail/indifferent_hash.rb +1 -0
- data/lib/mail/mail.rb +6 -11
- data/lib/mail/matchers/attachment_matchers.rb +44 -0
- data/lib/mail/matchers/has_sent_mail.rb +53 -9
- data/lib/mail/message.rb +132 -136
- data/lib/mail/multibyte/chars.rb +24 -180
- data/lib/mail/multibyte/unicode.rb +31 -26
- data/lib/mail/multibyte/utils.rb +27 -43
- data/lib/mail/multibyte.rb +56 -16
- data/lib/mail/network/delivery_methods/exim.rb +9 -11
- data/lib/mail/network/delivery_methods/file_delivery.rb +14 -16
- data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +68 -24
- data/lib/mail/network/delivery_methods/smtp.rb +77 -54
- data/lib/mail/network/delivery_methods/smtp_connection.rb +5 -9
- data/lib/mail/network/delivery_methods/test_mailer.rb +9 -9
- data/lib/mail/network/retriever_methods/base.rb +9 -8
- data/lib/mail/network/retriever_methods/imap.rb +21 -7
- data/lib/mail/network/retriever_methods/pop3.rb +6 -3
- data/lib/mail/network/retriever_methods/test_retriever.rb +4 -2
- data/lib/mail/network.rb +2 -0
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +33226 -116
- data/lib/mail/parsers/address_lists_parser.rl +179 -0
- data/lib/mail/parsers/content_disposition_parser.rb +883 -49
- data/lib/mail/parsers/content_disposition_parser.rl +89 -0
- data/lib/mail/parsers/content_location_parser.rb +810 -23
- data/lib/mail/parsers/content_location_parser.rl +78 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +510 -21
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
- data/lib/mail/parsers/content_type_parser.rb +1031 -47
- data/lib/mail/parsers/content_type_parser.rl +90 -0
- data/lib/mail/parsers/date_time_parser.rb +879 -24
- data/lib/mail/parsers/date_time_parser.rl +69 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3670 -40
- data/lib/mail/parsers/envelope_from_parser.rl +89 -0
- data/lib/mail/parsers/message_ids_parser.rb +5147 -25
- data/lib/mail/parsers/message_ids_parser.rl +93 -0
- data/lib/mail/parsers/mime_version_parser.rb +498 -26
- data/lib/mail/parsers/mime_version_parser.rl +68 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +872 -21
- data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
- data/lib/mail/parsers/received_parser.rb +8777 -42
- data/lib/mail/parsers/received_parser.rl +91 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
- data/lib/mail/parsers/rfc2045_mime.rl +16 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
- data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
- data/lib/mail/parsers/rfc5322.rl +74 -0
- data/lib/mail/parsers/rfc5322_address.rl +72 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/lib/mail/parsers.rb +12 -25
- data/lib/mail/part.rb +11 -12
- data/lib/mail/parts_list.rb +88 -14
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +377 -40
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +8 -15
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +9 -32
- metadata +138 -94
- data/CHANGELOG.rdoc +0 -752
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -2
- data/Gemfile +0 -15
- data/Rakefile +0 -29
- data/TODO.rdoc +0 -9
- data/VERSION +0 -4
- data/lib/mail/core_extensions/nil.rb +0 -19
- data/lib/mail/core_extensions/object.rb +0 -13
- data/lib/mail/core_extensions/smtp.rb +0 -24
- data/lib/mail/core_extensions/string/access.rb +0 -145
- data/lib/mail/core_extensions/string/multibyte.rb +0 -78
- data/lib/mail/core_extensions/string.rb +0 -43
- data/lib/mail/fields/common/address_container.rb +0 -16
- data/lib/mail/fields/common/common_address.rb +0 -135
- data/lib/mail/fields/common/common_date.rb +0 -35
- data/lib/mail/fields/common/common_field.rb +0 -57
- data/lib/mail/fields/common/common_message_id.rb +0 -48
- data/lib/mail/multibyte/exceptions.rb +0 -8
- data/lib/mail/parsers/ragel/common.rl +0 -184
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- 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 -2129
- 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
- data/lib/mail/parsers/ragel/ruby.rb +0 -39
- data/lib/mail/parsers/ragel.rb +0 -17
- data/lib/mail/patterns.rb +0 -37
- data/lib/mail/version_specific/ruby_1_8.rb +0 -119
- data/lib/mail/version_specific/ruby_1_9.rb +0 -159
data/lib/mail/message.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'mail/constants'
|
4
|
+
require 'mail/utilities'
|
5
|
+
require 'mail/yaml'
|
3
6
|
|
4
7
|
module Mail
|
5
8
|
# The Message class provides a single point of access to all things to do with an
|
@@ -45,25 +48,29 @@ module Mail
|
|
45
48
|
# follows the header and is separated from the header by an empty line
|
46
49
|
# (i.e., a line with nothing preceding the CRLF).
|
47
50
|
class Message
|
48
|
-
|
49
|
-
include Patterns
|
50
|
-
include Utilities
|
51
|
-
|
52
51
|
# ==Making an email
|
53
52
|
#
|
54
53
|
# You can make an new mail object via a block, passing a string, file or direct assignment.
|
55
54
|
#
|
56
55
|
# ===Making an email via a block
|
57
56
|
#
|
58
|
-
# mail = Mail.new do
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# subject 'This is a test email'
|
62
|
-
#
|
57
|
+
# mail = Mail.new do |m|
|
58
|
+
# m.from 'mikel@test.lindsaar.net'
|
59
|
+
# m.to 'you@test.lindsaar.net'
|
60
|
+
# m.subject 'This is a test email'
|
61
|
+
# m.body File.read('body.txt')
|
63
62
|
# end
|
64
63
|
#
|
65
64
|
# mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
|
66
65
|
#
|
66
|
+
# If may also pass a block with no arguments, in which case it will
|
67
|
+
# be evaluated in the scope of the new message instance:
|
68
|
+
#
|
69
|
+
# mail = Mail.new do
|
70
|
+
# from 'mikel@test.lindsaar.net'
|
71
|
+
# # …
|
72
|
+
# end
|
73
|
+
#
|
67
74
|
# ===Making an email via passing a string
|
68
75
|
#
|
69
76
|
# mail = Mail.new("To: mikel@test.lindsaar.net\r\nSubject: Hello\r\n\r\nHi there!")
|
@@ -105,7 +112,7 @@ module Mail
|
|
105
112
|
@html_part = nil
|
106
113
|
@errors = nil
|
107
114
|
@header = nil
|
108
|
-
@charset =
|
115
|
+
@charset = self.class.default_charset
|
109
116
|
@defaulted_charset = true
|
110
117
|
|
111
118
|
@smtp_envelope_from = nil
|
@@ -128,8 +135,23 @@ module Mail
|
|
128
135
|
init_with_string(args.flatten[0].to_s)
|
129
136
|
end
|
130
137
|
|
138
|
+
# Support both builder styles:
|
139
|
+
#
|
140
|
+
# Mail.new do
|
141
|
+
# to 'recipient@example.com'
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# and
|
145
|
+
#
|
146
|
+
# Mail.new do |m|
|
147
|
+
# m.to 'recipient@example.com'
|
148
|
+
# end
|
131
149
|
if block_given?
|
132
|
-
|
150
|
+
if block.arity.zero?
|
151
|
+
instance_eval(&block)
|
152
|
+
else
|
153
|
+
yield self
|
154
|
+
end
|
133
155
|
end
|
134
156
|
|
135
157
|
self
|
@@ -207,10 +229,9 @@ module Mail
|
|
207
229
|
# define a delivery_handler
|
208
230
|
attr_accessor :raise_delivery_errors
|
209
231
|
|
210
|
-
def
|
211
|
-
|
212
|
-
|
213
|
-
end
|
232
|
+
def self.default_charset; @@default_charset; end
|
233
|
+
def self.default_charset=(charset); @@default_charset = charset; end
|
234
|
+
self.default_charset = 'UTF-8'
|
214
235
|
|
215
236
|
def inform_observers
|
216
237
|
Mail.inform_observers(self)
|
@@ -220,7 +241,7 @@ module Mail
|
|
220
241
|
Mail.inform_interceptors(self)
|
221
242
|
end
|
222
243
|
|
223
|
-
# Delivers
|
244
|
+
# Delivers a mail object.
|
224
245
|
#
|
225
246
|
# Examples:
|
226
247
|
#
|
@@ -273,7 +294,7 @@ module Mail
|
|
273
294
|
reply.references ||= bracketed_message_id
|
274
295
|
end
|
275
296
|
if subject
|
276
|
-
reply.subject = subject =~ /^Re:/i ? subject : "
|
297
|
+
reply.subject = subject =~ /^Re:/i ? subject : "Re: #{subject}"
|
277
298
|
end
|
278
299
|
if reply_to || from
|
279
300
|
reply.to = self[reply_to ? :reply_to : :from].to_s
|
@@ -355,13 +376,8 @@ module Mail
|
|
355
376
|
if self.message_id && other.message_id
|
356
377
|
self.encoded == other.encoded
|
357
378
|
else
|
358
|
-
|
359
|
-
|
360
|
-
self.message_id, other.message_id = '<temp@test>', '<temp@test>'
|
361
|
-
self.encoded == other.encoded
|
362
|
-
ensure
|
363
|
-
self.message_id, other.message_id = self_message_id, other_message_id
|
364
|
-
end
|
379
|
+
dup.tap { |m| m.message_id = '<temp@test>' }.encoded ==
|
380
|
+
other.dup.tap { |m| m.message_id = '<temp@test>' }.encoded
|
365
381
|
end
|
366
382
|
end
|
367
383
|
|
@@ -383,9 +399,9 @@ module Mail
|
|
383
399
|
end
|
384
400
|
|
385
401
|
# Sets the envelope from for the email
|
386
|
-
def set_envelope(
|
402
|
+
def set_envelope(val)
|
387
403
|
@raw_envelope = val
|
388
|
-
@envelope = Mail::Envelope.
|
404
|
+
@envelope = Mail::Envelope.parse(val) rescue nil
|
389
405
|
end
|
390
406
|
|
391
407
|
# The raw_envelope is the From mikel@test.lindsaar.net Mon May 2 16:07:05 2009
|
@@ -1188,8 +1204,8 @@ module Mail
|
|
1188
1204
|
def default( sym, val = nil )
|
1189
1205
|
if val
|
1190
1206
|
header[sym] = val
|
1191
|
-
|
1192
|
-
|
1207
|
+
elsif field = header[sym]
|
1208
|
+
field.default
|
1193
1209
|
end
|
1194
1210
|
end
|
1195
1211
|
|
@@ -1235,14 +1251,13 @@ module Mail
|
|
1235
1251
|
def body(value = nil)
|
1236
1252
|
if value
|
1237
1253
|
self.body = value
|
1238
|
-
# add_encoding_to_body
|
1239
1254
|
else
|
1240
1255
|
process_body_raw if @body_raw
|
1241
1256
|
@body
|
1242
1257
|
end
|
1243
1258
|
end
|
1244
1259
|
|
1245
|
-
def body_encoding(value)
|
1260
|
+
def body_encoding(value = nil)
|
1246
1261
|
if value.nil?
|
1247
1262
|
body.encoding
|
1248
1263
|
else
|
@@ -1251,7 +1266,7 @@ module Mail
|
|
1251
1266
|
end
|
1252
1267
|
|
1253
1268
|
def body_encoding=(value)
|
1254
|
-
|
1269
|
+
body.encoding = value
|
1255
1270
|
end
|
1256
1271
|
|
1257
1272
|
# Returns the list of addresses this message should be sent to by
|
@@ -1317,7 +1332,7 @@ module Mail
|
|
1317
1332
|
# mail['foo'] = '1234'
|
1318
1333
|
# mail['foo'].to_s #=> '1234'
|
1319
1334
|
def [](name)
|
1320
|
-
header[underscoreize(name)]
|
1335
|
+
header[Utilities.underscoreize(name)]
|
1321
1336
|
end
|
1322
1337
|
|
1323
1338
|
# Method Missing in this implementation allows you to set any of the
|
@@ -1363,7 +1378,7 @@ module Mail
|
|
1363
1378
|
#:nodoc:
|
1364
1379
|
# Only take the structured fields, as we could take _anything_ really
|
1365
1380
|
# as it could become an optional field... "but therin lies the dark side"
|
1366
|
-
field_name = underscoreize(name).chomp("=")
|
1381
|
+
field_name = Utilities.underscoreize(name).chomp("=")
|
1367
1382
|
if Mail::Field::KNOWN_FIELDS.include?(field_name)
|
1368
1383
|
if args.empty?
|
1369
1384
|
header[field_name]
|
@@ -1411,12 +1426,7 @@ module Mail
|
|
1411
1426
|
end
|
1412
1427
|
|
1413
1428
|
def has_content_transfer_encoding?
|
1414
|
-
header[:content_transfer_encoding] && header[:content_transfer_encoding].errors
|
1415
|
-
end
|
1416
|
-
|
1417
|
-
def has_transfer_encoding? # :nodoc:
|
1418
|
-
STDERR.puts(":has_transfer_encoding? is deprecated in Mail 1.4.3. Please use has_content_transfer_encoding?\n#{caller}")
|
1419
|
-
has_content_transfer_encoding?
|
1429
|
+
header[:content_transfer_encoding] && Utilities.blank?(header[:content_transfer_encoding].errors)
|
1420
1430
|
end
|
1421
1431
|
|
1422
1432
|
# Creates a new empty Message-ID field and inserts it in the correct order
|
@@ -1463,35 +1473,19 @@ module Mail
|
|
1463
1473
|
if !body.empty?
|
1464
1474
|
# Only give a warning if this isn't an attachment, has non US-ASCII and the user
|
1465
1475
|
# has not specified an encoding explicitly.
|
1466
|
-
if @defaulted_charset && body.raw_source.
|
1476
|
+
if @defaulted_charset && !body.raw_source.ascii_only? && !self.attachment?
|
1467
1477
|
warning = "Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.\n"
|
1468
|
-
|
1478
|
+
warn(warning)
|
1479
|
+
end
|
1480
|
+
if @charset
|
1481
|
+
header[:content_type].parameters['charset'] = @charset
|
1469
1482
|
end
|
1470
|
-
header[:content_type].parameters['charset'] = @charset
|
1471
1483
|
end
|
1472
1484
|
end
|
1473
1485
|
|
1474
1486
|
# Adds a content transfer encoding
|
1475
|
-
#
|
1476
|
-
# Otherwise raises a warning
|
1477
1487
|
def add_content_transfer_encoding
|
1478
|
-
|
1479
|
-
header[:content_transfer_encoding] = '7bit'
|
1480
|
-
else
|
1481
|
-
warning = "Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect.\n"
|
1482
|
-
STDERR.puts(warning)
|
1483
|
-
header[:content_transfer_encoding] = '8bit'
|
1484
|
-
end
|
1485
|
-
end
|
1486
|
-
|
1487
|
-
def add_transfer_encoding # :nodoc:
|
1488
|
-
STDERR.puts(":add_transfer_encoding is deprecated in Mail 1.4.3. Please use add_content_transfer_encoding\n#{caller}")
|
1489
|
-
add_content_transfer_encoding
|
1490
|
-
end
|
1491
|
-
|
1492
|
-
def transfer_encoding # :nodoc:
|
1493
|
-
STDERR.puts(":transfer_encoding is deprecated in Mail 1.4.3. Please use content_transfer_encoding\n#{caller}")
|
1494
|
-
content_transfer_encoding
|
1488
|
+
header[:content_transfer_encoding] ||= body.default_encoding
|
1495
1489
|
end
|
1496
1490
|
|
1497
1491
|
# Returns the MIME media type of part we are on, this is taken from the content-type header
|
@@ -1499,15 +1493,10 @@ module Mail
|
|
1499
1493
|
has_content_type? ? header[:content_type].string : nil rescue nil
|
1500
1494
|
end
|
1501
1495
|
|
1502
|
-
def message_content_type
|
1503
|
-
STDERR.puts(":message_content_type is deprecated in Mail 1.4.3. Please use mime_type\n#{caller}")
|
1504
|
-
mime_type
|
1505
|
-
end
|
1506
|
-
|
1507
1496
|
# Returns the character set defined in the content type field
|
1508
1497
|
def charset
|
1509
1498
|
if @header
|
1510
|
-
has_content_type? ? content_type_parameters['charset'] : @charset
|
1499
|
+
has_content_type? && !multipart? ? content_type_parameters['charset'] : @charset
|
1511
1500
|
else
|
1512
1501
|
@charset
|
1513
1502
|
end
|
@@ -1530,12 +1519,6 @@ module Mail
|
|
1530
1519
|
has_content_type? ? header[:content_type].sub_type : nil rescue nil
|
1531
1520
|
end
|
1532
1521
|
|
1533
|
-
# Returns the content type parameters
|
1534
|
-
def mime_parameters
|
1535
|
-
STDERR.puts(':mime_parameters is deprecated in Mail 1.4.3, please use :content_type_parameters instead')
|
1536
|
-
content_type_parameters
|
1537
|
-
end
|
1538
|
-
|
1539
1522
|
# Returns the content type parameters
|
1540
1523
|
def content_type_parameters
|
1541
1524
|
has_content_type? ? header[:content_type].parameters : nil rescue nil
|
@@ -1558,7 +1541,14 @@ module Mail
|
|
1558
1541
|
|
1559
1542
|
# returns the part in a multipart/report email that has the content-type delivery-status
|
1560
1543
|
def delivery_status_part
|
1561
|
-
|
1544
|
+
unless defined? @delivery_status_part
|
1545
|
+
@delivery_status_part =
|
1546
|
+
if delivery_status_report?
|
1547
|
+
parts.detect(&:delivery_status_report_part?)
|
1548
|
+
end
|
1549
|
+
end
|
1550
|
+
|
1551
|
+
@delivery_status_part
|
1562
1552
|
end
|
1563
1553
|
|
1564
1554
|
def bounced?
|
@@ -1665,6 +1655,8 @@ module Mail
|
|
1665
1655
|
def html_part=(msg)
|
1666
1656
|
# Assign the html part and set multipart/alternative if there's a text part.
|
1667
1657
|
if msg
|
1658
|
+
msg = Mail::Part.new(:body => msg) unless msg.kind_of?(Mail::Message)
|
1659
|
+
|
1668
1660
|
@html_part = msg
|
1669
1661
|
@html_part.content_type = 'text/html' unless @html_part.has_content_type?
|
1670
1662
|
add_multipart_alternate_header if text_part
|
@@ -1687,6 +1679,8 @@ module Mail
|
|
1687
1679
|
def text_part=(msg)
|
1688
1680
|
# Assign the text part and set multipart/alternative if there's an html part.
|
1689
1681
|
if msg
|
1682
|
+
msg = Mail::Part.new(:body => msg) unless msg.kind_of?(Mail::Message)
|
1683
|
+
|
1690
1684
|
@text_part = msg
|
1691
1685
|
@text_part.content_type = 'text/plain' unless @text_part.has_content_type?
|
1692
1686
|
add_multipart_alternate_header if html_part
|
@@ -1705,7 +1699,7 @@ module Mail
|
|
1705
1699
|
|
1706
1700
|
# Adds a part to the parts list or creates the part list
|
1707
1701
|
def add_part(part)
|
1708
|
-
if !body.multipart? && !self.body.decoded
|
1702
|
+
if !body.multipart? && !Utilities.blank?(self.body.decoded)
|
1709
1703
|
@text_part = Mail::Part.new('Content-Type: text/plain;')
|
1710
1704
|
@text_part.body = body.decoded
|
1711
1705
|
self.body << @text_part
|
@@ -1761,24 +1755,34 @@ module Mail
|
|
1761
1755
|
#
|
1762
1756
|
# See also #attachments
|
1763
1757
|
def add_file(values)
|
1764
|
-
convert_to_multipart unless self.multipart? || self.body.decoded
|
1758
|
+
convert_to_multipart unless self.multipart? || Utilities.blank?(self.body.decoded)
|
1765
1759
|
add_multipart_mixed_header
|
1766
1760
|
if values.is_a?(String)
|
1767
1761
|
basename = File.basename(values)
|
1768
1762
|
filedata = File.open(values, 'rb') { |f| f.read }
|
1769
1763
|
else
|
1770
1764
|
basename = values[:filename]
|
1771
|
-
filedata = values
|
1765
|
+
filedata = values
|
1772
1766
|
end
|
1773
1767
|
self.attachments[basename] = filedata
|
1774
1768
|
end
|
1775
1769
|
|
1770
|
+
MULTIPART_CONVERSION_CONTENT_FIELDS = [ :content_description, :content_disposition, :content_transfer_encoding, :content_type ]
|
1771
|
+
private_constant :MULTIPART_CONVERSION_CONTENT_FIELDS if respond_to?(:private_constant)
|
1772
|
+
|
1776
1773
|
def convert_to_multipart
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1774
|
+
text_part = Mail::Part.new(:body => body.decoded)
|
1775
|
+
|
1776
|
+
MULTIPART_CONVERSION_CONTENT_FIELDS.each do |field_name|
|
1777
|
+
if value = send(field_name)
|
1778
|
+
writer = :"#{field_name}="
|
1779
|
+
text_part.send writer, value
|
1780
|
+
send writer, nil
|
1781
|
+
end
|
1782
|
+
end
|
1781
1783
|
text_part.charset = charset unless @defaulted_charset
|
1784
|
+
|
1785
|
+
self.body = ''
|
1782
1786
|
self.body << text_part
|
1783
1787
|
end
|
1784
1788
|
|
@@ -1786,7 +1790,6 @@ module Mail
|
|
1786
1790
|
# ready to send
|
1787
1791
|
def ready_to_send!
|
1788
1792
|
identify_and_set_transfer_encoding
|
1789
|
-
parts.sort!([ "text/plain", "text/enriched", "text/html", "multipart/alternative" ])
|
1790
1793
|
parts.each do |part|
|
1791
1794
|
part.transport_encoding = transport_encoding
|
1792
1795
|
part.ready_to_send!
|
@@ -1794,11 +1797,6 @@ module Mail
|
|
1794
1797
|
add_required_fields
|
1795
1798
|
end
|
1796
1799
|
|
1797
|
-
def encode!
|
1798
|
-
STDERR.puts("Deprecated in 1.1.0 in favour of :ready_to_send! as it is less confusing with encoding and decoding.")
|
1799
|
-
ready_to_send!
|
1800
|
-
end
|
1801
|
-
|
1802
1800
|
# Outputs an encoded string representation of the mail message including
|
1803
1801
|
# all headers, attachments, etc. This is an encoded email in US-ASCII,
|
1804
1802
|
# so it is able to be directly sent to an email server.
|
@@ -1811,16 +1809,13 @@ module Mail
|
|
1811
1809
|
end
|
1812
1810
|
|
1813
1811
|
def without_attachments!
|
1814
|
-
|
1815
|
-
|
1816
|
-
parts.delete_if { |p| p.attachment? }
|
1817
|
-
body_raw = if parts.empty?
|
1818
|
-
''
|
1819
|
-
else
|
1820
|
-
body.encoded
|
1821
|
-
end
|
1812
|
+
if has_attachments?
|
1813
|
+
parts.delete_attachments
|
1822
1814
|
|
1823
|
-
|
1815
|
+
reencoded = parts.empty? ? '' : body.encoded(content_transfer_encoding)
|
1816
|
+
@body = nil # So the new parts won't be added to the existing body
|
1817
|
+
self.body = reencoded
|
1818
|
+
end
|
1824
1819
|
|
1825
1820
|
self
|
1826
1821
|
end
|
@@ -1846,14 +1841,14 @@ module Mail
|
|
1846
1841
|
end
|
1847
1842
|
|
1848
1843
|
def self.from_yaml(str)
|
1849
|
-
hash = YAML.load(str)
|
1844
|
+
hash = Mail::YAML.load(str)
|
1850
1845
|
m = self.new(:headers => hash['headers'])
|
1851
1846
|
hash.delete('headers')
|
1852
1847
|
hash.each do |k,v|
|
1853
1848
|
case
|
1854
1849
|
when k == 'delivery_handler'
|
1855
1850
|
begin
|
1856
|
-
m.delivery_handler = Object.const_get(v) unless
|
1851
|
+
m.delivery_handler = Object.const_get(v) unless Utilities.blank?(v)
|
1857
1852
|
rescue NameError
|
1858
1853
|
end
|
1859
1854
|
when k == 'transport_encoding'
|
@@ -1879,6 +1874,15 @@ module Mail
|
|
1879
1874
|
"#<#{self.class}:#{self.object_id}, Multipart: #{multipart?}, Headers: #{header.field_summary}>"
|
1880
1875
|
end
|
1881
1876
|
|
1877
|
+
def inspect_structure
|
1878
|
+
inspect +
|
1879
|
+
if self.multipart?
|
1880
|
+
"\n" + parts.inspect_structure
|
1881
|
+
else
|
1882
|
+
''
|
1883
|
+
end
|
1884
|
+
end
|
1885
|
+
|
1882
1886
|
def decoded
|
1883
1887
|
case
|
1884
1888
|
when self.text?
|
@@ -1963,6 +1967,8 @@ module Mail
|
|
1963
1967
|
|
1964
1968
|
private
|
1965
1969
|
|
1970
|
+
HEADER_SEPARATOR = /#{Constants::LAX_CRLF}#{Constants::LAX_CRLF}/
|
1971
|
+
|
1966
1972
|
# 2.1. General Description
|
1967
1973
|
# A message consists of header fields (collectively called "the header
|
1968
1974
|
# of the message") followed, optionally, by a body. The header is a
|
@@ -1970,19 +1976,14 @@ module Mail
|
|
1970
1976
|
# this standard. The body is simply a sequence of characters that
|
1971
1977
|
# follows the header and is separated from the header by an empty line
|
1972
1978
|
# (i.e., a line with nothing preceding the CRLF).
|
1973
|
-
#
|
1974
|
-
# Additionally, I allow for the case where someone might have put whitespace
|
1975
|
-
# on the "gap line"
|
1976
1979
|
def parse_message
|
1977
|
-
header_part, body_part = raw_source.lstrip.split(
|
1980
|
+
header_part, body_part = raw_source.lstrip.split(HEADER_SEPARATOR, 2)
|
1978
1981
|
self.header = header_part
|
1979
1982
|
self.body = body_part
|
1980
1983
|
end
|
1981
1984
|
|
1982
1985
|
def raw_source=(value)
|
1983
|
-
@raw_source = value
|
1984
|
-
@raw_source.force_encoding("binary") if RUBY_VERSION >= "1.9.1"
|
1985
|
-
@raw_source
|
1986
|
+
@raw_source = value
|
1986
1987
|
end
|
1987
1988
|
|
1988
1989
|
# see comments to body=. We take data and process it lazily
|
@@ -1994,11 +1995,9 @@ module Mail
|
|
1994
1995
|
@body_raw = nil
|
1995
1996
|
add_encoding_to_body
|
1996
1997
|
when @body && @body.multipart?
|
1997
|
-
|
1998
|
-
add_encoding_to_body
|
1998
|
+
self.text_part = value
|
1999
1999
|
else
|
2000
2000
|
@body_raw = value
|
2001
|
-
# process_body_raw
|
2002
2001
|
end
|
2003
2002
|
end
|
2004
2003
|
|
@@ -2013,9 +2012,9 @@ module Mail
|
|
2013
2012
|
|
2014
2013
|
def set_envelope_header
|
2015
2014
|
raw_string = raw_source.to_s
|
2016
|
-
if match_data =
|
2015
|
+
if match_data = raw_string.match(/\AFrom\s+([^:\s]#{Constants::TEXT}*)#{Constants::LAX_CRLF}/m)
|
2017
2016
|
set_envelope(match_data[1])
|
2018
|
-
self.raw_source = raw_string.sub(match_data[0], "")
|
2017
|
+
self.raw_source = raw_string.sub(match_data[0], "")
|
2019
2018
|
end
|
2020
2019
|
end
|
2021
2020
|
|
@@ -2023,6 +2022,13 @@ module Mail
|
|
2023
2022
|
body.split!(boundary)
|
2024
2023
|
end
|
2025
2024
|
|
2025
|
+
def allowed_encodings
|
2026
|
+
case mime_type
|
2027
|
+
when 'message/rfc822'
|
2028
|
+
[Encodings::SevenBit, Encodings::EightBit, Encodings::Binary]
|
2029
|
+
end
|
2030
|
+
end
|
2031
|
+
|
2026
2032
|
def add_encoding_to_body
|
2027
2033
|
if has_content_transfer_encoding?
|
2028
2034
|
@body.encoding = content_transfer_encoding
|
@@ -2030,18 +2036,20 @@ module Mail
|
|
2030
2036
|
end
|
2031
2037
|
|
2032
2038
|
def identify_and_set_transfer_encoding
|
2033
|
-
|
2034
|
-
|
2039
|
+
if body
|
2040
|
+
if body.multipart?
|
2041
|
+
self.content_transfer_encoding = @transport_encoding
|
2035
2042
|
else
|
2036
|
-
|
2043
|
+
self.content_transfer_encoding = body.negotiate_best_encoding(@transport_encoding, allowed_encodings).to_s
|
2037
2044
|
end
|
2045
|
+
end
|
2038
2046
|
end
|
2039
2047
|
|
2040
2048
|
def add_required_fields
|
2041
2049
|
add_required_message_fields
|
2042
2050
|
add_multipart_mixed_header if body.multipart?
|
2043
2051
|
add_content_type unless has_content_type?
|
2044
|
-
add_charset
|
2052
|
+
add_charset if text? && !has_charset?
|
2045
2053
|
add_content_transfer_encoding unless has_content_transfer_encoding?
|
2046
2054
|
end
|
2047
2055
|
|
@@ -2053,15 +2061,17 @@ module Mail
|
|
2053
2061
|
|
2054
2062
|
def add_multipart_alternate_header
|
2055
2063
|
header['content-type'] = ContentTypeField.with_boundary('multipart/alternative').value
|
2056
|
-
header['content_type'].parameters[:charset] = @charset
|
2057
2064
|
body.boundary = boundary
|
2058
2065
|
end
|
2059
2066
|
|
2060
2067
|
def add_boundary
|
2061
2068
|
unless body.boundary && boundary
|
2062
|
-
|
2069
|
+
unless header['content-type']
|
2070
|
+
_charset = charset
|
2071
|
+
header['content-type'] = 'multipart/mixed'
|
2072
|
+
header['content-type'].parameters[:charset] = _charset
|
2073
|
+
end
|
2063
2074
|
header['content-type'].parameters[:boundary] = ContentTypeField.generate_boundary
|
2064
|
-
header['content_type'].parameters[:charset] = @charset
|
2065
2075
|
body.boundary = boundary
|
2066
2076
|
end
|
2067
2077
|
end
|
@@ -2069,7 +2079,6 @@ module Mail
|
|
2069
2079
|
def add_multipart_mixed_header
|
2070
2080
|
unless header['content-type']
|
2071
2081
|
header['content-type'] = ContentTypeField.with_boundary('multipart/mixed').value
|
2072
|
-
header['content_type'].parameters[:charset] = @charset
|
2073
2082
|
body.boundary = boundary
|
2074
2083
|
end
|
2075
2084
|
end
|
@@ -2086,7 +2095,7 @@ module Mail
|
|
2086
2095
|
body_content = nil
|
2087
2096
|
|
2088
2097
|
passed_in_options.each_pair do |k,v|
|
2089
|
-
k = underscoreize(k).to_sym if k.class == String
|
2098
|
+
k = Utilities.underscoreize(k).to_sym if k.class == String
|
2090
2099
|
if k == :headers
|
2091
2100
|
self.headers(v)
|
2092
2101
|
elsif k == :body
|
@@ -2117,10 +2126,10 @@ module Mail
|
|
2117
2126
|
content_disp_name = header[:content_disposition].filename rescue nil
|
2118
2127
|
content_loc_name = header[:content_location].location rescue nil
|
2119
2128
|
case
|
2120
|
-
when content_type && content_type_name
|
2121
|
-
filename = content_type_name
|
2122
2129
|
when content_disposition && content_disp_name
|
2123
2130
|
filename = content_disp_name
|
2131
|
+
when content_type && content_type_name
|
2132
|
+
filename = content_type_name
|
2124
2133
|
when content_location && content_loc_name
|
2125
2134
|
filename = content_loc_name
|
2126
2135
|
else
|
@@ -2141,20 +2150,7 @@ module Mail
|
|
2141
2150
|
end
|
2142
2151
|
|
2143
2152
|
def decode_body_as_text
|
2144
|
-
|
2145
|
-
if charset
|
2146
|
-
if RUBY_VERSION < '1.9'
|
2147
|
-
require 'iconv'
|
2148
|
-
return Iconv.conv("UTF-8//TRANSLIT//IGNORE", charset, body_text)
|
2149
|
-
else
|
2150
|
-
if encoding = Encoding.find(charset) rescue nil
|
2151
|
-
body_text.force_encoding(encoding)
|
2152
|
-
return body_text.encode(Encoding::UTF_8, :undef => :replace, :invalid => :replace, :replace => '')
|
2153
|
-
end
|
2154
|
-
end
|
2155
|
-
end
|
2156
|
-
body_text
|
2153
|
+
Encodings.transcode_charset decode_body, charset, 'UTF-8'
|
2157
2154
|
end
|
2158
|
-
|
2159
2155
|
end
|
2160
2156
|
end
|