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
data/lib/mail/message.rb
CHANGED
@@ -56,15 +56,23 @@ module Mail
|
|
56
56
|
#
|
57
57
|
# ===Making an email via a block
|
58
58
|
#
|
59
|
-
# mail = Mail.new do
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# subject 'This is a test email'
|
63
|
-
#
|
59
|
+
# mail = Mail.new do |m|
|
60
|
+
# m.from 'mikel@test.lindsaar.net'
|
61
|
+
# m.to 'you@test.lindsaar.net'
|
62
|
+
# m.subject 'This is a test email'
|
63
|
+
# m.body File.read('body.txt')
|
64
64
|
# end
|
65
65
|
#
|
66
66
|
# mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
|
67
67
|
#
|
68
|
+
# If may also pass a block with no arguments, in which case it will
|
69
|
+
# be evaluated in the scope of the new message instance:
|
70
|
+
#
|
71
|
+
# mail = Mail.new do
|
72
|
+
# from 'mikel@test.lindsaar.net'
|
73
|
+
# # …
|
74
|
+
# end
|
75
|
+
#
|
68
76
|
# ===Making an email via passing a string
|
69
77
|
#
|
70
78
|
# mail = Mail.new("To: mikel@test.lindsaar.net\r\nSubject: Hello\r\n\r\nHi there!")
|
@@ -129,8 +137,23 @@ module Mail
|
|
129
137
|
init_with_string(args.flatten[0].to_s)
|
130
138
|
end
|
131
139
|
|
140
|
+
# Support both builder styles:
|
141
|
+
#
|
142
|
+
# Mail.new do
|
143
|
+
# to 'recipient@example.com'
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# and
|
147
|
+
#
|
148
|
+
# Mail.new do |m|
|
149
|
+
# m.to 'recipient@example.com'
|
150
|
+
# end
|
132
151
|
if block_given?
|
133
|
-
|
152
|
+
if block.arity.zero? || (RUBY_VERSION < '1.9' && block.arity < 1)
|
153
|
+
instance_eval(&block)
|
154
|
+
else
|
155
|
+
yield self
|
156
|
+
end
|
134
157
|
end
|
135
158
|
|
136
159
|
self
|
@@ -213,7 +236,7 @@ module Mail
|
|
213
236
|
self.default_charset = 'UTF-8'
|
214
237
|
|
215
238
|
def register_for_delivery_notification(observer)
|
216
|
-
|
239
|
+
warn("Message#register_for_delivery_notification is deprecated, please call Mail.register_observer instead")
|
217
240
|
Mail.register_observer(observer)
|
218
241
|
end
|
219
242
|
|
@@ -225,7 +248,7 @@ module Mail
|
|
225
248
|
Mail.inform_interceptors(self)
|
226
249
|
end
|
227
250
|
|
228
|
-
# Delivers
|
251
|
+
# Delivers a mail object.
|
229
252
|
#
|
230
253
|
# Examples:
|
231
254
|
#
|
@@ -1188,8 +1211,8 @@ module Mail
|
|
1188
1211
|
def default( sym, val = nil )
|
1189
1212
|
if val
|
1190
1213
|
header[sym] = val
|
1191
|
-
|
1192
|
-
|
1214
|
+
elsif field = header[sym]
|
1215
|
+
field.default
|
1193
1216
|
end
|
1194
1217
|
end
|
1195
1218
|
|
@@ -1235,14 +1258,13 @@ module Mail
|
|
1235
1258
|
def body(value = nil)
|
1236
1259
|
if value
|
1237
1260
|
self.body = value
|
1238
|
-
# add_encoding_to_body
|
1239
1261
|
else
|
1240
1262
|
process_body_raw if @body_raw
|
1241
1263
|
@body
|
1242
1264
|
end
|
1243
1265
|
end
|
1244
1266
|
|
1245
|
-
def body_encoding(value)
|
1267
|
+
def body_encoding(value = nil)
|
1246
1268
|
if value.nil?
|
1247
1269
|
body.encoding
|
1248
1270
|
else
|
@@ -1251,7 +1273,7 @@ module Mail
|
|
1251
1273
|
end
|
1252
1274
|
|
1253
1275
|
def body_encoding=(value)
|
1254
|
-
|
1276
|
+
body.encoding = value
|
1255
1277
|
end
|
1256
1278
|
|
1257
1279
|
# Returns the list of addresses this message should be sent to by
|
@@ -1415,7 +1437,7 @@ module Mail
|
|
1415
1437
|
end
|
1416
1438
|
|
1417
1439
|
def has_transfer_encoding? # :nodoc:
|
1418
|
-
|
1440
|
+
warn(":has_transfer_encoding? is deprecated in Mail 1.4.3. Please use has_content_transfer_encoding?\n#{caller}")
|
1419
1441
|
has_content_transfer_encoding?
|
1420
1442
|
end
|
1421
1443
|
|
@@ -1465,32 +1487,24 @@ module Mail
|
|
1465
1487
|
# has not specified an encoding explicitly.
|
1466
1488
|
if @defaulted_charset && !body.raw_source.ascii_only? && !self.attachment?
|
1467
1489
|
warning = "Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.\n"
|
1468
|
-
|
1490
|
+
warn(warning)
|
1469
1491
|
end
|
1470
1492
|
header[:content_type].parameters['charset'] = @charset
|
1471
1493
|
end
|
1472
1494
|
end
|
1473
1495
|
|
1474
1496
|
# Adds a content transfer encoding
|
1475
|
-
#
|
1476
|
-
# Otherwise raises a warning
|
1477
1497
|
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
|
1498
|
+
header[:content_transfer_encoding] ||= body.default_encoding
|
1485
1499
|
end
|
1486
1500
|
|
1487
1501
|
def add_transfer_encoding # :nodoc:
|
1488
|
-
|
1502
|
+
warn(":add_transfer_encoding is deprecated in Mail 1.4.3. Please use add_content_transfer_encoding\n#{caller}")
|
1489
1503
|
add_content_transfer_encoding
|
1490
1504
|
end
|
1491
1505
|
|
1492
1506
|
def transfer_encoding # :nodoc:
|
1493
|
-
|
1507
|
+
warn(":transfer_encoding is deprecated in Mail 1.4.3. Please use content_transfer_encoding\n#{caller}")
|
1494
1508
|
content_transfer_encoding
|
1495
1509
|
end
|
1496
1510
|
|
@@ -1500,7 +1514,7 @@ module Mail
|
|
1500
1514
|
end
|
1501
1515
|
|
1502
1516
|
def message_content_type
|
1503
|
-
|
1517
|
+
warn(":message_content_type is deprecated in Mail 1.4.3. Please use mime_type\n#{caller}")
|
1504
1518
|
mime_type
|
1505
1519
|
end
|
1506
1520
|
|
@@ -1532,7 +1546,7 @@ module Mail
|
|
1532
1546
|
|
1533
1547
|
# Returns the content type parameters
|
1534
1548
|
def mime_parameters
|
1535
|
-
|
1549
|
+
warn(':mime_parameters is deprecated in Mail 1.4.3, please use :content_type_parameters instead')
|
1536
1550
|
content_type_parameters
|
1537
1551
|
end
|
1538
1552
|
|
@@ -1780,9 +1794,6 @@ module Mail
|
|
1780
1794
|
else
|
1781
1795
|
basename = values[:filename]
|
1782
1796
|
filedata = values
|
1783
|
-
unless filedata[:content]
|
1784
|
-
filedata = values.merge(:content=>File.open(values[:filename], 'rb') { |f| f.read })
|
1785
|
-
end
|
1786
1797
|
end
|
1787
1798
|
self.attachments[basename] = filedata
|
1788
1799
|
end
|
@@ -1808,7 +1819,7 @@ module Mail
|
|
1808
1819
|
end
|
1809
1820
|
|
1810
1821
|
def encode!
|
1811
|
-
|
1822
|
+
warn("Deprecated in 1.1.0 in favour of :ready_to_send! as it is less confusing with encoding and decoding.")
|
1812
1823
|
ready_to_send!
|
1813
1824
|
end
|
1814
1825
|
|
@@ -1824,16 +1835,13 @@ module Mail
|
|
1824
1835
|
end
|
1825
1836
|
|
1826
1837
|
def without_attachments!
|
1827
|
-
|
1828
|
-
|
1829
|
-
parts.delete_if { |p| p.attachment? }
|
1830
|
-
body_raw = if parts.empty?
|
1831
|
-
''
|
1832
|
-
else
|
1833
|
-
body.encoded
|
1834
|
-
end
|
1838
|
+
if has_attachments?
|
1839
|
+
parts.delete_if { |p| p.attachment? }
|
1835
1840
|
|
1836
|
-
|
1841
|
+
reencoded = parts.empty? ? '' : body.encoded(content_transfer_encoding)
|
1842
|
+
@body = nil # So the new parts won't be added to the existing body
|
1843
|
+
self.body = reencoded
|
1844
|
+
end
|
1837
1845
|
|
1838
1846
|
self
|
1839
1847
|
end
|
@@ -1993,7 +2001,7 @@ module Mail
|
|
1993
2001
|
|
1994
2002
|
def raw_source=(value)
|
1995
2003
|
value = value.dup.force_encoding(Encoding::BINARY) if RUBY_VERSION >= "1.9.1"
|
1996
|
-
@raw_source =
|
2004
|
+
@raw_source = value
|
1997
2005
|
end
|
1998
2006
|
|
1999
2007
|
# see comments to body=. We take data and process it lazily
|
@@ -2005,11 +2013,9 @@ module Mail
|
|
2005
2013
|
@body_raw = nil
|
2006
2014
|
add_encoding_to_body
|
2007
2015
|
when @body && @body.multipart?
|
2008
|
-
|
2009
|
-
add_encoding_to_body
|
2016
|
+
self.text_part = value
|
2010
2017
|
else
|
2011
2018
|
@body_raw = value
|
2012
|
-
# process_body_raw
|
2013
2019
|
end
|
2014
2020
|
end
|
2015
2021
|
|
@@ -2024,7 +2030,7 @@ module Mail
|
|
2024
2030
|
|
2025
2031
|
def set_envelope_header
|
2026
2032
|
raw_string = raw_source.to_s
|
2027
|
-
if match_data =
|
2033
|
+
if match_data = raw_string.match(/\AFrom\s(#{TEXT}+)#{CRLF}/m)
|
2028
2034
|
set_envelope(match_data[1])
|
2029
2035
|
self.raw_source = raw_string.sub(match_data[0], "")
|
2030
2036
|
end
|
@@ -2034,6 +2040,13 @@ module Mail
|
|
2034
2040
|
body.split!(boundary)
|
2035
2041
|
end
|
2036
2042
|
|
2043
|
+
def allowed_encodings
|
2044
|
+
case mime_type
|
2045
|
+
when 'message/rfc822'
|
2046
|
+
[Encodings::SevenBit, Encodings::EightBit, Encodings::Binary]
|
2047
|
+
end
|
2048
|
+
end
|
2049
|
+
|
2037
2050
|
def add_encoding_to_body
|
2038
2051
|
if has_content_transfer_encoding?
|
2039
2052
|
@body.encoding = content_transfer_encoding
|
@@ -2041,11 +2054,11 @@ module Mail
|
|
2041
2054
|
end
|
2042
2055
|
|
2043
2056
|
def identify_and_set_transfer_encoding
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2057
|
+
if body && body.multipart?
|
2058
|
+
self.content_transfer_encoding = @transport_encoding
|
2059
|
+
else
|
2060
|
+
self.content_transfer_encoding = body.negotiate_best_encoding(@transport_encoding, allowed_encodings).to_s
|
2061
|
+
end
|
2049
2062
|
end
|
2050
2063
|
|
2051
2064
|
def add_required_fields
|
data/lib/mail/multibyte.rb
CHANGED
@@ -1,25 +1,23 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
|
+
require 'mail/multibyte/chars'
|
4
|
+
|
3
5
|
module Mail #:nodoc:
|
4
6
|
module Multibyte
|
5
|
-
|
6
|
-
|
7
|
-
require 'mail/multibyte/unicode'
|
7
|
+
# Raised when a problem with the encoding was found.
|
8
|
+
class EncodingError < StandardError; end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
class << self
|
11
|
+
# The proxy class returned when calling mb_chars. You can use this accessor to configure your own proxy
|
12
|
+
# class so you can support other encodings. See the Mail::Multibyte::Chars implementation for
|
13
|
+
# an example how to do this.
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
# Mail::Multibyte.proxy_class = CharsForUTF32
|
17
|
+
attr_accessor :proxy_class
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
def self.proxy_class
|
21
|
-
@proxy_class ||= Mail::Multibyte::Chars
|
22
|
-
end
|
20
|
+
self.proxy_class = Mail::Multibyte::Chars
|
23
21
|
|
24
22
|
if RUBY_VERSION >= "1.9"
|
25
23
|
# == Multibyte proxy
|
@@ -91,4 +89,4 @@ module Mail #:nodoc:
|
|
91
89
|
end
|
92
90
|
end
|
93
91
|
|
94
|
-
require 'mail/multibyte/utils'
|
92
|
+
require 'mail/multibyte/utils'
|
data/lib/mail/multibyte/chars.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
|
+
require 'mail/multibyte/unicode'
|
3
4
|
|
4
5
|
module Mail #:nodoc:
|
5
6
|
module Multibyte #:nodoc:
|
@@ -40,7 +41,7 @@ module Mail #:nodoc:
|
|
40
41
|
if RUBY_VERSION >= "1.9"
|
41
42
|
# Creates a new Chars instance by wrapping _string_.
|
42
43
|
def initialize(string)
|
43
|
-
@wrapped_string = string
|
44
|
+
@wrapped_string = string.dup
|
44
45
|
@wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
|
45
46
|
end
|
46
47
|
else
|
data/lib/mail/network.rb
CHANGED
@@ -4,6 +4,7 @@ require 'mail/network/retriever_methods/base'
|
|
4
4
|
module Mail
|
5
5
|
register_autoload :SMTP, 'mail/network/delivery_methods/smtp'
|
6
6
|
register_autoload :FileDelivery, 'mail/network/delivery_methods/file_delivery'
|
7
|
+
register_autoload :LoggerDelivery, 'mail/network/delivery_methods/logger_delivery'
|
7
8
|
register_autoload :Sendmail, 'mail/network/delivery_methods/sendmail'
|
8
9
|
register_autoload :Exim, 'mail/network/delivery_methods/exim'
|
9
10
|
register_autoload :SMTPConnection, 'mail/network/delivery_methods/smtp_connection'
|
@@ -37,17 +37,13 @@ module Mail
|
|
37
37
|
#
|
38
38
|
# mail.deliver!
|
39
39
|
class Exim < Sendmail
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
DEFAULTS = {
|
41
|
+
:location => '/usr/sbin/exim',
|
42
|
+
:arguments => '-i -t'
|
43
|
+
}
|
44
44
|
|
45
|
-
def self.call(path, arguments, destinations,
|
46
|
-
|
47
|
-
io.puts ::Mail::Utilities.to_lf(mail.encoded)
|
48
|
-
io.flush
|
49
|
-
end
|
45
|
+
def self.call(path, arguments, destinations, encoded_message)
|
46
|
+
super path, arguments, nil, encoded_message
|
50
47
|
end
|
51
|
-
|
52
48
|
end
|
53
49
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'mail/check_delivery_params'
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
class LoggerDelivery
|
5
|
+
include Mail::CheckDeliveryParams
|
6
|
+
|
7
|
+
attr_reader :logger, :severity, :settings
|
8
|
+
|
9
|
+
def initialize(settings)
|
10
|
+
@settings = settings
|
11
|
+
@logger = settings.fetch(:logger) { default_logger }
|
12
|
+
@severity = derive_severity(settings[:severity])
|
13
|
+
end
|
14
|
+
|
15
|
+
def deliver!(mail)
|
16
|
+
Mail::CheckDeliveryParams.check(mail)
|
17
|
+
logger.log(severity) { mail.encoded }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def default_logger
|
22
|
+
require 'logger'
|
23
|
+
::Logger.new($stdout)
|
24
|
+
end
|
25
|
+
|
26
|
+
def derive_severity(severity)
|
27
|
+
case severity
|
28
|
+
when nil
|
29
|
+
Logger::INFO
|
30
|
+
when Integer
|
31
|
+
severity
|
32
|
+
else
|
33
|
+
Logger.const_get(severity.to_s.upcase)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -38,17 +38,21 @@ module Mail
|
|
38
38
|
#
|
39
39
|
# mail.deliver!
|
40
40
|
class Sendmail
|
41
|
+
DEFAULTS = {
|
42
|
+
:location => '/usr/sbin/sendmail',
|
43
|
+
:arguments => '-i'
|
44
|
+
}
|
45
|
+
|
41
46
|
attr_accessor :settings
|
42
47
|
|
43
48
|
def initialize(values)
|
44
|
-
self.settings =
|
45
|
-
:arguments => '-i' }.merge(values)
|
49
|
+
self.settings = self.class::DEFAULTS.merge(values)
|
46
50
|
end
|
47
51
|
|
48
52
|
def deliver!(mail)
|
49
53
|
smtp_from, smtp_to, message = Mail::CheckDeliveryParams.check(mail)
|
50
54
|
|
51
|
-
from = "-f #{self.class.shellquote(smtp_from)}"
|
55
|
+
from = "-f #{self.class.shellquote(smtp_from)}" if smtp_from
|
52
56
|
to = smtp_to.map { |_to| self.class.shellquote(_to) }.join(' ')
|
53
57
|
|
54
58
|
arguments = "#{settings[:arguments]} #{from} --"
|
@@ -57,7 +61,7 @@ module Mail
|
|
57
61
|
|
58
62
|
def self.call(path, arguments, destinations, encoded_message)
|
59
63
|
popen "#{path} #{arguments} #{destinations}" do |io|
|
60
|
-
io.puts ::Mail::Utilities.
|
64
|
+
io.puts ::Mail::Utilities.binary_unsafe_to_lf(encoded_message)
|
61
65
|
io.flush
|
62
66
|
end
|
63
67
|
end
|
@@ -76,73 +76,74 @@ module Mail
|
|
76
76
|
class SMTP
|
77
77
|
attr_accessor :settings
|
78
78
|
|
79
|
+
DEFAULTS = {
|
80
|
+
:address => 'localhost',
|
81
|
+
:port => 25,
|
82
|
+
:domain => 'localhost.localdomain',
|
83
|
+
:user_name => nil,
|
84
|
+
:password => nil,
|
85
|
+
:authentication => nil,
|
86
|
+
:enable_starttls => nil,
|
87
|
+
:enable_starttls_auto => true,
|
88
|
+
:openssl_verify_mode => nil,
|
89
|
+
:ssl => nil,
|
90
|
+
:tls => nil,
|
91
|
+
:open_timeout => nil,
|
92
|
+
:read_timeout => nil
|
93
|
+
}
|
94
|
+
|
79
95
|
def initialize(values)
|
80
|
-
self.settings =
|
81
|
-
:port => 25,
|
82
|
-
:domain => 'localhost.localdomain',
|
83
|
-
:user_name => nil,
|
84
|
-
:password => nil,
|
85
|
-
:authentication => nil,
|
86
|
-
:enable_starttls => nil,
|
87
|
-
:enable_starttls_auto => true,
|
88
|
-
:openssl_verify_mode => nil,
|
89
|
-
:ssl => nil,
|
90
|
-
:tls => nil,
|
91
|
-
:open_timeout => nil,
|
92
|
-
:read_timeout => nil
|
93
|
-
}.merge!(values)
|
96
|
+
self.settings = DEFAULTS.merge(values)
|
94
97
|
end
|
95
98
|
|
96
|
-
# Send the message via SMTP.
|
97
|
-
# The from and to attributes are optional. If not set, they are retrieve from the Message.
|
98
99
|
def deliver!(mail)
|
99
|
-
|
100
|
-
|
101
|
-
smtp = Net::SMTP.new(settings[:address], settings[:port])
|
102
|
-
if settings[:tls] || settings[:ssl]
|
103
|
-
if smtp.respond_to?(:enable_tls)
|
104
|
-
smtp.enable_tls(ssl_context)
|
105
|
-
end
|
106
|
-
elsif settings[:enable_starttls]
|
107
|
-
if smtp.respond_to?(:enable_starttls)
|
108
|
-
smtp.enable_starttls(ssl_context)
|
109
|
-
end
|
110
|
-
elsif settings[:enable_starttls_auto]
|
111
|
-
if smtp.respond_to?(:enable_starttls_auto)
|
112
|
-
smtp.enable_starttls_auto(ssl_context)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
smtp.open_timeout = settings[:open_timeout] if settings[:open_timeout]
|
116
|
-
smtp.read_timeout = settings[:read_timeout] if settings[:read_timeout]
|
117
|
-
|
118
|
-
response = nil
|
119
|
-
smtp.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication]) do |smtp_obj|
|
120
|
-
response = smtp_obj.sendmail(message, smtp_from, smtp_to)
|
100
|
+
response = start_smtp_session do |smtp|
|
101
|
+
Mail::SMTPConnection.new(:connection => smtp, :return_response => true).deliver!(mail)
|
121
102
|
end
|
122
103
|
|
123
|
-
|
124
|
-
response
|
125
|
-
else
|
126
|
-
self
|
127
|
-
end
|
104
|
+
settings[:return_response] ? response : self
|
128
105
|
end
|
129
106
|
|
130
107
|
private
|
108
|
+
def start_smtp_session(&block)
|
109
|
+
build_smtp_session.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication], &block)
|
110
|
+
end
|
131
111
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
112
|
+
def build_smtp_session
|
113
|
+
Net::SMTP.new(settings[:address], settings[:port]).tap do |smtp|
|
114
|
+
if settings[:tls] || settings[:ssl]
|
115
|
+
if smtp.respond_to?(:enable_tls)
|
116
|
+
smtp.enable_tls(ssl_context)
|
117
|
+
end
|
118
|
+
elsif settings[:enable_starttls]
|
119
|
+
if smtp.respond_to?(:enable_starttls)
|
120
|
+
smtp.enable_starttls(ssl_context)
|
121
|
+
end
|
122
|
+
elsif settings[:enable_starttls_auto]
|
123
|
+
if smtp.respond_to?(:enable_starttls_auto)
|
124
|
+
smtp.enable_starttls_auto(ssl_context)
|
125
|
+
end
|
126
|
+
end
|
136
127
|
|
137
|
-
|
138
|
-
|
128
|
+
smtp.open_timeout = settings[:open_timeout] if settings[:open_timeout]
|
129
|
+
smtp.read_timeout = settings[:read_timeout] if settings[:read_timeout]
|
130
|
+
end
|
139
131
|
end
|
140
132
|
|
141
|
-
context
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
133
|
+
# Allow SSL context to be configured via settings, for Ruby >= 1.9
|
134
|
+
# Just returns openssl verify mode for Ruby 1.8.x
|
135
|
+
def ssl_context
|
136
|
+
openssl_verify_mode = settings[:openssl_verify_mode]
|
137
|
+
|
138
|
+
if openssl_verify_mode.kind_of?(String)
|
139
|
+
openssl_verify_mode = OpenSSL::SSL.const_get("VERIFY_#{openssl_verify_mode.upcase}")
|
140
|
+
end
|
141
|
+
|
142
|
+
context = Net::SMTP.default_ssl_context
|
143
|
+
context.verify_mode = openssl_verify_mode if openssl_verify_mode
|
144
|
+
context.ca_path = settings[:ca_path] if settings[:ca_path]
|
145
|
+
context.ca_file = settings[:ca_file] if settings[:ca_file]
|
146
|
+
context
|
147
|
+
end
|
147
148
|
end
|
148
149
|
end
|