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
@@ -14,9 +14,8 @@ module Mail
|
|
14
14
|
|
15
15
|
def value=(value)
|
16
16
|
@length = nil
|
17
|
-
@tree = nil
|
18
17
|
@element = nil
|
19
|
-
@value = value
|
18
|
+
@value = value.is_a?(Array) ? value : value.to_s
|
20
19
|
end
|
21
20
|
|
22
21
|
def value
|
@@ -41,14 +40,6 @@ module Mail
|
|
41
40
|
|
42
41
|
private
|
43
42
|
|
44
|
-
def strip_field(field_name, value)
|
45
|
-
if value.is_a?(Array)
|
46
|
-
value
|
47
|
-
else
|
48
|
-
value.to_s.sub(/\A#{field_name}:\s+/i, EMPTY)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
43
|
FILENAME_RE = /\b(filename|name)=([^;"\r\n]+\s[^;"\r\n]+)/
|
53
44
|
def ensure_filename_quoted(value)
|
54
45
|
if value.is_a?(String)
|
@@ -11,7 +11,7 @@ module Mail
|
|
11
11
|
def initialize(value = nil, charset = 'utf-8')
|
12
12
|
self.charset = charset
|
13
13
|
value = ensure_filename_quoted(value)
|
14
|
-
super(CAPITALIZED_FIELD,
|
14
|
+
super(CAPITALIZED_FIELD, value, charset)
|
15
15
|
self.parse
|
16
16
|
self
|
17
17
|
end
|
@@ -38,9 +38,9 @@ module Mail
|
|
38
38
|
|
39
39
|
def filename
|
40
40
|
case
|
41
|
-
when
|
41
|
+
when parameters['filename']
|
42
42
|
@filename = parameters['filename']
|
43
|
-
when
|
43
|
+
when parameters['name']
|
44
44
|
@filename = parameters['name']
|
45
45
|
else
|
46
46
|
@filename = nil
|
@@ -15,9 +15,9 @@ module Mail
|
|
15
15
|
if Utilities.blank?(value)
|
16
16
|
value = generate_content_id
|
17
17
|
else
|
18
|
-
value =
|
18
|
+
value = value.to_s
|
19
19
|
end
|
20
|
-
super(CAPITALIZED_FIELD,
|
20
|
+
super(CAPITALIZED_FIELD, value, charset)
|
21
21
|
self.parse
|
22
22
|
self
|
23
23
|
end
|
@@ -13,7 +13,7 @@ module Mail
|
|
13
13
|
self.charset = charset
|
14
14
|
value = '7bit' if value.to_s =~ /7-?bits?/i
|
15
15
|
value = '8bit' if value.to_s =~ /8-?bits?/i
|
16
|
-
super(CAPITALIZED_FIELD,
|
16
|
+
super(CAPITALIZED_FIELD, value, charset)
|
17
17
|
self.parse
|
18
18
|
self
|
19
19
|
end
|
@@ -37,9 +37,8 @@ module Mail
|
|
37
37
|
if Utilities.blank?(value)
|
38
38
|
value = ::DateTime.now.strftime('%a, %d %b %Y %H:%M:%S %z')
|
39
39
|
else
|
40
|
-
value =
|
41
|
-
value.
|
42
|
-
value = ::DateTime.parse(value.to_s.squeeze(" ")).strftime('%a, %d %b %Y %H:%M:%S %z')
|
40
|
+
value = value.to_s.gsub(/\(.*?\)/, '').squeeze(' ')
|
41
|
+
value = ::DateTime.parse(value).strftime('%a, %d %b %Y %H:%M:%S %z')
|
43
42
|
end
|
44
43
|
super(CAPITALIZED_FIELD, value, charset)
|
45
44
|
rescue ArgumentError => e
|
@@ -40,7 +40,7 @@ module Mail
|
|
40
40
|
def initialize(value = nil, charset = 'utf-8')
|
41
41
|
self.charset = charset
|
42
42
|
value = value.join("\r\n\s") if value.is_a?(Array)
|
43
|
-
super(CAPITALIZED_FIELD,
|
43
|
+
super(CAPITALIZED_FIELD, value, charset)
|
44
44
|
self.parse
|
45
45
|
self
|
46
46
|
end
|
@@ -40,7 +40,7 @@ module Mail
|
|
40
40
|
def initialize(value = nil, charset = 'utf-8')
|
41
41
|
self.charset = charset
|
42
42
|
value = value.join("\r\n\s") if value.is_a?(Array)
|
43
|
-
super(CAPITALIZED_FIELD,
|
43
|
+
super(CAPITALIZED_FIELD, value, charset)
|
44
44
|
self.parse
|
45
45
|
self
|
46
46
|
end
|
@@ -17,7 +17,6 @@ module Mail
|
|
17
17
|
if Utilities.blank?(value)
|
18
18
|
value = ::DateTime.now.strftime('%a, %d %b %Y %H:%M:%S %z')
|
19
19
|
else
|
20
|
-
value = strip_field(FIELD_NAME, value)
|
21
20
|
value = ::DateTime.parse(value.to_s).strftime('%a, %d %b %Y %H:%M:%S %z')
|
22
21
|
end
|
23
22
|
super(CAPITALIZED_FIELD, value, charset)
|
data/lib/mail/fields/to_field.rb
CHANGED
@@ -32,6 +32,12 @@ module Mail
|
|
32
32
|
else
|
33
33
|
# Ensure we are dealing with a string
|
34
34
|
value = value.to_s
|
35
|
+
|
36
|
+
# Mark UTF-8 strings parsed from ASCII-8BIT
|
37
|
+
if value.respond_to?(:force_encoding) && value.encoding == Encoding::ASCII_8BIT
|
38
|
+
utf8 = value.dup.force_encoding(Encoding::UTF_8)
|
39
|
+
value = utf8 if utf8.valid_encoding?
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
43
|
if charset
|
@@ -67,7 +73,11 @@ module Mail
|
|
67
73
|
private
|
68
74
|
|
69
75
|
def do_encode
|
70
|
-
value.
|
76
|
+
if value && !value.empty?
|
77
|
+
"#{wrapped_value}\r\n"
|
78
|
+
else
|
79
|
+
''
|
80
|
+
end
|
71
81
|
end
|
72
82
|
|
73
83
|
def do_decode
|
@@ -148,7 +158,14 @@ module Mail
|
|
148
158
|
first_word = true
|
149
159
|
while !words.empty?
|
150
160
|
break unless word = words.first.dup
|
151
|
-
|
161
|
+
|
162
|
+
# Convert on 1.9+ only since we aren't sure of the current
|
163
|
+
# charset encoding on 1.8. We'd need to track internal/external
|
164
|
+
# charset on each field.
|
165
|
+
if charset && word.respond_to?(:encoding)
|
166
|
+
word = Encodings.transcode_charset(word, word.encoding, charset)
|
167
|
+
end
|
168
|
+
|
152
169
|
word = encode(word) if should_encode
|
153
170
|
word = encode_crlf(word)
|
154
171
|
# Skip to next line if we're going to go past the limit
|
data/lib/mail/header.rb
CHANGED
@@ -50,7 +50,7 @@ module Mail
|
|
50
50
|
# me the example so we can fix it.
|
51
51
|
def initialize(header_text = nil, charset = nil)
|
52
52
|
@charset = charset
|
53
|
-
self.raw_source =
|
53
|
+
self.raw_source = header_text
|
54
54
|
split_header if header_text
|
55
55
|
end
|
56
56
|
|
@@ -93,14 +93,15 @@ module Mail
|
|
93
93
|
# h.fields = ['From: mikel@me.com', 'To: bob@you.com']
|
94
94
|
def fields=(unfolded_fields)
|
95
95
|
@fields = Mail::FieldList.new
|
96
|
-
warn "
|
96
|
+
Kernel.warn "WARNING: More than #{self.class.maximum_amount} header fields; only using the first #{self.class.maximum_amount} and ignoring the rest" if unfolded_fields.length > self.class.maximum_amount
|
97
97
|
unfolded_fields[0..(self.class.maximum_amount-1)].each do |field|
|
98
98
|
|
99
|
-
field = Field.
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
99
|
+
if field = Field.parse(field, charset)
|
100
|
+
if limited_field?(field.name) && (selected = select_field_for(field.name)) && selected.any?
|
101
|
+
selected.first.update(field.name, field.value)
|
102
|
+
else
|
103
|
+
@fields << field
|
104
|
+
end
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
@@ -249,7 +250,7 @@ module Mail
|
|
249
250
|
private
|
250
251
|
|
251
252
|
def raw_source=(val)
|
252
|
-
@raw_source = val
|
253
|
+
@raw_source = ::Mail::Utilities.to_crlf(val).lstrip
|
253
254
|
end
|
254
255
|
|
255
256
|
# Splits an unfolded and line break cleaned header into individual field
|
data/lib/mail/mail.rb
CHANGED
@@ -90,19 +90,11 @@ module Mail
|
|
90
90
|
# Each mail object inherits the default set in Mail.delivery_method, however, on
|
91
91
|
# a per email basis, you can override the method:
|
92
92
|
#
|
93
|
-
# mail.delivery_method :
|
93
|
+
# mail.delivery_method :smtp
|
94
94
|
#
|
95
95
|
# Or you can override the method and pass in settings:
|
96
96
|
#
|
97
|
-
# mail.delivery_method :
|
98
|
-
#
|
99
|
-
# You can also just modify the settings:
|
100
|
-
#
|
101
|
-
# mail.delivery_settings = { :address => 'some.host' }
|
102
|
-
#
|
103
|
-
# The passed in hash is just merged against the defaults with +merge!+ and the result
|
104
|
-
# assigned the mail object. So the above example will change only the :address value
|
105
|
-
# of the global smtp_settings to be 'some.host', keeping all other values
|
97
|
+
# mail.delivery_method :smtp, :address => 'some.host'
|
106
98
|
def self.defaults(&block)
|
107
99
|
Configuration.instance.instance_eval(&block)
|
108
100
|
end
|
@@ -83,6 +83,16 @@ module Mail
|
|
83
83
|
self
|
84
84
|
end
|
85
85
|
|
86
|
+
def with_html(body)
|
87
|
+
@html_part_body = body
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def with_text(body)
|
92
|
+
@text_part_body = body
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
86
96
|
def description
|
87
97
|
result = "send a matching email"
|
88
98
|
result
|
@@ -108,7 +118,7 @@ module Mail
|
|
108
118
|
candidate_deliveries = deliveries
|
109
119
|
modifiers =
|
110
120
|
%w(sender recipients copy_recipients blind_copy_recipients subject
|
111
|
-
subject_matcher body body_matcher having_attachments attachments)
|
121
|
+
subject_matcher body body_matcher html_part_body text_part_body having_attachments attachments)
|
112
122
|
modifiers.each do |modifier_name|
|
113
123
|
next unless instance_variable_defined?("@#{modifier_name}")
|
114
124
|
candidate_deliveries = candidate_deliveries.select{|matching_delivery| self.send("matches_on_#{modifier_name}?", matching_delivery)}
|
@@ -160,6 +170,14 @@ module Mail
|
|
160
170
|
@body_matcher.match delivery.body.raw_source
|
161
171
|
end
|
162
172
|
|
173
|
+
def matches_on_html_part_body?(delivery)
|
174
|
+
delivery.html_part.body == @html_part_body
|
175
|
+
end
|
176
|
+
|
177
|
+
def matches_on_text_part_body?(delivery)
|
178
|
+
delivery.text_part.body == @text_part_body
|
179
|
+
end
|
180
|
+
|
163
181
|
def explain_expectations
|
164
182
|
result = ''
|
165
183
|
result += "from #{@sender} " if instance_variable_defined?('@sender')
|
@@ -170,6 +188,8 @@ module Mail
|
|
170
188
|
result += "with subject matching \"#{@subject_matcher}\" " if instance_variable_defined?('@subject_matcher')
|
171
189
|
result += "with body \"#{@body}\" " if instance_variable_defined?('@body')
|
172
190
|
result += "with body matching \"#{@body_matcher}\" " if instance_variable_defined?('@body_matcher')
|
191
|
+
result += "with a text part matching \"#{@text_part_body}\" " if instance_variable_defined?('@text_part_body')
|
192
|
+
result += "with an HTML part matching \"#{@html_part_body}\" " if instance_variable_defined?('@html_part_body')
|
173
193
|
result
|
174
194
|
end
|
175
195
|
|