mail 2.6.3 → 2.6.4.rc1
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/CHANGELOG.rdoc +22 -0
- data/Gemfile +1 -4
- data/MIT-LICENSE +1 -1
- data/README.md +38 -2
- data/Rakefile +2 -2
- data/lib/mail.rb +8 -2
- data/lib/mail/body.rb +4 -4
- data/lib/mail/check_delivery_params.rb +3 -3
- data/lib/mail/constants.rb +2 -1
- data/lib/mail/core_extensions/nil.rb +0 -6
- data/lib/mail/core_extensions/string.rb +0 -6
- data/lib/mail/elements/address.rb +7 -7
- data/lib/mail/encodings.rb +25 -28
- data/lib/mail/encodings/8bit.rb +5 -0
- data/lib/mail/encodings/base64.rb +5 -0
- data/lib/mail/encodings/quoted_printable.rb +6 -1
- data/lib/mail/encodings/transfer_encoding.rb +26 -17
- data/lib/mail/field.rb +18 -4
- data/lib/mail/fields/bcc_field.rb +14 -3
- data/lib/mail/fields/cc_field.rb +0 -1
- data/lib/mail/fields/common/common_address.rb +7 -7
- data/lib/mail/fields/common/common_date.rb +1 -1
- data/lib/mail/fields/common/common_field.rb +1 -1
- data/lib/mail/fields/common/common_message_id.rb +2 -2
- data/lib/mail/fields/content_disposition_field.rb +11 -11
- 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 +1 -1
- data/lib/mail/fields/from_field.rb +0 -1
- data/lib/mail/fields/keywords_field.rb +1 -2
- data/lib/mail/fields/message_id_field.rb +1 -1
- data/lib/mail/fields/mime_version_field.rb +2 -2
- data/lib/mail/fields/received_field.rb +3 -3
- data/lib/mail/fields/reply_to_field.rb +0 -1
- data/lib/mail/fields/resent_bcc_field.rb +0 -1
- data/lib/mail/fields/resent_cc_field.rb +0 -1
- data/lib/mail/fields/resent_date_field.rb +1 -1
- data/lib/mail/fields/resent_from_field.rb +0 -1
- data/lib/mail/fields/resent_sender_field.rb +0 -1
- data/lib/mail/fields/resent_to_field.rb +0 -1
- data/lib/mail/fields/return_path_field.rb +0 -1
- data/lib/mail/fields/sender_field.rb +0 -1
- data/lib/mail/fields/to_field.rb +0 -1
- data/lib/mail/fields/unstructured_field.rb +1 -1
- data/lib/mail/header.rb +3 -3
- data/lib/mail/matchers/attachment_matchers.rb +28 -0
- data/lib/mail/matchers/has_sent_mail.rb +30 -7
- data/lib/mail/message.rb +15 -21
- data/lib/mail/multibyte/unicode.rb +20 -16
- data/lib/mail/parsers/address_lists_parser.rb +1 -1
- data/lib/mail/parsers/content_disposition_parser.rb +1 -1
- data/lib/mail/parsers/content_location_parser.rb +1 -1
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +1 -1
- data/lib/mail/parsers/envelope_from_parser.rb +1 -1
- data/lib/mail/parsers/message_ids_parser.rb +1 -1
- data/lib/mail/parsers/mime_version_parser.rb +1 -1
- data/lib/mail/part.rb +4 -2
- data/lib/mail/parts_list.rb +25 -8
- data/lib/mail/utilities.rb +15 -0
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +2 -2
- data/lib/mail/version_specific/ruby_1_8.rb +10 -4
- data/lib/mail/version_specific/ruby_1_9.rb +39 -10
- metadata +8 -8
- data/lib/mail/core_extensions/object.rb +0 -13
@@ -23,30 +23,39 @@ module Mail
|
|
23
23
|
raise "Unimplemented"
|
24
24
|
end
|
25
25
|
|
26
|
+
def self.compatible_input?(str)
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
26
30
|
def self.to_s
|
27
31
|
self::NAME
|
28
32
|
end
|
29
33
|
|
30
34
|
def self.get_best_compatible(source_encoding, str)
|
31
|
-
if self.can_transport?
|
32
|
-
|
35
|
+
if self.can_transport?(source_encoding) && self.compatible_input?(str)
|
36
|
+
source_encoding
|
33
37
|
else
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
38
|
+
choices = Encodings.get_all.select do |enc|
|
39
|
+
self.can_transport?(enc) && enc.can_encode?(source_encoding)
|
40
|
+
end
|
41
|
+
|
42
|
+
best = nil
|
43
|
+
best_cost = nil
|
44
|
+
|
45
|
+
choices.each do |enc|
|
46
|
+
# If the current choice cannot be transported safely,
|
47
|
+
# give priority to other choices but allow it to be used as a fallback.
|
48
|
+
this_cost = enc.cost(str) if enc.compatible_input?(str)
|
49
|
+
|
50
|
+
if !best_cost || (this_cost && this_cost < best_cost)
|
51
|
+
best_cost = this_cost
|
52
|
+
best = enc
|
53
|
+
elsif this_cost == best_cost
|
54
|
+
best = enc if enc::PRIORITY < best::PRIORITY
|
48
55
|
end
|
49
|
-
|
56
|
+
end
|
57
|
+
|
58
|
+
best
|
50
59
|
end
|
51
60
|
end
|
52
61
|
|
data/lib/mail/field.rb
CHANGED
@@ -114,11 +114,11 @@ module Mail
|
|
114
114
|
def initialize(name, value = nil, charset = 'utf-8')
|
115
115
|
case
|
116
116
|
when name.index(COLON) # Field.new("field-name: field data")
|
117
|
-
@charset =
|
117
|
+
@charset = Utilities.blank?(value) ? charset : value
|
118
118
|
@name = name[FIELD_PREFIX]
|
119
119
|
@raw_value = name
|
120
120
|
@value = nil
|
121
|
-
when
|
121
|
+
when Utilities.blank?(value) # Field.new("field-name")
|
122
122
|
@name = name
|
123
123
|
@value = nil
|
124
124
|
@raw_value = nil
|
@@ -168,15 +168,19 @@ module Mail
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def same( other )
|
171
|
+
return false unless other.kind_of?(self.class)
|
171
172
|
match_to_s(other.name, self.name)
|
172
173
|
end
|
173
174
|
|
175
|
+
def ==( other )
|
176
|
+
return false unless other.kind_of?(self.class)
|
177
|
+
match_to_s(other.name, self.name) && match_to_s(other.value, self.value)
|
178
|
+
end
|
179
|
+
|
174
180
|
def responsible_for?( val )
|
175
181
|
name.to_s.casecmp(val.to_s) == 0
|
176
182
|
end
|
177
183
|
|
178
|
-
alias_method :==, :same
|
179
|
-
|
180
184
|
def <=>( other )
|
181
185
|
self.field_order_id <=> other.field_order_id
|
182
186
|
end
|
@@ -189,6 +193,16 @@ module Mail
|
|
189
193
|
field.send(name, *args, &block)
|
190
194
|
end
|
191
195
|
|
196
|
+
if RUBY_VERSION >= '1.9.2'
|
197
|
+
def respond_to_missing?(method_name, include_private)
|
198
|
+
field.respond_to?(method_name, include_private) || super
|
199
|
+
end
|
200
|
+
else
|
201
|
+
def respond_to?(method_name, include_private = false)
|
202
|
+
field.respond_to?(method_name, include_private) || super
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
192
206
|
FIELD_ORDER = %w[ return-path received
|
193
207
|
resent-date resent-from resent-sender resent-to
|
194
208
|
resent-cc resent-bcc resent-message-id
|
@@ -39,13 +39,24 @@ module Mail
|
|
39
39
|
def initialize(value = '', charset = 'utf-8')
|
40
40
|
@charset = charset
|
41
41
|
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
42
|
-
self.parse
|
43
42
|
self
|
44
43
|
end
|
45
44
|
|
46
|
-
|
45
|
+
def include_in_headers=(include_in_headers)
|
46
|
+
@include_in_headers = include_in_headers
|
47
|
+
end
|
48
|
+
|
49
|
+
def include_in_headers
|
50
|
+
defined?(@include_in_headers) ? @include_in_headers : self.include_in_headers = false
|
51
|
+
end
|
52
|
+
|
53
|
+
# Bcc field should not be :encoded by default
|
47
54
|
def encoded
|
48
|
-
|
55
|
+
if include_in_headers
|
56
|
+
do_encode(CAPITALIZED_FIELD)
|
57
|
+
else
|
58
|
+
''
|
59
|
+
end
|
49
60
|
end
|
50
61
|
|
51
62
|
def decoded
|
data/lib/mail/fields/cc_field.rb
CHANGED
@@ -5,7 +5,7 @@ module Mail
|
|
5
5
|
module CommonAddress # :nodoc:
|
6
6
|
|
7
7
|
def parse(val = value)
|
8
|
-
unless
|
8
|
+
unless Utilities.blank?(val)
|
9
9
|
@address_list = AddressList.new(encode_if_needed(val))
|
10
10
|
else
|
11
11
|
nil
|
@@ -84,10 +84,10 @@ module Mail
|
|
84
84
|
case
|
85
85
|
when val.nil?
|
86
86
|
raise ArgumentError, "Need to pass an address to <<"
|
87
|
-
when
|
87
|
+
when Utilities.blank?(val)
|
88
88
|
parse(encoded)
|
89
89
|
else
|
90
|
-
self.value = [self.value, val].reject {|a|
|
90
|
+
self.value = [self.value, val].reject {|a| Utilities.blank?(a) }.join(", ")
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -99,22 +99,22 @@ module Mail
|
|
99
99
|
private
|
100
100
|
|
101
101
|
def do_encode(field_name)
|
102
|
-
return '' if
|
102
|
+
return '' if Utilities.blank?(value)
|
103
103
|
address_array = address_list.addresses.reject { |a| encoded_group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
|
104
104
|
address_text = address_array.join(", \r\n\s")
|
105
105
|
group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.encoded }.join(", \r\n\s")};" }
|
106
106
|
group_text = group_array.join(" \r\n\s")
|
107
|
-
return_array = [address_text, group_text].reject { |a|
|
107
|
+
return_array = [address_text, group_text].reject { |a| Utilities.blank?(a) }
|
108
108
|
"#{field_name}: #{return_array.join(", \r\n\s")}\r\n"
|
109
109
|
end
|
110
110
|
|
111
111
|
def do_decode
|
112
|
-
return nil if
|
112
|
+
return nil if Utilities.blank?(value)
|
113
113
|
address_array = address_list.addresses.reject { |a| decoded_group_addresses.include?(a.decoded) }.map { |a| a.decoded }
|
114
114
|
address_text = address_array.join(", ")
|
115
115
|
group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.decoded }.join(", ")};" }
|
116
116
|
group_text = group_array.join(" ")
|
117
|
-
return_array = [address_text, group_text].reject { |a|
|
117
|
+
return_array = [address_text, group_text].reject { |a| Utilities.blank?(a) }
|
118
118
|
return_array.join(", ")
|
119
119
|
end
|
120
120
|
|
@@ -2,11 +2,11 @@
|
|
2
2
|
module Mail
|
3
3
|
module CommonMessageId # :nodoc:
|
4
4
|
def element
|
5
|
-
@element ||= Mail::MessageIdsElement.new(value) unless
|
5
|
+
@element ||= Mail::MessageIdsElement.new(value) unless Utilities.blank?(value)
|
6
6
|
end
|
7
7
|
|
8
8
|
def parse(val = value)
|
9
|
-
unless
|
9
|
+
unless Utilities.blank?(val)
|
10
10
|
@element = Mail::MessageIdsElement.new(val)
|
11
11
|
else
|
12
12
|
nil
|
@@ -3,10 +3,10 @@ require 'mail/fields/common/parameter_hash'
|
|
3
3
|
|
4
4
|
module Mail
|
5
5
|
class ContentDispositionField < StructuredField
|
6
|
-
|
6
|
+
|
7
7
|
FIELD_NAME = 'content-disposition'
|
8
8
|
CAPITALIZED_FIELD = 'Content-Disposition'
|
9
|
-
|
9
|
+
|
10
10
|
def initialize(value = nil, charset = 'utf-8')
|
11
11
|
self.charset = charset
|
12
12
|
ensure_filename_quoted(value)
|
@@ -14,13 +14,13 @@ module Mail
|
|
14
14
|
self.parse
|
15
15
|
self
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def parse(val = value)
|
19
|
-
unless
|
19
|
+
unless Utilities.blank?(val)
|
20
20
|
@element = Mail::ContentDispositionElement.new(val)
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def element
|
25
25
|
@element ||= Mail::ContentDispositionElement.new(value)
|
26
26
|
end
|
@@ -28,20 +28,20 @@ module Mail
|
|
28
28
|
def disposition_type
|
29
29
|
element.disposition_type
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def parameters
|
33
33
|
@parameters = ParameterHash.new
|
34
|
-
element.parameters.each { |p| @parameters.merge!(p) }
|
34
|
+
element.parameters.each { |p| @parameters.merge!(p) } unless element.parameters.nil?
|
35
35
|
@parameters
|
36
36
|
end
|
37
37
|
|
38
38
|
def filename
|
39
39
|
case
|
40
|
-
when !parameters['filename']
|
40
|
+
when !Utilities.blank?(parameters['filename'])
|
41
41
|
@filename = parameters['filename']
|
42
|
-
when !parameters['name']
|
42
|
+
when !Utilities.blank?(parameters['name'])
|
43
43
|
@filename = parameters['name']
|
44
|
-
else
|
44
|
+
else
|
45
45
|
@filename = nil
|
46
46
|
end
|
47
47
|
@filename
|
@@ -56,7 +56,7 @@ module Mail
|
|
56
56
|
end
|
57
57
|
"#{CAPITALIZED_FIELD}: #{disposition_type}" + p
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
def decoded
|
61
61
|
if parameters.length > 0
|
62
62
|
p = "; #{parameters.decoded}"
|
@@ -11,7 +11,7 @@ module Mail
|
|
11
11
|
def initialize(value = nil, charset = 'utf-8')
|
12
12
|
self.charset = charset
|
13
13
|
@uniq = 1
|
14
|
-
if
|
14
|
+
if Utilities.blank?(value)
|
15
15
|
value = generate_content_id
|
16
16
|
else
|
17
17
|
value = strip_field(FIELD_NAME, value)
|
@@ -22,7 +22,7 @@ module Mail
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def parse(val = value)
|
25
|
-
unless
|
25
|
+
unless Utilities.blank?(val)
|
26
26
|
@element = Mail::MessageIdsElement.new(val)
|
27
27
|
end
|
28
28
|
end
|
@@ -10,12 +10,11 @@ module Mail
|
|
10
10
|
def initialize(value = nil, charset = 'utf-8')
|
11
11
|
self.charset = charset
|
12
12
|
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
13
|
-
self.parse
|
14
13
|
self
|
15
14
|
end
|
16
15
|
|
17
16
|
def parse(val = value)
|
18
|
-
unless
|
17
|
+
unless Utilities.blank?(val)
|
19
18
|
@phrase_list ||= PhraseList.new(value)
|
20
19
|
end
|
21
20
|
end
|
@@ -10,7 +10,7 @@ module Mail
|
|
10
10
|
|
11
11
|
def initialize(value = nil, charset = 'utf-8')
|
12
12
|
self.charset = charset
|
13
|
-
if
|
13
|
+
if Utilities.blank?(value)
|
14
14
|
value = '1.0'
|
15
15
|
end
|
16
16
|
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
@@ -20,7 +20,7 @@ module Mail
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def parse(val = value)
|
23
|
-
unless
|
23
|
+
unless Utilities.blank?(val)
|
24
24
|
@element = Mail::MimeVersionElement.new(val)
|
25
25
|
end
|
26
26
|
end
|
@@ -34,7 +34,7 @@ module Mail
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def parse(val = value)
|
37
|
-
unless
|
37
|
+
unless Utilities.blank?(val)
|
38
38
|
@element = Mail::ReceivedElement.new(val)
|
39
39
|
end
|
40
40
|
end
|
@@ -56,7 +56,7 @@ module Mail
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def encoded
|
59
|
-
if
|
59
|
+
if Utilities.blank?(value)
|
60
60
|
"#{CAPITALIZED_FIELD}: \r\n"
|
61
61
|
else
|
62
62
|
"#{CAPITALIZED_FIELD}: #{info}; #{formatted_date}\r\n"
|
@@ -64,7 +64,7 @@ module Mail
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def decoded
|
67
|
-
if
|
67
|
+
if Utilities.blank?(value)
|
68
68
|
""
|
69
69
|
else
|
70
70
|
"#{info}; #{formatted_date}"
|