mail 2.5.2 → 2.6.0
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 +7 -0
- data/CHANGELOG.rdoc +78 -0
- data/CONTRIBUTING.md +17 -4
- data/Dependencies.txt +0 -1
- data/Gemfile +10 -21
- data/MIT-LICENSE +20 -0
- data/README.md +50 -29
- data/Rakefile +11 -22
- data/VERSION +4 -0
- data/lib/mail/attachments_list.rb +2 -2
- data/lib/mail/body.rb +5 -5
- data/lib/mail/check_delivery_params.rb +12 -22
- data/lib/mail/core_extensions/object.rb +8 -8
- data/lib/mail/core_extensions/smtp.rb +12 -13
- data/lib/mail/core_extensions/string.rb +16 -6
- data/lib/mail/elements/address.rb +43 -79
- data/lib/mail/elements/address_list.rb +19 -42
- data/lib/mail/elements/content_disposition_element.rb +3 -7
- data/lib/mail/elements/content_location_element.rb +2 -6
- data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
- data/lib/mail/elements/content_type_element.rb +4 -8
- data/lib/mail/elements/date_time_element.rb +3 -7
- data/lib/mail/elements/envelope_from_element.rb +18 -13
- data/lib/mail/elements/message_ids_element.rb +1 -6
- data/lib/mail/elements/mime_version_element.rb +3 -7
- data/lib/mail/elements/phrase_list.rb +2 -7
- data/lib/mail/elements/received_element.rb +3 -7
- data/lib/mail/encodings/quoted_printable.rb +4 -3
- data/lib/mail/encodings.rb +60 -28
- data/lib/mail/envelope.rb +0 -5
- data/lib/mail/field.rb +63 -28
- data/lib/mail/field_list.rb +18 -18
- data/lib/mail/fields/bcc_field.rb +2 -2
- data/lib/mail/fields/cc_field.rb +2 -2
- data/lib/mail/fields/comments_field.rb +1 -1
- data/lib/mail/fields/common/common_address.rb +26 -21
- data/lib/mail/fields/common/common_date.rb +0 -7
- data/lib/mail/fields/common/common_field.rb +5 -5
- data/lib/mail/fields/content_id_field.rb +1 -2
- data/lib/mail/fields/content_transfer_encoding_field.rb +2 -8
- data/lib/mail/fields/content_type_field.rb +1 -1
- data/lib/mail/fields/date_field.rb +14 -14
- data/lib/mail/fields/from_field.rb +2 -2
- data/lib/mail/fields/in_reply_to_field.rb +2 -1
- data/lib/mail/fields/message_id_field.rb +2 -3
- data/lib/mail/fields/references_field.rb +2 -1
- data/lib/mail/fields/reply_to_field.rb +2 -2
- data/lib/mail/fields/resent_bcc_field.rb +2 -2
- data/lib/mail/fields/resent_cc_field.rb +2 -2
- data/lib/mail/fields/resent_from_field.rb +2 -2
- data/lib/mail/fields/resent_sender_field.rb +3 -3
- data/lib/mail/fields/resent_to_field.rb +2 -2
- data/lib/mail/fields/sender_field.rb +8 -8
- data/lib/mail/fields/to_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +8 -2
- data/lib/mail/header.rb +13 -23
- data/lib/mail/mail.rb +12 -0
- data/lib/mail/matchers/has_sent_mail.rb +34 -1
- data/lib/mail/message.rb +151 -48
- data/lib/mail/multibyte/chars.rb +2 -2
- data/lib/mail/multibyte/unicode.rb +6 -4
- data/lib/mail/network/delivery_methods/exim.rb +1 -6
- data/lib/mail/network/delivery_methods/file_delivery.rb +1 -1
- data/lib/mail/network/delivery_methods/sendmail.rb +32 -10
- data/lib/mail/network/delivery_methods/smtp.rb +31 -34
- data/lib/mail/network/delivery_methods/smtp_connection.rb +6 -6
- data/lib/mail/network/delivery_methods/test_mailer.rb +2 -2
- data/lib/mail/network/retriever_methods/imap.rb +18 -13
- data/lib/mail/parsers/address_lists_parser.rb +132 -0
- data/lib/mail/parsers/content_disposition_parser.rb +67 -0
- data/lib/mail/parsers/content_location_parser.rb +35 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
- data/lib/mail/parsers/content_type_parser.rb +64 -0
- data/lib/mail/parsers/date_time_parser.rb +36 -0
- data/lib/mail/parsers/envelope_from_parser.rb +45 -0
- data/lib/mail/parsers/message_ids_parser.rb +39 -0
- data/lib/mail/parsers/mime_version_parser.rb +41 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
- data/lib/mail/parsers/ragel/common.rl +184 -0
- data/lib/mail/parsers/ragel/date_time.rl +30 -0
- data/lib/mail/parsers/ragel/parser_info.rb +61 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
- data/lib/mail/parsers/ragel/ruby.rb +29 -0
- data/lib/mail/parsers/ragel.rb +17 -0
- data/lib/mail/parsers/received_parser.rb +47 -0
- data/lib/mail/parsers.rb +26 -0
- data/lib/mail/part.rb +6 -2
- data/lib/mail/parts_list.rb +5 -3
- data/lib/mail/patterns.rb +4 -1
- data/lib/mail/utilities.rb +28 -18
- data/lib/mail/version.rb +1 -1
- data/lib/mail/version_specific/ruby_1_8.rb +6 -2
- data/lib/mail/version_specific/ruby_1_9.rb +61 -21
- data/lib/mail.rb +1 -2
- metadata +112 -73
- data/lib/VERSION +0 -4
- data/lib/load_parsers.rb +0 -41
- data/lib/mail/core_extensions/shell_escape.rb +0 -56
- 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 -162
- data/lib/mail/parsers/content_transfer_encoding.treetop +0 -20
- data/lib/mail/parsers/content_type.rb +0 -967
- 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 -464
- data/lib/mail/parsers/rfc2045.treetop +0 -36
- data/lib/mail/parsers/rfc2822.rb +0 -5397
- data/lib/mail/parsers/rfc2822.treetop +0 -410
- data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
- data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
- data/lib/tasks/corpus.rake +0 -125
- data/lib/tasks/treetop.rake +0 -10
data/lib/mail/message.rb
CHANGED
|
@@ -108,6 +108,9 @@ module Mail
|
|
|
108
108
|
@charset = 'UTF-8'
|
|
109
109
|
@defaulted_charset = true
|
|
110
110
|
|
|
111
|
+
@smtp_envelope_from = nil
|
|
112
|
+
@smtp_envelope_to = nil
|
|
113
|
+
|
|
111
114
|
@perform_deliveries = true
|
|
112
115
|
@raise_delivery_errors = true
|
|
113
116
|
|
|
@@ -122,7 +125,7 @@ module Mail
|
|
|
122
125
|
if args.flatten.first.respond_to?(:each_pair)
|
|
123
126
|
init_with_hash(args.flatten.first)
|
|
124
127
|
else
|
|
125
|
-
init_with_string(args.flatten[0].to_s
|
|
128
|
+
init_with_string(args.flatten[0].to_s)
|
|
126
129
|
end
|
|
127
130
|
|
|
128
131
|
if block_given?
|
|
@@ -169,7 +172,7 @@ module Mail
|
|
|
169
172
|
# obj.mail.deliver
|
|
170
173
|
#
|
|
171
174
|
# Would cause Mail to call obj.deliver_mail passing itself as a parameter,
|
|
172
|
-
# which then can just yield and let Mail do
|
|
175
|
+
# which then can just yield and let Mail do its own private do_delivery
|
|
173
176
|
# method.
|
|
174
177
|
attr_accessor :delivery_handler
|
|
175
178
|
|
|
@@ -237,7 +240,7 @@ module Mail
|
|
|
237
240
|
# This method bypasses checking perform_deliveries and raise_delivery_errors,
|
|
238
241
|
# so use with caution.
|
|
239
242
|
#
|
|
240
|
-
# It still however fires off the
|
|
243
|
+
# It still however fires off the interceptors and calls the observers callbacks if they are defined.
|
|
241
244
|
#
|
|
242
245
|
# Returns self
|
|
243
246
|
def deliver!
|
|
@@ -350,17 +353,23 @@ module Mail
|
|
|
350
353
|
return false unless other.respond_to?(:encoded)
|
|
351
354
|
|
|
352
355
|
if self.message_id && other.message_id
|
|
353
|
-
|
|
356
|
+
self.encoded == other.encoded
|
|
354
357
|
else
|
|
355
358
|
self_message_id, other_message_id = self.message_id, other.message_id
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
359
|
+
begin
|
|
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
|
|
361
365
|
end
|
|
362
366
|
end
|
|
363
367
|
|
|
368
|
+
def initialize_copy(original)
|
|
369
|
+
super
|
|
370
|
+
@header = @header.dup
|
|
371
|
+
end
|
|
372
|
+
|
|
364
373
|
# Provides access to the raw source of the message as it was when it
|
|
365
374
|
# was instantiated. This is set at initialization and so is untouched
|
|
366
375
|
# by the parsers or decoder / encoders
|
|
@@ -938,8 +947,8 @@ module Mail
|
|
|
938
947
|
#
|
|
939
948
|
# Example:
|
|
940
949
|
#
|
|
941
|
-
# mail.
|
|
942
|
-
# mail.
|
|
950
|
+
# mail.resent_sender = 'Mikel <mikel@test.lindsaar.net>'
|
|
951
|
+
# mail.resent_sender #=> 'mikel@test.lindsaar.net'
|
|
943
952
|
def resent_sender=( val )
|
|
944
953
|
header[:resent_sender] = val
|
|
945
954
|
end
|
|
@@ -1023,6 +1032,82 @@ module Mail
|
|
|
1023
1032
|
header[:sender] = val
|
|
1024
1033
|
end
|
|
1025
1034
|
|
|
1035
|
+
# Returns the SMTP Envelope From value of the mail object, as a single
|
|
1036
|
+
# string of an address spec.
|
|
1037
|
+
#
|
|
1038
|
+
# Defaults to Return-Path, Sender, or the first From address.
|
|
1039
|
+
#
|
|
1040
|
+
# Example:
|
|
1041
|
+
#
|
|
1042
|
+
# mail.smtp_envelope_from = 'Mikel <mikel@test.lindsaar.net>'
|
|
1043
|
+
# mail.smtp_envelope_from #=> 'mikel@test.lindsaar.net'
|
|
1044
|
+
#
|
|
1045
|
+
# Also allows you to set the value by passing a value as a parameter
|
|
1046
|
+
#
|
|
1047
|
+
# Example:
|
|
1048
|
+
#
|
|
1049
|
+
# mail.smtp_envelope_from 'Mikel <mikel@test.lindsaar.net>'
|
|
1050
|
+
# mail.smtp_envelope_from #=> 'mikel@test.lindsaar.net'
|
|
1051
|
+
def smtp_envelope_from( val = nil )
|
|
1052
|
+
if val
|
|
1053
|
+
self.smtp_envelope_from = val
|
|
1054
|
+
else
|
|
1055
|
+
@smtp_envelope_from || return_path || sender || from_addrs.first
|
|
1056
|
+
end
|
|
1057
|
+
end
|
|
1058
|
+
|
|
1059
|
+
# Sets the From address on the SMTP Envelope.
|
|
1060
|
+
#
|
|
1061
|
+
# Example:
|
|
1062
|
+
#
|
|
1063
|
+
# mail.smtp_envelope_from = 'Mikel <mikel@test.lindsaar.net>'
|
|
1064
|
+
# mail.smtp_envelope_from #=> 'mikel@test.lindsaar.net'
|
|
1065
|
+
def smtp_envelope_from=( val )
|
|
1066
|
+
@smtp_envelope_from = val
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
# Returns the SMTP Envelope To value of the mail object.
|
|
1070
|
+
#
|
|
1071
|
+
# Defaults to #destinations: To, Cc, and Bcc addresses.
|
|
1072
|
+
#
|
|
1073
|
+
# Example:
|
|
1074
|
+
#
|
|
1075
|
+
# mail.smtp_envelope_to = 'Mikel <mikel@test.lindsaar.net>'
|
|
1076
|
+
# mail.smtp_envelope_to #=> 'mikel@test.lindsaar.net'
|
|
1077
|
+
#
|
|
1078
|
+
# Also allows you to set the value by passing a value as a parameter
|
|
1079
|
+
#
|
|
1080
|
+
# Example:
|
|
1081
|
+
#
|
|
1082
|
+
# mail.smtp_envelope_to ['Mikel <mikel@test.lindsaar.net>', 'Lindsaar <lindsaar@test.lindsaar.net>']
|
|
1083
|
+
# mail.smtp_envelope_to #=> ['mikel@test.lindsaar.net', 'lindsaar@test.lindsaar.net']
|
|
1084
|
+
def smtp_envelope_to( val = nil )
|
|
1085
|
+
if val
|
|
1086
|
+
self.smtp_envelope_to = val
|
|
1087
|
+
else
|
|
1088
|
+
@smtp_envelope_to || destinations
|
|
1089
|
+
end
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
# Sets the To addresses on the SMTP Envelope.
|
|
1093
|
+
#
|
|
1094
|
+
# Example:
|
|
1095
|
+
#
|
|
1096
|
+
# mail.smtp_envelope_to = 'Mikel <mikel@test.lindsaar.net>'
|
|
1097
|
+
# mail.smtp_envelope_to #=> 'mikel@test.lindsaar.net'
|
|
1098
|
+
#
|
|
1099
|
+
# mail.smtp_envelope_to = ['Mikel <mikel@test.lindsaar.net>', 'Lindsaar <lindsaar@test.lindsaar.net>']
|
|
1100
|
+
# mail.smtp_envelope_to #=> ['mikel@test.lindsaar.net', 'lindsaar@test.lindsaar.net']
|
|
1101
|
+
def smtp_envelope_to=( val )
|
|
1102
|
+
@smtp_envelope_to =
|
|
1103
|
+
case val
|
|
1104
|
+
when Array, NilClass
|
|
1105
|
+
val
|
|
1106
|
+
else
|
|
1107
|
+
[val]
|
|
1108
|
+
end
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1026
1111
|
# Returns the decoded value of the subject field, as a single string.
|
|
1027
1112
|
#
|
|
1028
1113
|
# Example:
|
|
@@ -1309,7 +1394,7 @@ module Mail
|
|
|
1309
1394
|
header.has_date?
|
|
1310
1395
|
end
|
|
1311
1396
|
|
|
1312
|
-
# Returns true if the message has a
|
|
1397
|
+
# Returns true if the message has a Mime-Version field, the field may or may
|
|
1313
1398
|
# not have a value, but the field exists or not.
|
|
1314
1399
|
def has_mime_version?
|
|
1315
1400
|
header.has_mime_version?
|
|
@@ -1515,8 +1600,8 @@ module Mail
|
|
|
1515
1600
|
end
|
|
1516
1601
|
|
|
1517
1602
|
# Returns an AttachmentsList object, which holds all of the attachments in
|
|
1518
|
-
# the receiver object (either the
|
|
1519
|
-
# of
|
|
1603
|
+
# the receiver object (either the entire email or a part within) and all
|
|
1604
|
+
# of its descendants.
|
|
1520
1605
|
#
|
|
1521
1606
|
# It also allows you to add attachments to the mail object directly, like so:
|
|
1522
1607
|
#
|
|
@@ -1559,9 +1644,7 @@ module Mail
|
|
|
1559
1644
|
# Accessor for html_part
|
|
1560
1645
|
def html_part(&block)
|
|
1561
1646
|
if block_given?
|
|
1562
|
-
|
|
1563
|
-
add_multipart_alternate_header unless html_part.blank?
|
|
1564
|
-
add_part(@html_part)
|
|
1647
|
+
self.html_part = Mail::Part.new(:content_type => 'text/html', &block)
|
|
1565
1648
|
else
|
|
1566
1649
|
@html_part || find_first_mime_type('text/html')
|
|
1567
1650
|
end
|
|
@@ -1570,9 +1653,7 @@ module Mail
|
|
|
1570
1653
|
# Accessor for text_part
|
|
1571
1654
|
def text_part(&block)
|
|
1572
1655
|
if block_given?
|
|
1573
|
-
|
|
1574
|
-
add_multipart_alternate_header unless html_part.blank?
|
|
1575
|
-
add_part(@text_part)
|
|
1656
|
+
self.text_part = Mail::Part.new(:content_type => 'text/plain', &block)
|
|
1576
1657
|
else
|
|
1577
1658
|
@text_part || find_first_mime_type('text/plain')
|
|
1578
1659
|
end
|
|
@@ -1581,36 +1662,54 @@ module Mail
|
|
|
1581
1662
|
# Helper to add a html part to a multipart/alternative email. If this and
|
|
1582
1663
|
# text_part are both defined in a message, then it will be a multipart/alternative
|
|
1583
1664
|
# message and set itself that way.
|
|
1584
|
-
def html_part=(msg
|
|
1665
|
+
def html_part=(msg)
|
|
1666
|
+
# Assign the html part and set multipart/alternative if there's a text part.
|
|
1585
1667
|
if msg
|
|
1586
1668
|
@html_part = msg
|
|
1587
|
-
|
|
1588
|
-
|
|
1669
|
+
@html_part.content_type = 'text/html' unless @html_part.has_content_type?
|
|
1670
|
+
add_multipart_alternate_header if text_part
|
|
1671
|
+
add_part @html_part
|
|
1672
|
+
|
|
1673
|
+
# If nil, delete the html part and back out of multipart/alternative.
|
|
1674
|
+
elsif @html_part
|
|
1675
|
+
parts.delete_if { |p| p.object_id == @html_part.object_id }
|
|
1676
|
+
@html_part = nil
|
|
1677
|
+
if text_part
|
|
1678
|
+
self.content_type = nil
|
|
1679
|
+
body.boundary = nil
|
|
1680
|
+
end
|
|
1589
1681
|
end
|
|
1590
|
-
add_multipart_alternate_header unless text_part.blank?
|
|
1591
|
-
add_part(@html_part)
|
|
1592
1682
|
end
|
|
1593
1683
|
|
|
1594
1684
|
# Helper to add a text part to a multipart/alternative email. If this and
|
|
1595
1685
|
# html_part are both defined in a message, then it will be a multipart/alternative
|
|
1596
1686
|
# message and set itself that way.
|
|
1597
|
-
def text_part=(msg
|
|
1687
|
+
def text_part=(msg)
|
|
1688
|
+
# Assign the text part and set multipart/alternative if there's an html part.
|
|
1598
1689
|
if msg
|
|
1599
1690
|
@text_part = msg
|
|
1600
|
-
|
|
1601
|
-
|
|
1691
|
+
@text_part.content_type = 'text/plain' unless @text_part.has_content_type?
|
|
1692
|
+
add_multipart_alternate_header if html_part
|
|
1693
|
+
add_part @text_part
|
|
1694
|
+
|
|
1695
|
+
# If nil, delete the text part and back out of multipart/alternative.
|
|
1696
|
+
elsif @text_part
|
|
1697
|
+
parts.delete_if { |p| p.object_id == @text_part.object_id }
|
|
1698
|
+
@text_part = nil
|
|
1699
|
+
if html_part
|
|
1700
|
+
self.content_type = nil
|
|
1701
|
+
body.boundary = nil
|
|
1702
|
+
end
|
|
1602
1703
|
end
|
|
1603
|
-
add_multipart_alternate_header unless html_part.blank?
|
|
1604
|
-
add_part(@text_part)
|
|
1605
1704
|
end
|
|
1606
1705
|
|
|
1607
1706
|
# Adds a part to the parts list or creates the part list
|
|
1608
1707
|
def add_part(part)
|
|
1609
1708
|
if !body.multipart? && !self.body.decoded.blank?
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1709
|
+
@text_part = Mail::Part.new('Content-Type: text/plain;')
|
|
1710
|
+
@text_part.body = body.decoded
|
|
1711
|
+
self.body << @text_part
|
|
1712
|
+
add_multipart_alternate_header
|
|
1614
1713
|
end
|
|
1615
1714
|
add_boundary
|
|
1616
1715
|
self.body << part
|
|
@@ -1646,7 +1745,7 @@ module Mail
|
|
|
1646
1745
|
# m.add_file(:filename => 'filename.png', :content => File.read('/path/to/file.jpg'))
|
|
1647
1746
|
#
|
|
1648
1747
|
# Note also that if you add a file to an existing message, Mail will convert that message
|
|
1649
|
-
# to a MIME multipart email, moving whatever plain text body you had into
|
|
1748
|
+
# to a MIME multipart email, moving whatever plain text body you had into its own text
|
|
1650
1749
|
# plain part.
|
|
1651
1750
|
#
|
|
1652
1751
|
# Example:
|
|
@@ -1683,7 +1782,7 @@ module Mail
|
|
|
1683
1782
|
self.body << text_part
|
|
1684
1783
|
end
|
|
1685
1784
|
|
|
1686
|
-
# Encodes the message, calls encode on all
|
|
1785
|
+
# Encodes the message, calls encode on all its parts, gets an email message
|
|
1687
1786
|
# ready to send
|
|
1688
1787
|
def ready_to_send!
|
|
1689
1788
|
identify_and_set_transfer_encoding
|
|
@@ -1875,14 +1974,15 @@ module Mail
|
|
|
1875
1974
|
# Additionally, I allow for the case where someone might have put whitespace
|
|
1876
1975
|
# on the "gap line"
|
|
1877
1976
|
def parse_message
|
|
1878
|
-
header_part, body_part = raw_source.split(/#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/m, 2)
|
|
1977
|
+
header_part, body_part = raw_source.lstrip.split(/#{CRLF}#{CRLF}|#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/m, 2)
|
|
1879
1978
|
self.header = header_part
|
|
1880
1979
|
self.body = body_part
|
|
1881
1980
|
end
|
|
1882
1981
|
|
|
1883
1982
|
def raw_source=(value)
|
|
1884
|
-
value.force_encoding("binary") if RUBY_VERSION >= "1.9.1"
|
|
1885
1983
|
@raw_source = value.to_crlf
|
|
1984
|
+
@raw_source.force_encoding("binary") if RUBY_VERSION >= "1.9.1"
|
|
1985
|
+
@raw_source
|
|
1886
1986
|
end
|
|
1887
1987
|
|
|
1888
1988
|
# see comments to body=. We take data and process it lazily
|
|
@@ -1904,11 +2004,11 @@ module Mail
|
|
|
1904
2004
|
|
|
1905
2005
|
|
|
1906
2006
|
def process_body_raw
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2007
|
+
@body = Mail::Body.new(@body_raw)
|
|
2008
|
+
@body_raw = nil
|
|
2009
|
+
separate_parts if @separate_parts
|
|
1910
2010
|
|
|
1911
|
-
|
|
2011
|
+
add_encoding_to_body
|
|
1912
2012
|
end
|
|
1913
2013
|
|
|
1914
2014
|
def set_envelope_header
|
|
@@ -1938,16 +2038,19 @@ module Mail
|
|
|
1938
2038
|
end
|
|
1939
2039
|
|
|
1940
2040
|
def add_required_fields
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
add_message_id unless (has_message_id? || self.class == Mail::Part)
|
|
1944
|
-
add_date unless has_date?
|
|
1945
|
-
add_mime_version unless has_mime_version?
|
|
2041
|
+
add_required_message_fields
|
|
2042
|
+
add_multipart_mixed_header if body.multipart?
|
|
1946
2043
|
add_content_type unless has_content_type?
|
|
1947
2044
|
add_charset unless has_charset?
|
|
1948
2045
|
add_content_transfer_encoding unless has_content_transfer_encoding?
|
|
1949
2046
|
end
|
|
1950
2047
|
|
|
2048
|
+
def add_required_message_fields
|
|
2049
|
+
add_date unless has_date?
|
|
2050
|
+
add_mime_version unless has_mime_version?
|
|
2051
|
+
add_message_id unless has_message_id?
|
|
2052
|
+
end
|
|
2053
|
+
|
|
1951
2054
|
def add_multipart_alternate_header
|
|
1952
2055
|
header['content-type'] = ContentTypeField.with_boundary('multipart/alternative').value
|
|
1953
2056
|
header['content_type'].parameters[:charset] = @charset
|
|
@@ -2032,7 +2135,7 @@ module Mail
|
|
|
2032
2135
|
if perform_deliveries
|
|
2033
2136
|
delivery_method.deliver!(self)
|
|
2034
2137
|
end
|
|
2035
|
-
rescue
|
|
2138
|
+
rescue => e # Net::SMTP errors or sendmail pipe errors
|
|
2036
2139
|
raise e if raise_delivery_errors
|
|
2037
2140
|
end
|
|
2038
2141
|
end
|
data/lib/mail/multibyte/chars.rb
CHANGED
|
@@ -364,7 +364,7 @@ module Mail #:nodoc:
|
|
|
364
364
|
# "ÉL QUE SE ENTERÓ".mb_chars.titleize # => "Él Que Se Enteró"
|
|
365
365
|
# "日本語".mb_chars.titleize # => "日本語"
|
|
366
366
|
def titleize
|
|
367
|
-
chars(downcase.to_s.gsub(/\b('
|
|
367
|
+
chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.apply_mapping $1, :uppercase_mapping })
|
|
368
368
|
end
|
|
369
369
|
alias_method :titlecase, :titleize
|
|
370
370
|
|
|
@@ -412,7 +412,7 @@ module Mail #:nodoc:
|
|
|
412
412
|
chars(Unicode.tidy_bytes(@wrapped_string, force))
|
|
413
413
|
end
|
|
414
414
|
|
|
415
|
-
|
|
415
|
+
%w(capitalize downcase lstrip reverse rstrip slice strip tidy_bytes upcase).each do |method|
|
|
416
416
|
# Only define a corresponding bang method for methods defined in the proxy; On 1.9 the proxy will
|
|
417
417
|
# exclude lstrip!, rstrip! and strip! because they are already work as expected on multibyte strings.
|
|
418
418
|
if public_method_defined?(method)
|
|
@@ -341,7 +341,7 @@ module Mail
|
|
|
341
341
|
def load
|
|
342
342
|
begin
|
|
343
343
|
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
|
|
344
|
-
rescue
|
|
344
|
+
rescue => e
|
|
345
345
|
raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), Mail::Multibyte is unusable")
|
|
346
346
|
end
|
|
347
347
|
|
|
@@ -391,8 +391,10 @@ module Mail
|
|
|
391
391
|
end
|
|
392
392
|
end
|
|
393
393
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
394
|
+
unless defined?(ActiveSupport)
|
|
395
|
+
module ActiveSupport
|
|
396
|
+
unless const_defined?(:Multibyte)
|
|
397
|
+
Multibyte = Mail::Multibyte
|
|
398
|
+
end
|
|
397
399
|
end
|
|
398
400
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'mail/check_delivery_params'
|
|
2
|
-
|
|
3
1
|
module Mail
|
|
4
2
|
|
|
5
3
|
# A delivery method implementation which sends via exim.
|
|
@@ -38,16 +36,13 @@ module Mail
|
|
|
38
36
|
#
|
|
39
37
|
# mail.deliver!
|
|
40
38
|
class Exim < Sendmail
|
|
41
|
-
include Mail::CheckDeliveryParams
|
|
42
|
-
|
|
43
39
|
def initialize(values)
|
|
44
40
|
self.settings = { :location => '/usr/sbin/exim',
|
|
45
41
|
:arguments => '-i -t' }.merge(values)
|
|
46
42
|
end
|
|
47
43
|
|
|
48
44
|
def self.call(path, arguments, destinations, mail)
|
|
49
|
-
|
|
50
|
-
IO.popen("#{path} #{arguments}", "w+") do |io|
|
|
45
|
+
popen "#{path} #{arguments}" do |io|
|
|
51
46
|
io.puts mail.encoded.to_lf
|
|
52
47
|
io.flush
|
|
53
48
|
end
|
|
@@ -41,27 +41,49 @@ module Mail
|
|
|
41
41
|
|
|
42
42
|
def initialize(values)
|
|
43
43
|
self.settings = { :location => '/usr/sbin/sendmail',
|
|
44
|
-
:arguments => '-i
|
|
44
|
+
:arguments => '-i' }.merge(values)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
attr_accessor :settings
|
|
48
48
|
|
|
49
49
|
def deliver!(mail)
|
|
50
|
-
|
|
50
|
+
smtp_from, smtp_to, message = check_delivery_params(mail)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
from = "-f #{self.class.shellquote(smtp_from)}"
|
|
53
|
+
to = smtp_to.map { |_to| self.class.shellquote(_to) }.join(' ')
|
|
54
54
|
|
|
55
|
-
arguments =
|
|
56
|
-
|
|
57
|
-
self.class.call(settings[:location], arguments, mail.destinations.collect(&:escape_for_shell).join(" "), mail)
|
|
55
|
+
arguments = "#{settings[:arguments]} #{from} --"
|
|
56
|
+
self.class.call(settings[:location], arguments, to, message)
|
|
58
57
|
end
|
|
59
58
|
|
|
60
|
-
def self.call(path, arguments, destinations,
|
|
61
|
-
|
|
62
|
-
io.puts
|
|
59
|
+
def self.call(path, arguments, destinations, encoded_message)
|
|
60
|
+
popen "#{path} #{arguments} #{destinations}" do |io|
|
|
61
|
+
io.puts encoded_message.to_lf
|
|
63
62
|
io.flush
|
|
64
63
|
end
|
|
65
64
|
end
|
|
65
|
+
|
|
66
|
+
if RUBY_VERSION < '1.9.0'
|
|
67
|
+
def self.popen(command, &block)
|
|
68
|
+
IO.popen "#{command} 2>&1", 'w+', &block
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
def self.popen(command, &block)
|
|
72
|
+
IO.popen command, 'w+', :err => :out, &block
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# The following is an adaptation of ruby 1.9.2's shellwords.rb file,
|
|
77
|
+
# it is modified to include '+' in the allowed list to allow for
|
|
78
|
+
# sendmail to accept email addresses as the sender with a + in them.
|
|
79
|
+
def self.shellquote(address)
|
|
80
|
+
# Process as a single byte sequence because not all shell
|
|
81
|
+
# implementations are multibyte aware.
|
|
82
|
+
#
|
|
83
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
|
84
|
+
# combo is regarded as line continuation and simply ignored. Strip it.
|
|
85
|
+
escaped = address.gsub(/([^A-Za-z0-9_\s\+\-.,:\/@])/n, "\\\\\\1").gsub("\n", '')
|
|
86
|
+
%("#{escaped}")
|
|
87
|
+
end
|
|
66
88
|
end
|
|
67
89
|
end
|
|
@@ -89,57 +89,54 @@ module Mail
|
|
|
89
89
|
:tls => nil
|
|
90
90
|
}.merge!(values)
|
|
91
91
|
end
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
attr_accessor :settings
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
# Send the message via SMTP.
|
|
96
96
|
# The from and to attributes are optional. If not set, they are retrieve from the Message.
|
|
97
97
|
def deliver!(mail)
|
|
98
|
-
|
|
98
|
+
smtp_from, smtp_to, message = check_delivery_params(mail)
|
|
99
99
|
|
|
100
100
|
smtp = Net::SMTP.new(settings[:address], settings[:port])
|
|
101
101
|
if settings[:tls] || settings[:ssl]
|
|
102
102
|
if smtp.respond_to?(:enable_tls)
|
|
103
|
-
|
|
104
|
-
smtp.enable_tls
|
|
105
|
-
else
|
|
106
|
-
openssl_verify_mode = settings[:openssl_verify_mode]
|
|
107
|
-
if openssl_verify_mode.kind_of?(String)
|
|
108
|
-
openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
|
|
109
|
-
end
|
|
110
|
-
context = Net::SMTP.default_ssl_context
|
|
111
|
-
context.verify_mode = openssl_verify_mode
|
|
112
|
-
smtp.enable_tls(context)
|
|
113
|
-
end
|
|
103
|
+
smtp.enable_tls(ssl_context)
|
|
114
104
|
end
|
|
115
105
|
elsif settings[:enable_starttls_auto]
|
|
116
|
-
if smtp.respond_to?(:enable_starttls_auto)
|
|
117
|
-
|
|
118
|
-
smtp.enable_starttls_auto
|
|
119
|
-
else
|
|
120
|
-
openssl_verify_mode = settings[:openssl_verify_mode]
|
|
121
|
-
if openssl_verify_mode.kind_of?(String)
|
|
122
|
-
openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
|
|
123
|
-
end
|
|
124
|
-
if RUBY_VERSION >= '1.9.0'
|
|
125
|
-
context = Net::SMTP.default_ssl_context
|
|
126
|
-
context.verify_mode = openssl_verify_mode
|
|
127
|
-
smtp.enable_tls(context)
|
|
128
|
-
else
|
|
129
|
-
smtp.enable_tls(openssl_verify_mode)
|
|
130
|
-
end
|
|
131
|
-
end
|
|
106
|
+
if smtp.respond_to?(:enable_starttls_auto)
|
|
107
|
+
smtp.enable_starttls_auto(ssl_context)
|
|
132
108
|
end
|
|
133
109
|
end
|
|
134
|
-
|
|
110
|
+
|
|
135
111
|
response = nil
|
|
136
112
|
smtp.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication]) do |smtp_obj|
|
|
137
|
-
response = smtp_obj.sendmail(message,
|
|
113
|
+
response = smtp_obj.sendmail(message, smtp_from, smtp_to)
|
|
138
114
|
end
|
|
139
115
|
|
|
140
|
-
|
|
116
|
+
if settings[:return_response]
|
|
117
|
+
response
|
|
118
|
+
else
|
|
119
|
+
self
|
|
120
|
+
end
|
|
141
121
|
end
|
|
142
122
|
|
|
143
|
-
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
# Allow SSL context to be configured via settings, for Ruby >= 1.9
|
|
127
|
+
# Just returns openssl verify mode for Ruby 1.8.x
|
|
128
|
+
def ssl_context
|
|
129
|
+
openssl_verify_mode = settings[:openssl_verify_mode]
|
|
130
|
+
|
|
131
|
+
if openssl_verify_mode.kind_of?(String)
|
|
132
|
+
openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context = Net::SMTP.default_ssl_context
|
|
136
|
+
context.verify_mode = openssl_verify_mode
|
|
137
|
+
context.ca_path = settings[:ca_path] if settings[:ca_path]
|
|
138
|
+
context.ca_file = settings[:ca_file] if settings[:ca_file]
|
|
139
|
+
context
|
|
140
|
+
end
|
|
144
141
|
end
|
|
145
142
|
end
|
|
@@ -44,18 +44,18 @@ module Mail
|
|
|
44
44
|
self.smtp = values[:connection]
|
|
45
45
|
self.settings = values
|
|
46
46
|
end
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
attr_accessor :smtp
|
|
49
49
|
attr_accessor :settings
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
# Send the message via SMTP.
|
|
52
52
|
# The from and to attributes are optional. If not set, they are retrieve from the Message.
|
|
53
53
|
def deliver!(mail)
|
|
54
|
-
|
|
55
|
-
response = smtp.sendmail(message,
|
|
54
|
+
smtp_from, smtp_to, message = check_delivery_params(mail)
|
|
55
|
+
response = smtp.sendmail(message, smtp_from, smtp_to)
|
|
56
56
|
|
|
57
|
-
settings[:return_response] ? response : self
|
|
57
|
+
settings[:return_response] ? response : self
|
|
58
58
|
end
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -30,13 +30,13 @@ module Mail
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def initialize(values)
|
|
33
|
-
@settings =
|
|
33
|
+
@settings = values.dup
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
attr_accessor :settings
|
|
37
37
|
|
|
38
38
|
def deliver!(mail)
|
|
39
|
-
|
|
39
|
+
check_delivery_params(mail)
|
|
40
40
|
Mail::TestMailer.deliveries << mail
|
|
41
41
|
end
|
|
42
42
|
|