mail 2.7.1 → 2.9.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 +4 -4
- data/README.md +135 -59
- data/lib/mail/attachments_list.rb +5 -6
- data/lib/mail/body.rb +51 -74
- data/lib/mail/constants.rb +27 -5
- data/lib/mail/elements/address.rb +27 -27
- data/lib/mail/elements/address_list.rb +1 -1
- data/lib/mail/elements/content_disposition_element.rb +1 -1
- data/lib/mail/elements/content_location_element.rb +1 -1
- data/lib/mail/elements/content_transfer_encoding_element.rb +1 -1
- data/lib/mail/elements/content_type_element.rb +8 -4
- data/lib/mail/elements/date_time_element.rb +1 -1
- data/lib/mail/elements/envelope_from_element.rb +13 -7
- data/lib/mail/elements/message_ids_element.rb +14 -5
- data/lib/mail/elements/mime_version_element.rb +1 -1
- data/lib/mail/elements/phrase_list.rb +7 -2
- data/lib/mail/elements/received_element.rb +20 -6
- data/lib/mail/encodings/7bit.rb +5 -0
- data/lib/mail/encodings/base64.rb +2 -2
- data/lib/mail/encodings/quoted_printable.rb +2 -2
- data/lib/mail/encodings/unix_to_unix.rb +1 -1
- data/lib/mail/encodings.rb +32 -61
- data/lib/mail/envelope.rb +11 -14
- data/lib/mail/field.rb +100 -86
- data/lib/mail/field_list.rb +61 -8
- data/lib/mail/fields/bcc_field.rb +33 -52
- data/lib/mail/fields/cc_field.rb +27 -49
- data/lib/mail/fields/comments_field.rb +26 -37
- data/lib/mail/fields/common_address_field.rb +162 -0
- data/lib/mail/fields/common_date_field.rb +56 -0
- data/lib/mail/fields/common_field.rb +77 -0
- data/lib/mail/fields/common_message_id_field.rb +41 -0
- data/lib/mail/fields/content_description_field.rb +6 -14
- data/lib/mail/fields/content_disposition_field.rb +11 -38
- data/lib/mail/fields/content_id_field.rb +23 -51
- data/lib/mail/fields/content_location_field.rb +10 -25
- data/lib/mail/fields/content_transfer_encoding_field.rb +30 -31
- data/lib/mail/fields/content_type_field.rb +49 -75
- data/lib/mail/fields/date_field.rb +22 -51
- data/lib/mail/fields/from_field.rb +27 -49
- data/lib/mail/fields/in_reply_to_field.rb +37 -49
- data/lib/mail/fields/keywords_field.rb +17 -31
- data/lib/mail/fields/message_id_field.rb +24 -71
- data/lib/mail/fields/mime_version_field.rb +18 -30
- data/lib/mail/fields/named_structured_field.rb +10 -0
- data/lib/mail/fields/named_unstructured_field.rb +10 -0
- data/lib/mail/fields/optional_field.rb +5 -7
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +12 -10
- data/lib/mail/fields/received_field.rb +42 -57
- data/lib/mail/fields/references_field.rb +34 -49
- data/lib/mail/fields/reply_to_field.rb +27 -49
- data/lib/mail/fields/resent_bcc_field.rb +27 -49
- data/lib/mail/fields/resent_cc_field.rb +27 -49
- data/lib/mail/fields/resent_date_field.rb +4 -29
- data/lib/mail/fields/resent_from_field.rb +27 -49
- data/lib/mail/fields/resent_message_id_field.rb +4 -29
- data/lib/mail/fields/resent_sender_field.rb +26 -56
- data/lib/mail/fields/resent_to_field.rb +27 -49
- data/lib/mail/fields/return_path_field.rb +49 -54
- data/lib/mail/fields/sender_field.rb +33 -55
- data/lib/mail/fields/structured_field.rb +2 -30
- data/lib/mail/fields/subject_field.rb +8 -11
- data/lib/mail/fields/to_field.rb +27 -49
- data/lib/mail/fields/unstructured_field.rb +15 -48
- data/lib/mail/fields.rb +9 -0
- data/lib/mail/header.rb +69 -110
- data/lib/mail/mail.rb +32 -27
- data/lib/mail/matchers/attachment_matchers.rb +15 -0
- data/lib/mail/message.rb +67 -78
- data/lib/mail/multibyte/chars.rb +9 -167
- data/lib/mail/multibyte/unicode.rb +1 -1
- data/lib/mail/multibyte/utils.rb +26 -43
- data/lib/mail/multibyte.rb +1 -11
- data/lib/mail/network/delivery_methods/exim.rb +5 -4
- data/lib/mail/network/delivery_methods/file_delivery.rb +13 -12
- data/lib/mail/network/delivery_methods/logger_delivery.rb +2 -5
- data/lib/mail/network/delivery_methods/sendmail.rb +27 -35
- data/lib/mail/network/delivery_methods/smtp.rb +81 -30
- data/lib/mail/network/delivery_methods/smtp_connection.rb +10 -19
- data/lib/mail/network/delivery_methods/test_mailer.rb +8 -6
- data/lib/mail/network/retriever_methods/base.rb +13 -13
- data/lib/mail/network/retriever_methods/imap.rb +8 -5
- data/lib/mail/network/retriever_methods/pop3.rb +22 -22
- data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
- data/lib/mail/parsers/address_lists_parser.rb +33073 -33064
- data/lib/mail/parsers/address_lists_parser.rl +11 -0
- data/lib/mail/parsers/content_disposition_parser.rb +837 -828
- data/lib/mail/parsers/content_disposition_parser.rl +11 -0
- data/lib/mail/parsers/content_location_parser.rb +773 -764
- data/lib/mail/parsers/content_location_parser.rl +12 -1
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +477 -468
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +11 -0
- data/lib/mail/parsers/content_type_parser.rb +974 -965
- data/lib/mail/parsers/content_type_parser.rl +11 -0
- data/lib/mail/parsers/date_time_parser.rb +841 -832
- data/lib/mail/parsers/date_time_parser.rl +11 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3627 -3530
- data/lib/mail/parsers/envelope_from_parser.rl +11 -0
- data/lib/mail/parsers/message_ids_parser.rb +5110 -2800
- data/lib/mail/parsers/message_ids_parser.rl +16 -1
- data/lib/mail/parsers/mime_version_parser.rb +466 -457
- data/lib/mail/parsers/mime_version_parser.rl +11 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +839 -830
- data/lib/mail/parsers/phrase_lists_parser.rl +12 -1
- data/lib/mail/parsers/received_parser.rb +8692 -8683
- data/lib/mail/parsers/received_parser.rl +11 -0
- data/lib/mail/parsers/rfc5322.rl +28 -13
- data/lib/mail/parsers.rb +11 -17
- data/lib/mail/part.rb +24 -28
- data/lib/mail/parts_list.rb +57 -0
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +321 -69
- data/lib/mail/version.rb +1 -1
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +2 -22
- metadata +83 -19
- data/lib/mail/check_delivery_params.rb +0 -60
- data/lib/mail/core_extensions/smtp.rb +0 -28
- data/lib/mail/core_extensions/string.rb +0 -17
- data/lib/mail/fields/common/address_container.rb +0 -17
- data/lib/mail/fields/common/common_address.rb +0 -161
- data/lib/mail/fields/common/common_date.rb +0 -36
- data/lib/mail/fields/common/common_field.rb +0 -52
- data/lib/mail/fields/common/common_message_id.rb +0 -49
- data/lib/mail/version_specific/ruby_1_8.rb +0 -163
- data/lib/mail/version_specific/ruby_1_9.rb +0 -278
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
require 'mail/utilities'
|
|
3
3
|
require 'mail/parser_tools'
|
|
4
4
|
|
|
5
|
+
begin
|
|
6
|
+
original_verbose, $VERBOSE = $VERBOSE, nil
|
|
7
|
+
|
|
5
8
|
%%{
|
|
6
9
|
machine date_time;
|
|
7
10
|
alphtype int;
|
|
@@ -74,6 +77,10 @@ module Mail::Parsers
|
|
|
74
77
|
%%write init;
|
|
75
78
|
%%write exec;
|
|
76
79
|
|
|
80
|
+
if false
|
|
81
|
+
testEof
|
|
82
|
+
end
|
|
83
|
+
|
|
77
84
|
if p != eof || cs < %%{ write first_final; }%%
|
|
78
85
|
raise Mail::Field::IncompleteParseError.new(Mail::ReceivedElement, data, p)
|
|
79
86
|
end
|
|
@@ -82,3 +89,7 @@ module Mail::Parsers
|
|
|
82
89
|
end
|
|
83
90
|
end
|
|
84
91
|
end
|
|
92
|
+
|
|
93
|
+
ensure
|
|
94
|
+
$VERBOSE = original_verbose
|
|
95
|
+
end
|
data/lib/mail/parsers/rfc5322.rl
CHANGED
|
@@ -30,19 +30,35 @@
|
|
|
30
30
|
|
|
31
31
|
# 3.6.4. Identification Fields
|
|
32
32
|
obs_id_left = local_part;
|
|
33
|
-
id_left = dot_atom_text | obs_id_left;
|
|
34
|
-
# id_right modifications to support multiple '@' in msg_id.
|
|
35
|
-
msg_id_atext = ALPHA | DIGIT | "!" | "#" | "$" | "%" | "&" | "'" | "*" |
|
|
36
|
-
"+" | "-" | "/" | "=" | "?" | "^" | "_" | "`" | "{" | "|" |
|
|
37
|
-
"}" | "~" | "@";
|
|
38
|
-
msg_id_dot_atom_text = (msg_id_atext+ "."?)+;
|
|
39
33
|
obs_id_right = domain;
|
|
40
34
|
no_fold_literal = "[" (dtext)* "]";
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
|
|
36
|
+
msg_id_atext = rfc5322_atext | ":" | "," | "." | " ";
|
|
37
|
+
|
|
38
|
+
id_left = msg_id_atext+ | obs_id_left;
|
|
39
|
+
id_left_ns = ( msg_id_atext - ( " " | "," ) )+;
|
|
40
|
+
|
|
41
|
+
# id_right modifications to support multiple '@' in msg_id.
|
|
42
|
+
id_right = ( msg_id_atext | "@" )+ | no_fold_literal | obs_id_right;
|
|
43
|
+
id_right_ns = ( msg_id_atext - ( " " | "," ) | "@" )+ | no_fold_literal;
|
|
44
|
+
|
|
45
|
+
# Handle various message-id formats:
|
|
46
|
+
# <id_left@id_right>
|
|
47
|
+
# <id_left@id_right...
|
|
48
|
+
# <id_left@>
|
|
49
|
+
# <id_left>
|
|
50
|
+
# <id_left...
|
|
51
|
+
# id_left@id_right
|
|
52
|
+
# id_left
|
|
53
|
+
# Handle comma-separated message_ids.
|
|
54
|
+
msg_id = (CFWS)? (
|
|
55
|
+
(("<" id_left "@" id_right? ">") >msg_id_s %msg_id_e) |
|
|
56
|
+
(("<" id_left "@" id_right? :>> "...") >msg_id_s %msg_id_e) |
|
|
57
|
+
(("<" id_left ">") >msg_id_s %msg_id_e) |
|
|
58
|
+
(("<" id_left :>> "..." ) >msg_id_s %msg_id_e) |
|
|
59
|
+
((id_left_ns ("@" id_right_ns)? ) >msg_id_s %msg_id_e)
|
|
60
|
+
) (CFWS)? <: ","?;
|
|
61
|
+
message_ids = msg_id**;
|
|
46
62
|
|
|
47
63
|
|
|
48
64
|
# 3.6.7 Trace Fields
|
|
@@ -54,6 +70,5 @@
|
|
|
54
70
|
# Envelope From
|
|
55
71
|
ctime_date = day_name " "+ month " "+ day " " time_of_day " " year;
|
|
56
72
|
null_sender = ('<>' ' '{0,1});
|
|
57
|
-
envelope_from = (addr_spec_no_angle_brackets | null_sender) >address_s %address_e " "
|
|
58
|
-
(ctime_date >ctime_date_s %ctime_date_e);
|
|
73
|
+
envelope_from = (addr_spec_no_angle_brackets | null_sender) >address_s %address_e (" " (ctime_date >ctime_date_s %ctime_date_e))?;
|
|
59
74
|
}%%
|
data/lib/mail/parsers.rb
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# Ragel-generated parsers are full of known warnings. Suppress them.
|
|
3
|
-
begin
|
|
4
|
-
orig, $VERBOSE = $VERBOSE, nil
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ensure
|
|
18
|
-
$VERBOSE = orig
|
|
19
|
-
end
|
|
3
|
+
require 'mail/parsers/address_lists_parser'
|
|
4
|
+
require 'mail/parsers/content_disposition_parser'
|
|
5
|
+
require 'mail/parsers/content_location_parser'
|
|
6
|
+
require 'mail/parsers/content_transfer_encoding_parser'
|
|
7
|
+
require 'mail/parsers/content_type_parser'
|
|
8
|
+
require 'mail/parsers/date_time_parser'
|
|
9
|
+
require 'mail/parsers/envelope_from_parser'
|
|
10
|
+
require 'mail/parsers/message_ids_parser'
|
|
11
|
+
require 'mail/parsers/mime_version_parser'
|
|
12
|
+
require 'mail/parsers/phrase_lists_parser'
|
|
13
|
+
require 'mail/parsers/received_parser'
|
data/lib/mail/part.rb
CHANGED
|
@@ -1,43 +1,39 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
require 'mail/constants'
|
|
4
|
+
require 'mail/utilities'
|
|
5
|
+
|
|
3
6
|
module Mail
|
|
4
7
|
class Part < Message
|
|
5
|
-
|
|
6
8
|
# Creates a new empty Content-ID field and inserts it in the correct order
|
|
7
9
|
# into the Header. The ContentIdField object will automatically generate
|
|
8
10
|
# a unique content ID if you try and encode it or output it to_s without
|
|
9
11
|
# specifying a content id.
|
|
10
|
-
#
|
|
12
|
+
#
|
|
11
13
|
# It will preserve the content ID you specify if you do.
|
|
12
14
|
def add_content_id(content_id_val = '')
|
|
13
15
|
header['content-id'] = content_id_val
|
|
14
16
|
end
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
# Returns true if the part has a content ID field, the field may or may
|
|
17
19
|
# not have a value, but the field exists or not.
|
|
18
20
|
def has_content_id?
|
|
19
21
|
header.has_content_id?
|
|
20
22
|
end
|
|
21
|
-
|
|
22
|
-
def inline_content_id
|
|
23
|
-
# TODO: Deprecated in 2.2.2 - Remove in 2.3
|
|
24
|
-
warn("Part#inline_content_id is deprecated, please call Part#cid instead")
|
|
25
|
-
cid
|
|
26
|
-
end
|
|
27
|
-
|
|
23
|
+
|
|
28
24
|
def cid
|
|
29
25
|
add_content_id unless has_content_id?
|
|
30
|
-
uri_escape(unbracket(content_id))
|
|
26
|
+
Utilities.uri_escape(Utilities.unbracket(content_id))
|
|
31
27
|
end
|
|
32
|
-
|
|
28
|
+
|
|
33
29
|
def url
|
|
34
30
|
"cid:#{cid}"
|
|
35
31
|
end
|
|
36
|
-
|
|
32
|
+
|
|
37
33
|
def inline?
|
|
38
34
|
header[:content_disposition].disposition_type == 'inline' if header[:content_disposition].respond_to?(:disposition_type)
|
|
39
35
|
end
|
|
40
|
-
|
|
36
|
+
|
|
41
37
|
def add_required_fields
|
|
42
38
|
super
|
|
43
39
|
add_content_id if !has_content_id? && inline?
|
|
@@ -46,15 +42,15 @@ module Mail
|
|
|
46
42
|
def add_required_message_fields
|
|
47
43
|
# Override so we don't add Date, MIME-Version, or Message-ID.
|
|
48
44
|
end
|
|
49
|
-
|
|
45
|
+
|
|
50
46
|
def delivery_status_report_part?
|
|
51
47
|
(main_type =~ /message/i && sub_type =~ /delivery-status/i) && body =~ /Status:/
|
|
52
48
|
end
|
|
53
|
-
|
|
49
|
+
|
|
54
50
|
def delivery_status_data
|
|
55
51
|
delivery_status_report_part? ? parse_delivery_status_report : {}
|
|
56
52
|
end
|
|
57
|
-
|
|
53
|
+
|
|
58
54
|
def bounced?
|
|
59
55
|
if action.is_a?(Array)
|
|
60
56
|
!!(action.first =~ /failed/i)
|
|
@@ -62,18 +58,18 @@ module Mail
|
|
|
62
58
|
!!(action =~ /failed/i)
|
|
63
59
|
end
|
|
64
60
|
end
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
|
|
62
|
+
|
|
67
63
|
# Either returns the action if the message has just a single report, or an
|
|
68
64
|
# array of all the actions, one for each report
|
|
69
65
|
def action
|
|
70
66
|
get_return_values('action')
|
|
71
67
|
end
|
|
72
|
-
|
|
68
|
+
|
|
73
69
|
def final_recipient
|
|
74
70
|
get_return_values('final-recipient')
|
|
75
71
|
end
|
|
76
|
-
|
|
72
|
+
|
|
77
73
|
def error_status
|
|
78
74
|
get_return_values('status')
|
|
79
75
|
end
|
|
@@ -81,17 +77,17 @@ module Mail
|
|
|
81
77
|
def diagnostic_code
|
|
82
78
|
get_return_values('diagnostic-code')
|
|
83
79
|
end
|
|
84
|
-
|
|
80
|
+
|
|
85
81
|
def remote_mta
|
|
86
82
|
get_return_values('remote-mta')
|
|
87
83
|
end
|
|
88
|
-
|
|
84
|
+
|
|
89
85
|
def retryable?
|
|
90
86
|
!(error_status =~ /^5/)
|
|
91
87
|
end
|
|
92
88
|
|
|
93
89
|
private
|
|
94
|
-
|
|
90
|
+
|
|
95
91
|
def get_return_values(key)
|
|
96
92
|
if delivery_status_data[key].is_a?(Array)
|
|
97
93
|
delivery_status_data[key].map { |a| a.value }
|
|
@@ -101,10 +97,10 @@ module Mail
|
|
|
101
97
|
nil
|
|
102
98
|
end
|
|
103
99
|
end
|
|
104
|
-
|
|
100
|
+
|
|
105
101
|
# A part may not have a header.... so, just init a body if no header
|
|
106
102
|
def parse_message
|
|
107
|
-
header_part, body_part = raw_source.split(/#{Constants::
|
|
103
|
+
header_part, body_part = raw_source.split(/#{Constants::LAX_CRLF}#{Constants::WSP}*#{Constants::LAX_CRLF}/m, 2)
|
|
108
104
|
if header_part =~ Constants::HEADER_LINE
|
|
109
105
|
self.header = header_part
|
|
110
106
|
self.body = body_part
|
|
@@ -113,11 +109,11 @@ module Mail
|
|
|
113
109
|
self.body = raw_source
|
|
114
110
|
end
|
|
115
111
|
end
|
|
116
|
-
|
|
112
|
+
|
|
117
113
|
def parse_delivery_status_report
|
|
118
114
|
@delivery_status_data ||= Header.new(body.to_s.gsub("\r\n\r\n", "\r\n"))
|
|
119
115
|
end
|
|
120
116
|
|
|
121
117
|
end
|
|
122
|
-
|
|
118
|
+
|
|
123
119
|
end
|
data/lib/mail/parts_list.rb
CHANGED
|
@@ -44,6 +44,63 @@ module Mail
|
|
|
44
44
|
raise NoMethodError, "#collect! is not defined, please call #collect and create a new PartsList"
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
def inspect_structure(parent_id = '')
|
|
48
|
+
enum_for(:map).with_index { |part, i|
|
|
49
|
+
i = i + 1 # Use 1-based indexes since this is for humans to read
|
|
50
|
+
id = parent_id.empty? ? "#{i}" : "#{parent_id}.#{i}"
|
|
51
|
+
if part.content_type == "message/rfc822"
|
|
52
|
+
sub_list = Mail.new(part.body).parts
|
|
53
|
+
else
|
|
54
|
+
sub_list = part.parts
|
|
55
|
+
end
|
|
56
|
+
id + '. ' + part.inspect +
|
|
57
|
+
if sub_list.any?
|
|
58
|
+
"\n" + sub_list.inspect_structure(id)
|
|
59
|
+
end.to_s
|
|
60
|
+
}.join("\n")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def recursive_each(&block)
|
|
64
|
+
each do |part|
|
|
65
|
+
if part.content_type == "message/rfc822"
|
|
66
|
+
sub_list = Mail.new(part.body).parts
|
|
67
|
+
else
|
|
68
|
+
sub_list = part.parts
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
yield part
|
|
72
|
+
|
|
73
|
+
sub_list.recursive_each(&block)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def recursive_size
|
|
78
|
+
i = 0
|
|
79
|
+
recursive_each {|p| i += 1 }
|
|
80
|
+
i
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def recursive_delete_if
|
|
84
|
+
delete_if { |part|
|
|
85
|
+
if part.content_type == "message/rfc822"
|
|
86
|
+
sub_list = Mail.new(part.body).parts
|
|
87
|
+
else
|
|
88
|
+
sub_list = part.parts
|
|
89
|
+
end
|
|
90
|
+
(yield part).tap {
|
|
91
|
+
if sub_list.any?
|
|
92
|
+
sub_list.recursive_delete_if {|part| yield part }
|
|
93
|
+
end
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def delete_attachments
|
|
99
|
+
recursive_delete_if { |part|
|
|
100
|
+
part.attachment?
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
|
|
47
104
|
def sort
|
|
48
105
|
self.class.new(@parts.sort)
|
|
49
106
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mail
|
|
4
|
+
class SmtpEnvelope #:nodoc:
|
|
5
|
+
# Reasonable cap on address length to avoid SMTP line length
|
|
6
|
+
# overflow on old SMTP servers.
|
|
7
|
+
MAX_ADDRESS_BYTESIZE = 2000
|
|
8
|
+
|
|
9
|
+
attr_reader :from, :to, :message
|
|
10
|
+
|
|
11
|
+
def initialize(mail)
|
|
12
|
+
self.from = mail.smtp_envelope_from
|
|
13
|
+
self.to = mail.smtp_envelope_to
|
|
14
|
+
self.message = mail.encoded
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def from=(addr)
|
|
18
|
+
if Utilities.blank? addr
|
|
19
|
+
raise ArgumentError, "SMTP From address may not be blank: #{addr.inspect}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@from = validate_addr 'From', addr
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to=(addr)
|
|
26
|
+
if Utilities.blank?(addr)
|
|
27
|
+
raise ArgumentError, "SMTP To address may not be blank: #{addr.inspect}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@to = Array(addr).map do |addr|
|
|
31
|
+
validate_addr 'To', addr
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def message=(message)
|
|
36
|
+
if Utilities.blank?(message)
|
|
37
|
+
raise ArgumentError, 'SMTP message may not be blank'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@message = message
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
def validate_addr(addr_name, addr)
|
|
46
|
+
if addr.bytesize > MAX_ADDRESS_BYTESIZE
|
|
47
|
+
raise ArgumentError, "SMTP #{addr_name} address may not exceed #{MAX_ADDRESS_BYTESIZE} bytes: #{addr.inspect}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if /[\r\n]/.match?(addr)
|
|
51
|
+
raise ArgumentError, "SMTP #{addr_name} address may not contain CR or LF line breaks: #{addr.inspect}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
addr
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|