mail 2.7.1 → 2.8.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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/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 +46 -64
- 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 +3 -3
- 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 +3 -3
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +0 -20
- metadata +74 -21
- 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;
|
@@ -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
|