mail 2.5.5 → 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 +170 -108
- data/lib/mail/attachments_list.rb +13 -10
- data/lib/mail/body.rb +105 -91
- data/lib/mail/check_delivery_params.rb +30 -22
- data/lib/mail/configuration.rb +3 -0
- data/lib/mail/constants.rb +79 -0
- data/lib/mail/elements/address.rb +118 -174
- data/lib/mail/elements/address_list.rb +16 -56
- data/lib/mail/elements/content_disposition_element.rb +12 -22
- data/lib/mail/elements/content_location_element.rb +9 -17
- data/lib/mail/elements/content_transfer_encoding_element.rb +8 -19
- data/lib/mail/elements/content_type_element.rb +20 -30
- data/lib/mail/elements/date_time_element.rb +10 -21
- data/lib/mail/elements/envelope_from_element.rb +23 -31
- data/lib/mail/elements/message_ids_element.rb +22 -20
- data/lib/mail/elements/mime_version_element.rb +10 -21
- data/lib/mail/elements/phrase_list.rb +13 -15
- data/lib/mail/elements/received_element.rb +26 -21
- 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 -93
- data/lib/mail/envelope.rb +12 -19
- data/lib/mail/field.rb +143 -71
- data/lib/mail/field_list.rb +73 -19
- 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 +31 -36
- 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 +43 -51
- data/lib/mail/fields.rb +1 -0
- data/lib/mail/header.rb +78 -129
- data/lib/mail/indifferent_hash.rb +1 -0
- data/lib/mail/mail.rb +18 -11
- data/lib/mail/matchers/attachment_matchers.rb +44 -0
- data/lib/mail/matchers/has_sent_mail.rb +81 -4
- data/lib/mail/message.rb +142 -139
- data/lib/mail/multibyte/chars.rb +24 -180
- data/lib/mail/multibyte/unicode.rb +32 -27
- data/lib/mail/multibyte/utils.rb +27 -43
- data/lib/mail/multibyte.rb +56 -16
- data/lib/mail/network/delivery_methods/exim.rb +6 -4
- data/lib/mail/network/delivery_methods/file_delivery.rb +12 -10
- data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +63 -21
- data/lib/mail/network/delivery_methods/smtp.rb +76 -50
- data/lib/mail/network/delivery_methods/smtp_connection.rb +4 -4
- data/lib/mail/network/delivery_methods/test_mailer.rb +5 -2
- data/lib/mail/network/retriever_methods/base.rb +9 -8
- data/lib/mail/network/retriever_methods/imap.rb +37 -18
- 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 +33242 -0
- data/lib/mail/parsers/address_lists_parser.rl +179 -0
- data/lib/mail/parsers/content_disposition_parser.rb +901 -0
- data/lib/mail/parsers/content_disposition_parser.rl +89 -0
- data/lib/mail/parsers/content_location_parser.rb +822 -0
- data/lib/mail/parsers/content_location_parser.rl +78 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +522 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
- data/lib/mail/parsers/content_type_parser.rb +1048 -0
- data/lib/mail/parsers/content_type_parser.rl +90 -0
- data/lib/mail/parsers/date_time_parser.rb +891 -0
- data/lib/mail/parsers/date_time_parser.rl +69 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3675 -0
- data/lib/mail/parsers/envelope_from_parser.rl +89 -0
- data/lib/mail/parsers/message_ids_parser.rb +5161 -0
- data/lib/mail/parsers/message_ids_parser.rl +93 -0
- data/lib/mail/parsers/mime_version_parser.rb +513 -0
- data/lib/mail/parsers/mime_version_parser.rl +68 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +884 -0
- data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
- data/lib/mail/parsers/received_parser.rb +8782 -0
- 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/rfc5322_date_time.rl +37 -0
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/lib/mail/parsers.rb +13 -0
- data/lib/mail/part.rb +11 -12
- data/lib/mail/parts_list.rb +90 -14
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +415 -76
- 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 +127 -79
- data/CHANGELOG.rdoc +0 -742
- data/CONTRIBUTING.md +0 -45
- data/Dependencies.txt +0 -3
- data/Gemfile +0 -32
- data/Rakefile +0 -21
- data/TODO.rdoc +0 -9
- data/lib/VERSION +0 -4
- data/lib/load_parsers.rb +0 -35
- 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 -33
- data/lib/mail/fields/common/address_container.rb +0 -16
- data/lib/mail/fields/common/common_address.rb +0 -140
- data/lib/mail/fields/common/common_date.rb +0 -42
- 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/address_lists.rb +0 -64
- data/lib/mail/parsers/address_lists.treetop +0 -19
- data/lib/mail/parsers/content_disposition.rb +0 -535
- data/lib/mail/parsers/content_disposition.treetop +0 -46
- data/lib/mail/parsers/content_location.rb +0 -139
- data/lib/mail/parsers/content_location.treetop +0 -20
- data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
- data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
- data/lib/mail/parsers/content_type.rb +0 -971
- data/lib/mail/parsers/content_type.treetop +0 -68
- data/lib/mail/parsers/date_time.rb +0 -114
- data/lib/mail/parsers/date_time.treetop +0 -11
- data/lib/mail/parsers/envelope_from.rb +0 -194
- data/lib/mail/parsers/envelope_from.treetop +0 -32
- data/lib/mail/parsers/message_ids.rb +0 -45
- data/lib/mail/parsers/message_ids.treetop +0 -15
- data/lib/mail/parsers/mime_version.rb +0 -144
- data/lib/mail/parsers/mime_version.treetop +0 -19
- data/lib/mail/parsers/phrase_lists.rb +0 -45
- data/lib/mail/parsers/phrase_lists.treetop +0 -15
- data/lib/mail/parsers/received.rb +0 -71
- data/lib/mail/parsers/received.treetop +0 -11
- data/lib/mail/parsers/rfc2045.rb +0 -421
- data/lib/mail/parsers/rfc2045.treetop +0 -35
- data/lib/mail/parsers/rfc2822.rb +0 -5397
- data/lib/mail/parsers/rfc2822.treetop +0 -408
- data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
- data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
- data/lib/mail/patterns.rb +0 -35
- data/lib/mail/version_specific/ruby_1_8.rb +0 -119
- data/lib/mail/version_specific/ruby_1_9.rb +0 -147
- data/lib/tasks/corpus.rake +0 -125
- data/lib/tasks/treetop.rake +0 -10
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
|
#
|
@@ -240,7 +261,7 @@ module Mail
|
|
240
261
|
# This method bypasses checking perform_deliveries and raise_delivery_errors,
|
241
262
|
# so use with caution.
|
242
263
|
#
|
243
|
-
# It still however fires off the
|
264
|
+
# It still however fires off the interceptors and calls the observers callbacks if they are defined.
|
244
265
|
#
|
245
266
|
# Returns self
|
246
267
|
def deliver!
|
@@ -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
|
@@ -353,17 +374,18 @@ module Mail
|
|
353
374
|
return false unless other.respond_to?(:encoded)
|
354
375
|
|
355
376
|
if self.message_id && other.message_id
|
356
|
-
|
377
|
+
self.encoded == other.encoded
|
357
378
|
else
|
358
|
-
|
359
|
-
|
360
|
-
result = self.encoded == other.encoded
|
361
|
-
self.message_id = "<#{self_message_id}>" if self_message_id
|
362
|
-
other.message_id = "<#{other_message_id}>" if other_message_id
|
363
|
-
result
|
379
|
+
dup.tap { |m| m.message_id = '<temp@test>' }.encoded ==
|
380
|
+
other.dup.tap { |m| m.message_id = '<temp@test>' }.encoded
|
364
381
|
end
|
365
382
|
end
|
366
383
|
|
384
|
+
def initialize_copy(original)
|
385
|
+
super
|
386
|
+
@header = @header.dup
|
387
|
+
end
|
388
|
+
|
367
389
|
# Provides access to the raw source of the message as it was when it
|
368
390
|
# was instantiated. This is set at initialization and so is untouched
|
369
391
|
# by the parsers or decoder / encoders
|
@@ -377,9 +399,9 @@ module Mail
|
|
377
399
|
end
|
378
400
|
|
379
401
|
# Sets the envelope from for the email
|
380
|
-
def set_envelope(
|
402
|
+
def set_envelope(val)
|
381
403
|
@raw_envelope = val
|
382
|
-
@envelope = Mail::Envelope.
|
404
|
+
@envelope = Mail::Envelope.parse(val) rescue nil
|
383
405
|
end
|
384
406
|
|
385
407
|
# The raw_envelope is the From mikel@test.lindsaar.net Mon May 2 16:07:05 2009
|
@@ -1182,8 +1204,8 @@ module Mail
|
|
1182
1204
|
def default( sym, val = nil )
|
1183
1205
|
if val
|
1184
1206
|
header[sym] = val
|
1185
|
-
|
1186
|
-
|
1207
|
+
elsif field = header[sym]
|
1208
|
+
field.default
|
1187
1209
|
end
|
1188
1210
|
end
|
1189
1211
|
|
@@ -1229,14 +1251,13 @@ module Mail
|
|
1229
1251
|
def body(value = nil)
|
1230
1252
|
if value
|
1231
1253
|
self.body = value
|
1232
|
-
# add_encoding_to_body
|
1233
1254
|
else
|
1234
1255
|
process_body_raw if @body_raw
|
1235
1256
|
@body
|
1236
1257
|
end
|
1237
1258
|
end
|
1238
1259
|
|
1239
|
-
def body_encoding(value)
|
1260
|
+
def body_encoding(value = nil)
|
1240
1261
|
if value.nil?
|
1241
1262
|
body.encoding
|
1242
1263
|
else
|
@@ -1245,7 +1266,7 @@ module Mail
|
|
1245
1266
|
end
|
1246
1267
|
|
1247
1268
|
def body_encoding=(value)
|
1248
|
-
|
1269
|
+
body.encoding = value
|
1249
1270
|
end
|
1250
1271
|
|
1251
1272
|
# Returns the list of addresses this message should be sent to by
|
@@ -1311,7 +1332,7 @@ module Mail
|
|
1311
1332
|
# mail['foo'] = '1234'
|
1312
1333
|
# mail['foo'].to_s #=> '1234'
|
1313
1334
|
def [](name)
|
1314
|
-
header[underscoreize(name)]
|
1335
|
+
header[Utilities.underscoreize(name)]
|
1315
1336
|
end
|
1316
1337
|
|
1317
1338
|
# Method Missing in this implementation allows you to set any of the
|
@@ -1357,7 +1378,7 @@ module Mail
|
|
1357
1378
|
#:nodoc:
|
1358
1379
|
# Only take the structured fields, as we could take _anything_ really
|
1359
1380
|
# as it could become an optional field... "but therin lies the dark side"
|
1360
|
-
field_name = underscoreize(name).chomp("=")
|
1381
|
+
field_name = Utilities.underscoreize(name).chomp("=")
|
1361
1382
|
if Mail::Field::KNOWN_FIELDS.include?(field_name)
|
1362
1383
|
if args.empty?
|
1363
1384
|
header[field_name]
|
@@ -1388,7 +1409,7 @@ module Mail
|
|
1388
1409
|
header.has_date?
|
1389
1410
|
end
|
1390
1411
|
|
1391
|
-
# Returns true if the message has a
|
1412
|
+
# Returns true if the message has a Mime-Version field, the field may or may
|
1392
1413
|
# not have a value, but the field exists or not.
|
1393
1414
|
def has_mime_version?
|
1394
1415
|
header.has_mime_version?
|
@@ -1405,12 +1426,7 @@ module Mail
|
|
1405
1426
|
end
|
1406
1427
|
|
1407
1428
|
def has_content_transfer_encoding?
|
1408
|
-
header[:content_transfer_encoding] && header[:content_transfer_encoding].errors
|
1409
|
-
end
|
1410
|
-
|
1411
|
-
def has_transfer_encoding? # :nodoc:
|
1412
|
-
STDERR.puts(":has_transfer_encoding? is deprecated in Mail 1.4.3. Please use has_content_transfer_encoding?\n#{caller}")
|
1413
|
-
has_content_transfer_encoding?
|
1429
|
+
header[:content_transfer_encoding] && Utilities.blank?(header[:content_transfer_encoding].errors)
|
1414
1430
|
end
|
1415
1431
|
|
1416
1432
|
# Creates a new empty Message-ID field and inserts it in the correct order
|
@@ -1457,35 +1473,19 @@ module Mail
|
|
1457
1473
|
if !body.empty?
|
1458
1474
|
# Only give a warning if this isn't an attachment, has non US-ASCII and the user
|
1459
1475
|
# has not specified an encoding explicitly.
|
1460
|
-
if @defaulted_charset && body.raw_source.
|
1476
|
+
if @defaulted_charset && !body.raw_source.ascii_only? && !self.attachment?
|
1461
1477
|
warning = "Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.\n"
|
1462
|
-
|
1478
|
+
warn(warning)
|
1479
|
+
end
|
1480
|
+
if @charset
|
1481
|
+
header[:content_type].parameters['charset'] = @charset
|
1463
1482
|
end
|
1464
|
-
header[:content_type].parameters['charset'] = @charset
|
1465
1483
|
end
|
1466
1484
|
end
|
1467
1485
|
|
1468
1486
|
# Adds a content transfer encoding
|
1469
|
-
#
|
1470
|
-
# Otherwise raises a warning
|
1471
1487
|
def add_content_transfer_encoding
|
1472
|
-
|
1473
|
-
header[:content_transfer_encoding] = '7bit'
|
1474
|
-
else
|
1475
|
-
warning = "Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect.\n"
|
1476
|
-
STDERR.puts(warning)
|
1477
|
-
header[:content_transfer_encoding] = '8bit'
|
1478
|
-
end
|
1479
|
-
end
|
1480
|
-
|
1481
|
-
def add_transfer_encoding # :nodoc:
|
1482
|
-
STDERR.puts(":add_transfer_encoding is deprecated in Mail 1.4.3. Please use add_content_transfer_encoding\n#{caller}")
|
1483
|
-
add_content_transfer_encoding
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
def transfer_encoding # :nodoc:
|
1487
|
-
STDERR.puts(":transfer_encoding is deprecated in Mail 1.4.3. Please use content_transfer_encoding\n#{caller}")
|
1488
|
-
content_transfer_encoding
|
1488
|
+
header[:content_transfer_encoding] ||= body.default_encoding
|
1489
1489
|
end
|
1490
1490
|
|
1491
1491
|
# Returns the MIME media type of part we are on, this is taken from the content-type header
|
@@ -1493,15 +1493,10 @@ module Mail
|
|
1493
1493
|
has_content_type? ? header[:content_type].string : nil rescue nil
|
1494
1494
|
end
|
1495
1495
|
|
1496
|
-
def message_content_type
|
1497
|
-
STDERR.puts(":message_content_type is deprecated in Mail 1.4.3. Please use mime_type\n#{caller}")
|
1498
|
-
mime_type
|
1499
|
-
end
|
1500
|
-
|
1501
1496
|
# Returns the character set defined in the content type field
|
1502
1497
|
def charset
|
1503
1498
|
if @header
|
1504
|
-
has_content_type? ? content_type_parameters['charset'] : @charset
|
1499
|
+
has_content_type? && !multipart? ? content_type_parameters['charset'] : @charset
|
1505
1500
|
else
|
1506
1501
|
@charset
|
1507
1502
|
end
|
@@ -1524,12 +1519,6 @@ module Mail
|
|
1524
1519
|
has_content_type? ? header[:content_type].sub_type : nil rescue nil
|
1525
1520
|
end
|
1526
1521
|
|
1527
|
-
# Returns the content type parameters
|
1528
|
-
def mime_parameters
|
1529
|
-
STDERR.puts(':mime_parameters is deprecated in Mail 1.4.3, please use :content_type_parameters instead')
|
1530
|
-
content_type_parameters
|
1531
|
-
end
|
1532
|
-
|
1533
1522
|
# Returns the content type parameters
|
1534
1523
|
def content_type_parameters
|
1535
1524
|
has_content_type? ? header[:content_type].parameters : nil rescue nil
|
@@ -1552,7 +1541,14 @@ module Mail
|
|
1552
1541
|
|
1553
1542
|
# returns the part in a multipart/report email that has the content-type delivery-status
|
1554
1543
|
def delivery_status_part
|
1555
|
-
|
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
|
1556
1552
|
end
|
1557
1553
|
|
1558
1554
|
def bounced?
|
@@ -1594,7 +1590,7 @@ module Mail
|
|
1594
1590
|
end
|
1595
1591
|
|
1596
1592
|
# Returns an AttachmentsList object, which holds all of the attachments in
|
1597
|
-
# the receiver object (either the
|
1593
|
+
# the receiver object (either the entire email or a part within) and all
|
1598
1594
|
# of its descendants.
|
1599
1595
|
#
|
1600
1596
|
# It also allows you to add attachments to the mail object directly, like so:
|
@@ -1659,6 +1655,8 @@ module Mail
|
|
1659
1655
|
def html_part=(msg)
|
1660
1656
|
# Assign the html part and set multipart/alternative if there's a text part.
|
1661
1657
|
if msg
|
1658
|
+
msg = Mail::Part.new(:body => msg) unless msg.kind_of?(Mail::Message)
|
1659
|
+
|
1662
1660
|
@html_part = msg
|
1663
1661
|
@html_part.content_type = 'text/html' unless @html_part.has_content_type?
|
1664
1662
|
add_multipart_alternate_header if text_part
|
@@ -1681,6 +1679,8 @@ module Mail
|
|
1681
1679
|
def text_part=(msg)
|
1682
1680
|
# Assign the text part and set multipart/alternative if there's an html part.
|
1683
1681
|
if msg
|
1682
|
+
msg = Mail::Part.new(:body => msg) unless msg.kind_of?(Mail::Message)
|
1683
|
+
|
1684
1684
|
@text_part = msg
|
1685
1685
|
@text_part.content_type = 'text/plain' unless @text_part.has_content_type?
|
1686
1686
|
add_multipart_alternate_header if html_part
|
@@ -1699,7 +1699,7 @@ module Mail
|
|
1699
1699
|
|
1700
1700
|
# Adds a part to the parts list or creates the part list
|
1701
1701
|
def add_part(part)
|
1702
|
-
if !body.multipart? && !self.body.decoded
|
1702
|
+
if !body.multipart? && !Utilities.blank?(self.body.decoded)
|
1703
1703
|
@text_part = Mail::Part.new('Content-Type: text/plain;')
|
1704
1704
|
@text_part.body = body.decoded
|
1705
1705
|
self.body << @text_part
|
@@ -1755,24 +1755,34 @@ module Mail
|
|
1755
1755
|
#
|
1756
1756
|
# See also #attachments
|
1757
1757
|
def add_file(values)
|
1758
|
-
convert_to_multipart unless self.multipart? || self.body.decoded
|
1758
|
+
convert_to_multipart unless self.multipart? || Utilities.blank?(self.body.decoded)
|
1759
1759
|
add_multipart_mixed_header
|
1760
1760
|
if values.is_a?(String)
|
1761
1761
|
basename = File.basename(values)
|
1762
1762
|
filedata = File.open(values, 'rb') { |f| f.read }
|
1763
1763
|
else
|
1764
1764
|
basename = values[:filename]
|
1765
|
-
filedata = values
|
1765
|
+
filedata = values
|
1766
1766
|
end
|
1767
1767
|
self.attachments[basename] = filedata
|
1768
1768
|
end
|
1769
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
|
+
|
1770
1773
|
def convert_to_multipart
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
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
|
1775
1783
|
text_part.charset = charset unless @defaulted_charset
|
1784
|
+
|
1785
|
+
self.body = ''
|
1776
1786
|
self.body << text_part
|
1777
1787
|
end
|
1778
1788
|
|
@@ -1780,7 +1790,6 @@ module Mail
|
|
1780
1790
|
# ready to send
|
1781
1791
|
def ready_to_send!
|
1782
1792
|
identify_and_set_transfer_encoding
|
1783
|
-
parts.sort!([ "text/plain", "text/enriched", "text/html", "multipart/alternative" ])
|
1784
1793
|
parts.each do |part|
|
1785
1794
|
part.transport_encoding = transport_encoding
|
1786
1795
|
part.ready_to_send!
|
@@ -1788,11 +1797,6 @@ module Mail
|
|
1788
1797
|
add_required_fields
|
1789
1798
|
end
|
1790
1799
|
|
1791
|
-
def encode!
|
1792
|
-
STDERR.puts("Deprecated in 1.1.0 in favour of :ready_to_send! as it is less confusing with encoding and decoding.")
|
1793
|
-
ready_to_send!
|
1794
|
-
end
|
1795
|
-
|
1796
1800
|
# Outputs an encoded string representation of the mail message including
|
1797
1801
|
# all headers, attachments, etc. This is an encoded email in US-ASCII,
|
1798
1802
|
# so it is able to be directly sent to an email server.
|
@@ -1805,16 +1809,13 @@ module Mail
|
|
1805
1809
|
end
|
1806
1810
|
|
1807
1811
|
def without_attachments!
|
1808
|
-
|
1812
|
+
if has_attachments?
|
1813
|
+
parts.delete_attachments
|
1809
1814
|
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
body.encoded
|
1815
|
-
end
|
1816
|
-
|
1817
|
-
@body = Mail::Body.new(body_raw)
|
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
|
1818
1819
|
|
1819
1820
|
self
|
1820
1821
|
end
|
@@ -1840,14 +1841,14 @@ module Mail
|
|
1840
1841
|
end
|
1841
1842
|
|
1842
1843
|
def self.from_yaml(str)
|
1843
|
-
hash = YAML.load(str)
|
1844
|
+
hash = Mail::YAML.load(str)
|
1844
1845
|
m = self.new(:headers => hash['headers'])
|
1845
1846
|
hash.delete('headers')
|
1846
1847
|
hash.each do |k,v|
|
1847
1848
|
case
|
1848
1849
|
when k == 'delivery_handler'
|
1849
1850
|
begin
|
1850
|
-
m.delivery_handler = Object.const_get(v) unless
|
1851
|
+
m.delivery_handler = Object.const_get(v) unless Utilities.blank?(v)
|
1851
1852
|
rescue NameError
|
1852
1853
|
end
|
1853
1854
|
when k == 'transport_encoding'
|
@@ -1873,6 +1874,15 @@ module Mail
|
|
1873
1874
|
"#<#{self.class}:#{self.object_id}, Multipart: #{multipart?}, Headers: #{header.field_summary}>"
|
1874
1875
|
end
|
1875
1876
|
|
1877
|
+
def inspect_structure
|
1878
|
+
inspect +
|
1879
|
+
if self.multipart?
|
1880
|
+
"\n" + parts.inspect_structure
|
1881
|
+
else
|
1882
|
+
''
|
1883
|
+
end
|
1884
|
+
end
|
1885
|
+
|
1876
1886
|
def decoded
|
1877
1887
|
case
|
1878
1888
|
when self.text?
|
@@ -1957,6 +1967,8 @@ module Mail
|
|
1957
1967
|
|
1958
1968
|
private
|
1959
1969
|
|
1970
|
+
HEADER_SEPARATOR = /#{Constants::LAX_CRLF}#{Constants::LAX_CRLF}/
|
1971
|
+
|
1960
1972
|
# 2.1. General Description
|
1961
1973
|
# A message consists of header fields (collectively called "the header
|
1962
1974
|
# of the message") followed, optionally, by a body. The header is a
|
@@ -1964,18 +1976,14 @@ module Mail
|
|
1964
1976
|
# this standard. The body is simply a sequence of characters that
|
1965
1977
|
# follows the header and is separated from the header by an empty line
|
1966
1978
|
# (i.e., a line with nothing preceding the CRLF).
|
1967
|
-
#
|
1968
|
-
# Additionally, I allow for the case where someone might have put whitespace
|
1969
|
-
# on the "gap line"
|
1970
1979
|
def parse_message
|
1971
|
-
header_part, body_part = raw_source.lstrip.split(
|
1980
|
+
header_part, body_part = raw_source.lstrip.split(HEADER_SEPARATOR, 2)
|
1972
1981
|
self.header = header_part
|
1973
1982
|
self.body = body_part
|
1974
1983
|
end
|
1975
1984
|
|
1976
1985
|
def raw_source=(value)
|
1977
|
-
|
1978
|
-
@raw_source = value.to_crlf
|
1986
|
+
@raw_source = value
|
1979
1987
|
end
|
1980
1988
|
|
1981
1989
|
# see comments to body=. We take data and process it lazily
|
@@ -1987,11 +1995,9 @@ module Mail
|
|
1987
1995
|
@body_raw = nil
|
1988
1996
|
add_encoding_to_body
|
1989
1997
|
when @body && @body.multipart?
|
1990
|
-
|
1991
|
-
add_encoding_to_body
|
1998
|
+
self.text_part = value
|
1992
1999
|
else
|
1993
2000
|
@body_raw = value
|
1994
|
-
# process_body_raw
|
1995
2001
|
end
|
1996
2002
|
end
|
1997
2003
|
|
@@ -2006,9 +2012,9 @@ module Mail
|
|
2006
2012
|
|
2007
2013
|
def set_envelope_header
|
2008
2014
|
raw_string = raw_source.to_s
|
2009
|
-
if match_data =
|
2015
|
+
if match_data = raw_string.match(/\AFrom\s+([^:\s]#{Constants::TEXT}*)#{Constants::LAX_CRLF}/m)
|
2010
2016
|
set_envelope(match_data[1])
|
2011
|
-
self.raw_source = raw_string.sub(match_data[0], "")
|
2017
|
+
self.raw_source = raw_string.sub(match_data[0], "")
|
2012
2018
|
end
|
2013
2019
|
end
|
2014
2020
|
|
@@ -2016,6 +2022,13 @@ module Mail
|
|
2016
2022
|
body.split!(boundary)
|
2017
2023
|
end
|
2018
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
|
+
|
2019
2032
|
def add_encoding_to_body
|
2020
2033
|
if has_content_transfer_encoding?
|
2021
2034
|
@body.encoding = content_transfer_encoding
|
@@ -2023,18 +2036,20 @@ module Mail
|
|
2023
2036
|
end
|
2024
2037
|
|
2025
2038
|
def identify_and_set_transfer_encoding
|
2026
|
-
|
2027
|
-
|
2039
|
+
if body
|
2040
|
+
if body.multipart?
|
2041
|
+
self.content_transfer_encoding = @transport_encoding
|
2028
2042
|
else
|
2029
|
-
|
2043
|
+
self.content_transfer_encoding = body.negotiate_best_encoding(@transport_encoding, allowed_encodings).to_s
|
2030
2044
|
end
|
2045
|
+
end
|
2031
2046
|
end
|
2032
2047
|
|
2033
2048
|
def add_required_fields
|
2034
2049
|
add_required_message_fields
|
2035
2050
|
add_multipart_mixed_header if body.multipart?
|
2036
2051
|
add_content_type unless has_content_type?
|
2037
|
-
add_charset
|
2052
|
+
add_charset if text? && !has_charset?
|
2038
2053
|
add_content_transfer_encoding unless has_content_transfer_encoding?
|
2039
2054
|
end
|
2040
2055
|
|
@@ -2046,15 +2061,17 @@ module Mail
|
|
2046
2061
|
|
2047
2062
|
def add_multipart_alternate_header
|
2048
2063
|
header['content-type'] = ContentTypeField.with_boundary('multipart/alternative').value
|
2049
|
-
header['content_type'].parameters[:charset] = @charset
|
2050
2064
|
body.boundary = boundary
|
2051
2065
|
end
|
2052
2066
|
|
2053
2067
|
def add_boundary
|
2054
2068
|
unless body.boundary && boundary
|
2055
|
-
|
2069
|
+
unless header['content-type']
|
2070
|
+
_charset = charset
|
2071
|
+
header['content-type'] = 'multipart/mixed'
|
2072
|
+
header['content-type'].parameters[:charset] = _charset
|
2073
|
+
end
|
2056
2074
|
header['content-type'].parameters[:boundary] = ContentTypeField.generate_boundary
|
2057
|
-
header['content_type'].parameters[:charset] = @charset
|
2058
2075
|
body.boundary = boundary
|
2059
2076
|
end
|
2060
2077
|
end
|
@@ -2062,7 +2079,6 @@ module Mail
|
|
2062
2079
|
def add_multipart_mixed_header
|
2063
2080
|
unless header['content-type']
|
2064
2081
|
header['content-type'] = ContentTypeField.with_boundary('multipart/mixed').value
|
2065
|
-
header['content_type'].parameters[:charset] = @charset
|
2066
2082
|
body.boundary = boundary
|
2067
2083
|
end
|
2068
2084
|
end
|
@@ -2079,7 +2095,7 @@ module Mail
|
|
2079
2095
|
body_content = nil
|
2080
2096
|
|
2081
2097
|
passed_in_options.each_pair do |k,v|
|
2082
|
-
k = underscoreize(k).to_sym if k.class == String
|
2098
|
+
k = Utilities.underscoreize(k).to_sym if k.class == String
|
2083
2099
|
if k == :headers
|
2084
2100
|
self.headers(v)
|
2085
2101
|
elsif k == :body
|
@@ -2110,10 +2126,10 @@ module Mail
|
|
2110
2126
|
content_disp_name = header[:content_disposition].filename rescue nil
|
2111
2127
|
content_loc_name = header[:content_location].location rescue nil
|
2112
2128
|
case
|
2113
|
-
when content_type && content_type_name
|
2114
|
-
filename = content_type_name
|
2115
2129
|
when content_disposition && content_disp_name
|
2116
2130
|
filename = content_disp_name
|
2131
|
+
when content_type && content_type_name
|
2132
|
+
filename = content_type_name
|
2117
2133
|
when content_location && content_loc_name
|
2118
2134
|
filename = content_loc_name
|
2119
2135
|
else
|
@@ -2128,26 +2144,13 @@ module Mail
|
|
2128
2144
|
if perform_deliveries
|
2129
2145
|
delivery_method.deliver!(self)
|
2130
2146
|
end
|
2131
|
-
rescue
|
2147
|
+
rescue => e # Net::SMTP errors or sendmail pipe errors
|
2132
2148
|
raise e if raise_delivery_errors
|
2133
2149
|
end
|
2134
2150
|
end
|
2135
2151
|
|
2136
2152
|
def decode_body_as_text
|
2137
|
-
|
2138
|
-
if charset
|
2139
|
-
if RUBY_VERSION < '1.9'
|
2140
|
-
require 'iconv'
|
2141
|
-
return Iconv.conv("UTF-8//TRANSLIT//IGNORE", charset, body_text)
|
2142
|
-
else
|
2143
|
-
if encoding = Encoding.find(charset) rescue nil
|
2144
|
-
body_text.force_encoding(encoding)
|
2145
|
-
return body_text.encode(Encoding::UTF_8, :undef => :replace, :invalid => :replace, :replace => '')
|
2146
|
-
end
|
2147
|
-
end
|
2148
|
-
end
|
2149
|
-
body_text
|
2153
|
+
Encodings.transcode_charset decode_body, charset, 'UTF-8'
|
2150
2154
|
end
|
2151
|
-
|
2152
2155
|
end
|
2153
2156
|
end
|