mail 2.7.1 → 2.8.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 +4 -4
- data/README.md +45 -28
- data/lib/mail/attachments_list.rb +2 -5
- data/lib/mail/body.rb +24 -47
- data/lib/mail/check_delivery_params.rb +21 -16
- 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.rb +30 -59
- data/lib/mail/envelope.rb +11 -14
- data/lib/mail/field.rb +37 -53
- data/lib/mail/field_list.rb +60 -7
- data/lib/mail/fields/bcc_field.rb +34 -52
- data/lib/mail/fields/cc_field.rb +28 -49
- data/lib/mail/fields/comments_field.rb +27 -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 +7 -14
- data/lib/mail/fields/content_disposition_field.rb +13 -38
- data/lib/mail/fields/content_id_field.rb +24 -51
- data/lib/mail/fields/content_location_field.rb +11 -25
- data/lib/mail/fields/content_transfer_encoding_field.rb +31 -31
- data/lib/mail/fields/content_type_field.rb +46 -71
- data/lib/mail/fields/date_field.rb +23 -51
- data/lib/mail/fields/from_field.rb +28 -49
- data/lib/mail/fields/in_reply_to_field.rb +38 -49
- data/lib/mail/fields/keywords_field.rb +18 -31
- data/lib/mail/fields/message_id_field.rb +25 -71
- data/lib/mail/fields/mime_version_field.rb +19 -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 +5 -6
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +12 -10
- data/lib/mail/fields/received_field.rb +43 -57
- data/lib/mail/fields/references_field.rb +35 -49
- data/lib/mail/fields/reply_to_field.rb +28 -49
- data/lib/mail/fields/resent_bcc_field.rb +28 -49
- data/lib/mail/fields/resent_cc_field.rb +28 -49
- data/lib/mail/fields/resent_date_field.rb +5 -29
- data/lib/mail/fields/resent_from_field.rb +28 -49
- data/lib/mail/fields/resent_message_id_field.rb +5 -29
- data/lib/mail/fields/resent_sender_field.rb +27 -56
- data/lib/mail/fields/resent_to_field.rb +28 -49
- data/lib/mail/fields/return_path_field.rb +50 -54
- data/lib/mail/fields/sender_field.rb +34 -55
- data/lib/mail/fields/structured_field.rb +3 -30
- data/lib/mail/fields/subject_field.rb +9 -11
- data/lib/mail/fields/to_field.rb +28 -49
- data/lib/mail/fields/unstructured_field.rb +16 -48
- data/lib/mail/header.rb +69 -110
- data/lib/mail/matchers/attachment_matchers.rb +15 -0
- data/lib/mail/message.rb +52 -66
- data/lib/mail/multibyte/chars.rb +8 -166
- 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 +11 -10
- 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 +25 -9
- data/lib/mail/network/delivery_methods/smtp_connection.rb +3 -12
- data/lib/mail/network/delivery_methods/test_mailer.rb +4 -2
- data/lib/mail/network/retriever_methods/base.rb +8 -8
- data/lib/mail/network/retriever_methods/imap.rb +2 -2
- data/lib/mail/network/retriever_methods/pop3.rb +2 -2
- data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
- data/lib/mail/parsers/address_lists_parser.rb +33070 -33064
- data/lib/mail/parsers/address_lists_parser.rl +7 -0
- data/lib/mail/parsers/content_disposition_parser.rb +833 -827
- data/lib/mail/parsers/content_disposition_parser.rl +7 -0
- data/lib/mail/parsers/content_location_parser.rb +770 -764
- data/lib/mail/parsers/content_location_parser.rl +7 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +474 -468
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +7 -0
- data/lib/mail/parsers/content_type_parser.rb +971 -965
- data/lib/mail/parsers/content_type_parser.rl +7 -0
- data/lib/mail/parsers/date_time_parser.rb +838 -832
- data/lib/mail/parsers/date_time_parser.rl +7 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3623 -3529
- data/lib/mail/parsers/envelope_from_parser.rl +7 -0
- data/lib/mail/parsers/message_ids_parser.rb +5107 -2800
- data/lib/mail/parsers/message_ids_parser.rl +12 -1
- data/lib/mail/parsers/mime_version_parser.rb +463 -457
- data/lib/mail/parsers/mime_version_parser.rl +7 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +836 -830
- data/lib/mail/parsers/phrase_lists_parser.rl +8 -1
- data/lib/mail/parsers/received_parser.rb +8688 -8682
- data/lib/mail/parsers/received_parser.rl +7 -0
- data/lib/mail/parsers/rfc5322.rl +28 -13
- data/lib/mail/parsers.rb +11 -17
- data/lib/mail/part.rb +5 -9
- data/lib/mail/parts_list.rb +57 -0
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +307 -69
- data/lib/mail/version.rb +2 -2
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +3 -20
- metadata +72 -18
- 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;
|
@@ -82,3 +85,7 @@ module Mail::Parsers
|
|
82
85
|
end
|
83
86
|
end
|
84
87
|
end
|
88
|
+
|
89
|
+
ensure
|
90
|
+
$VERBOSE = original_verbose
|
91
|
+
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,8 +1,10 @@
|
|
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
|
@@ -19,15 +21,9 @@ module Mail
|
|
19
21
|
header.has_content_id?
|
20
22
|
end
|
21
23
|
|
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
|
-
|
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
|
@@ -104,7 +100,7 @@ module Mail
|
|
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
|
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]/ =~ 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
|