mail 2.6.6 → 2.8.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 +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +134 -119
- data/lib/mail/attachments_list.rb +10 -9
- data/lib/mail/body.rb +73 -84
- data/lib/mail/check_delivery_params.rb +28 -21
- data/lib/mail/configuration.rb +2 -0
- data/lib/mail/constants.rb +27 -5
- data/lib/mail/elements/address.rb +53 -47
- data/lib/mail/elements/address_list.rb +11 -19
- data/lib/mail/elements/content_disposition_element.rb +9 -16
- data/lib/mail/elements/content_location_element.rb +6 -11
- data/lib/mail/elements/content_transfer_encoding_element.rb +6 -11
- data/lib/mail/elements/content_type_element.rb +16 -23
- data/lib/mail/elements/date_time_element.rb +7 -15
- data/lib/mail/elements/envelope_from_element.rb +22 -23
- data/lib/mail/elements/message_ids_element.rb +18 -13
- data/lib/mail/elements/mime_version_element.rb +7 -15
- data/lib/mail/elements/phrase_list.rb +12 -10
- data/lib/mail/elements/received_element.rb +27 -19
- data/lib/mail/encodings/7bit.rb +9 -14
- 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 +3 -1
- data/lib/mail/encodings.rb +81 -54
- data/lib/mail/envelope.rb +11 -14
- data/lib/mail/field.rb +119 -98
- 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 +50 -80
- data/lib/mail/fields/date_field.rb +23 -52
- 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 +9 -7
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +13 -11
- 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 -30
- 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 +32 -47
- data/lib/mail/header.rb +71 -110
- data/lib/mail/mail.rb +2 -10
- data/lib/mail/matchers/attachment_matchers.rb +15 -0
- data/lib/mail/matchers/has_sent_mail.rb +21 -1
- data/lib/mail/message.rb +113 -117
- data/lib/mail/multibyte/chars.rb +21 -178
- data/lib/mail/multibyte/unicode.rb +10 -10
- data/lib/mail/multibyte/utils.rb +26 -43
- data/lib/mail/multibyte.rb +55 -16
- 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 +34 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +62 -21
- data/lib/mail/network/delivery_methods/smtp.rb +75 -50
- data/lib/mail/network/delivery_methods/smtp_connection.rb +3 -4
- 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 +20 -7
- data/lib/mail/network/retriever_methods/pop3.rb +5 -3
- data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
- data/lib/mail/network.rb +1 -0
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +33225 -116
- data/lib/mail/parsers/address_lists_parser.rl +179 -0
- data/lib/mail/parsers/content_disposition_parser.rb +882 -49
- data/lib/mail/parsers/content_disposition_parser.rl +89 -0
- data/lib/mail/parsers/content_location_parser.rb +809 -23
- data/lib/mail/parsers/content_location_parser.rl +78 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +509 -21
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
- data/lib/mail/parsers/content_type_parser.rb +1037 -56
- data/lib/mail/parsers/content_type_parser.rl +90 -0
- data/lib/mail/parsers/date_time_parser.rb +877 -25
- data/lib/mail/parsers/date_time_parser.rl +69 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3669 -40
- data/lib/mail/parsers/envelope_from_parser.rl +89 -0
- data/lib/mail/parsers/message_ids_parser.rb +5146 -25
- data/lib/mail/parsers/message_ids_parser.rl +93 -0
- data/lib/mail/parsers/mime_version_parser.rb +497 -26
- data/lib/mail/parsers/mime_version_parser.rl +68 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +870 -22
- data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
- data/lib/mail/parsers/received_parser.rb +8776 -43
- data/lib/mail/parsers/received_parser.rl +91 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
- data/lib/mail/parsers/rfc2045_mime.rl +16 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
- data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
- data/lib/mail/parsers/rfc5322.rl +74 -0
- data/lib/mail/parsers/rfc5322_address.rl +72 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/lib/mail/parsers.rb +11 -25
- data/lib/mail/part.rb +6 -10
- data/lib/mail/parts_list.rb +62 -6
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +343 -74
- data/lib/mail/version.rb +2 -2
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +5 -35
- metadata +111 -66
- data/CHANGELOG.rdoc +0 -803
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -2
- data/Gemfile +0 -14
- data/Rakefile +0 -29
- data/TODO.rdoc +0 -9
- data/lib/mail/core_extensions/smtp.rb +0 -25
- data/lib/mail/core_extensions/string/access.rb +0 -146
- data/lib/mail/core_extensions/string/multibyte.rb +0 -79
- data/lib/mail/core_extensions/string.rb +0 -21
- data/lib/mail/fields/common/address_container.rb +0 -17
- data/lib/mail/fields/common/common_address.rb +0 -136
- data/lib/mail/fields/common/common_date.rb +0 -36
- data/lib/mail/fields/common/common_field.rb +0 -61
- data/lib/mail/fields/common/common_message_id.rb +0 -49
- data/lib/mail/multibyte/exceptions.rb +0 -9
- data/lib/mail/parsers/ragel/common.rl +0 -185
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
- data/lib/mail/parsers/ragel/ruby.rb +0 -40
- data/lib/mail/parsers/ragel.rb +0 -18
- data/lib/mail/version_specific/ruby_1_8.rb +0 -126
- data/lib/mail/version_specific/ruby_1_9.rb +0 -226
@@ -7,17 +7,17 @@ module Mail
|
|
7
7
|
|
8
8
|
PRIORITY = -1
|
9
9
|
|
10
|
+
# And encoding's superclass can always transport it since the
|
11
|
+
# class hierarchy is arranged e.g. Base64 < 7bit < 8bit < Binary.
|
10
12
|
def self.can_transport?(enc)
|
11
|
-
enc
|
12
|
-
if Encodings.defined? enc
|
13
|
-
Encodings.get_encoding(enc).new.is_a? self
|
14
|
-
else
|
15
|
-
false
|
16
|
-
end
|
13
|
+
enc && enc <= self
|
17
14
|
end
|
18
15
|
|
16
|
+
# Override in subclasses to indicate that they can encode text
|
17
|
+
# that couldn't be directly transported, e.g. Base64 has 7bit output,
|
18
|
+
# but it can encode binary.
|
19
19
|
def self.can_encode?(enc)
|
20
|
-
can_transport? enc
|
20
|
+
can_transport? enc
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.cost(str)
|
@@ -32,36 +32,45 @@ module Mail
|
|
32
32
|
self::NAME
|
33
33
|
end
|
34
34
|
|
35
|
-
def self.
|
36
|
-
|
35
|
+
def self.negotiate(message_encoding, source_encoding, str, allowed_encodings = nil)
|
36
|
+
message_encoding = Encodings.get_encoding(message_encoding) || Encodings.get_encoding('8bit')
|
37
|
+
source_encoding = Encodings.get_encoding(source_encoding)
|
38
|
+
|
39
|
+
if message_encoding && source_encoding && message_encoding.can_transport?(source_encoding) && source_encoding.compatible_input?(str)
|
37
40
|
source_encoding
|
38
41
|
else
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
renegotiate(message_encoding, source_encoding, str, allowed_encodings)
|
43
|
+
end
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
|
46
|
+
def self.renegotiate(message_encoding, source_encoding, str, allowed_encodings = nil)
|
47
|
+
encodings = Encodings.get_all.select do |enc|
|
48
|
+
(allowed_encodings.nil? || allowed_encodings.include?(enc)) &&
|
49
|
+
message_encoding.can_transport?(enc) &&
|
50
|
+
enc.can_encode?(source_encoding)
|
51
|
+
end
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
# give priority to other choices but allow it to be used as a fallback.
|
49
|
-
this_cost = enc.cost(str) if enc.compatible_input?(str)
|
53
|
+
lowest_cost(str, encodings)
|
54
|
+
end
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
elsif this_cost == best_cost
|
55
|
-
best = enc if enc::PRIORITY < best::PRIORITY
|
56
|
-
end
|
57
|
-
end
|
56
|
+
def self.lowest_cost(str, encodings)
|
57
|
+
best = nil
|
58
|
+
best_cost = nil
|
58
59
|
|
59
|
-
|
60
|
+
encodings.each do |enc|
|
61
|
+
# If the current choice cannot be transported safely, give priority
|
62
|
+
# to other choices but allow it to be used as a fallback.
|
63
|
+
this_cost = enc.cost(str) if enc.compatible_input?(str)
|
64
|
+
|
65
|
+
if !best_cost || (this_cost && this_cost < best_cost)
|
66
|
+
best_cost = this_cost
|
67
|
+
best = enc
|
68
|
+
elsif this_cost == best_cost
|
69
|
+
best = enc if enc::PRIORITY < best::PRIORITY
|
70
|
+
end
|
60
71
|
end
|
61
|
-
end
|
62
72
|
|
63
|
-
|
64
|
-
self.class.to_s
|
73
|
+
best
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Mail
|
3
3
|
module Encodings
|
4
|
-
|
4
|
+
class UnixToUnix < TransferEncoding
|
5
5
|
NAME = "x-uuencode"
|
6
6
|
|
7
7
|
def self.decode(str)
|
@@ -13,6 +13,8 @@ module Mail
|
|
13
13
|
end
|
14
14
|
|
15
15
|
Encodings.register(NAME, self)
|
16
|
+
Encodings.register("uuencode", self)
|
17
|
+
Encodings.register("x-uue", self)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
data/lib/mail/encodings.rb
CHANGED
@@ -7,7 +7,6 @@ module Mail
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module Encodings
|
10
|
-
|
11
10
|
include Mail::Constants
|
12
11
|
extend Mail::Utilities
|
13
12
|
|
@@ -19,7 +18,7 @@ module Mail
|
|
19
18
|
#
|
20
19
|
# Encodings.register "base64", Mail::Encodings::Base64
|
21
20
|
def Encodings.register(name, cls)
|
22
|
-
|
21
|
+
@transfer_encodings[get_name(name)] = cls
|
23
22
|
end
|
24
23
|
|
25
24
|
# Is the encoding we want defined?
|
@@ -27,8 +26,8 @@ module Mail
|
|
27
26
|
# Example:
|
28
27
|
#
|
29
28
|
# Encodings.defined?(:base64) #=> true
|
30
|
-
def Encodings.defined?(
|
31
|
-
@transfer_encodings.include? get_name(
|
29
|
+
def Encodings.defined?(name)
|
30
|
+
@transfer_encodings.include? get_name(name)
|
32
31
|
end
|
33
32
|
|
34
33
|
# Gets a defined encoding type, QuotedPrintable or Base64 for now.
|
@@ -39,21 +38,21 @@ module Mail
|
|
39
38
|
# Example:
|
40
39
|
#
|
41
40
|
# Encodings.get_encoding(:base64) #=> Mail::Encodings::Base64
|
42
|
-
def Encodings.get_encoding(
|
43
|
-
@transfer_encodings[get_name(
|
41
|
+
def Encodings.get_encoding(name)
|
42
|
+
@transfer_encodings[get_name(name)]
|
44
43
|
end
|
45
44
|
|
46
45
|
def Encodings.get_all
|
47
46
|
@transfer_encodings.values
|
48
47
|
end
|
49
48
|
|
50
|
-
def Encodings.get_name(
|
51
|
-
underscoreize(
|
49
|
+
def Encodings.get_name(name)
|
50
|
+
underscoreize(name).downcase
|
52
51
|
end
|
53
52
|
|
54
53
|
def Encodings.transcode_charset(str, from_charset, to_charset = 'UTF-8')
|
55
54
|
if from_charset
|
56
|
-
|
55
|
+
Utilities.transcode_charset str, from_charset, to_charset
|
57
56
|
else
|
58
57
|
str
|
59
58
|
end
|
@@ -66,8 +65,7 @@ module Mail
|
|
66
65
|
# param_encode_language 'jp'
|
67
66
|
# end
|
68
67
|
#
|
69
|
-
# The character set used for encoding will
|
70
|
-
# Ruby < 1.9 or the encoding on the string passed in.
|
68
|
+
# The character set used for encoding will be the encoding on the string passed in.
|
71
69
|
#
|
72
70
|
# Example:
|
73
71
|
#
|
@@ -79,7 +77,7 @@ module Mail
|
|
79
77
|
when str.ascii_only?
|
80
78
|
str
|
81
79
|
else
|
82
|
-
|
80
|
+
Utilities.param_encode(str)
|
83
81
|
end
|
84
82
|
end
|
85
83
|
|
@@ -93,15 +91,15 @@ module Mail
|
|
93
91
|
# str.encoding #=> 'ISO-8859-1' ## Only on Ruby 1.9
|
94
92
|
# str #=> "This is fun"
|
95
93
|
def Encodings.param_decode(str, encoding)
|
96
|
-
|
94
|
+
Utilities.param_decode(str, encoding)
|
97
95
|
end
|
98
96
|
|
99
97
|
# Decodes or encodes a string as needed for either Base64 or QP encoding types in
|
100
98
|
# the =?<encoding>?[QB]?<string>?=" format.
|
101
99
|
#
|
102
100
|
# The output type needs to be :decode to decode the input string or :encode to
|
103
|
-
# encode the input string. The character set used for encoding will
|
104
|
-
#
|
101
|
+
# encode the input string. The character set used for encoding will be the
|
102
|
+
# encoding on the string passed in.
|
105
103
|
#
|
106
104
|
# On encoding, will only send out Base64 encoded strings.
|
107
105
|
def Encodings.decode_encode(str, output_type)
|
@@ -112,7 +110,7 @@ module Mail
|
|
112
110
|
if str.ascii_only?
|
113
111
|
str
|
114
112
|
else
|
115
|
-
Encodings.b_value_encode(str,
|
113
|
+
Encodings.b_value_encode(str, str.encoding)
|
116
114
|
end
|
117
115
|
end
|
118
116
|
end
|
@@ -146,13 +144,8 @@ module Mail
|
|
146
144
|
output
|
147
145
|
elsif to_encoding
|
148
146
|
begin
|
149
|
-
|
150
|
-
|
151
|
-
else
|
152
|
-
require 'iconv'
|
153
|
-
Iconv.iconv(to_encoding, 'UTF-8', output).first
|
154
|
-
end
|
155
|
-
rescue Iconv::IllegalSequence, Iconv::InvalidEncoding, Errno::EINVAL
|
147
|
+
output.encode(to_encoding)
|
148
|
+
rescue Errno::EINVAL
|
156
149
|
# the 'from' parameter specifies a charset other than what the text
|
157
150
|
# actually is...not much we can do in this case but just return the
|
158
151
|
# unconverted text.
|
@@ -168,21 +161,21 @@ module Mail
|
|
168
161
|
|
169
162
|
def Encodings.address_encode(address, charset = 'utf-8')
|
170
163
|
if address.is_a?(Array)
|
171
|
-
# loop back through for each element
|
172
164
|
address.compact.map { |a| Encodings.address_encode(a, charset) }.join(", ")
|
173
|
-
|
174
|
-
|
175
|
-
encode_non_usascii(address, charset) if address
|
165
|
+
elsif address
|
166
|
+
encode_non_usascii(address, charset)
|
176
167
|
end
|
177
168
|
end
|
178
169
|
|
179
170
|
def Encodings.encode_non_usascii(address, charset)
|
180
171
|
return address if address.ascii_only? or charset.nil?
|
181
|
-
|
182
|
-
# Encode
|
183
|
-
address = address.gsub(/("
|
172
|
+
|
173
|
+
# Encode all strings embedded inside of quotes
|
174
|
+
address = address.gsub(/("[^"]*[^\/]")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
|
175
|
+
|
184
176
|
# Then loop through all remaining items and encode as needed
|
185
177
|
tokens = address.split(/\s/)
|
178
|
+
|
186
179
|
map_with_index(tokens) do |word, i|
|
187
180
|
if word.ascii_only?
|
188
181
|
word
|
@@ -203,12 +196,15 @@ module Mail
|
|
203
196
|
#
|
204
197
|
# Encodings.b_value_encode('This is あ string', 'UTF-8')
|
205
198
|
# #=> "=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?="
|
206
|
-
def Encodings.b_value_encode(
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
199
|
+
def Encodings.b_value_encode(string, encoding = nil)
|
200
|
+
if string.to_s.ascii_only?
|
201
|
+
string
|
202
|
+
else
|
203
|
+
Encodings.each_base64_chunk_byterange(string, 60).map do |chunk|
|
204
|
+
str, encoding = Utilities.b_value_encode(chunk, encoding)
|
205
|
+
"=?#{encoding}?B?#{str.chomp}?="
|
206
|
+
end.join(" ")
|
207
|
+
end
|
212
208
|
end
|
213
209
|
|
214
210
|
# Encode a string with Quoted-Printable Encoding and returns it ready to be inserted
|
@@ -220,7 +216,7 @@ module Mail
|
|
220
216
|
# #=> "=?UTF-8?Q?This_is_=E3=81=82_string?="
|
221
217
|
def Encodings.q_value_encode(encoded_str, encoding = nil)
|
222
218
|
return encoded_str if encoded_str.to_s.ascii_only?
|
223
|
-
string, encoding =
|
219
|
+
string, encoding = Utilities.q_value_encode(encoded_str, encoding)
|
224
220
|
string.gsub!("=\r\n", '') # We already have limited the string to the length we want
|
225
221
|
map_lines(string) do |str|
|
226
222
|
"=?#{encoding}?Q?#{str.chomp.gsub(/ /, '_')}?="
|
@@ -236,7 +232,7 @@ module Mail
|
|
236
232
|
# Encodings.b_value_decode("=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?=")
|
237
233
|
# #=> 'This is あ string'
|
238
234
|
def Encodings.b_value_decode(str)
|
239
|
-
|
235
|
+
Utilities.b_value_decode(str)
|
240
236
|
end
|
241
237
|
|
242
238
|
# Decodes a Quoted-Printable string from the "=?UTF-8?Q?This_is_=E3=81=82_string?=" format
|
@@ -246,11 +242,7 @@ module Mail
|
|
246
242
|
# Encodings.q_value_decode("=?UTF-8?Q?This_is_=E3=81=82_string?=")
|
247
243
|
# #=> 'This is あ string'
|
248
244
|
def Encodings.q_value_decode(str)
|
249
|
-
|
250
|
-
end
|
251
|
-
|
252
|
-
def Encodings.find_encoding(str)
|
253
|
-
RUBY_VERSION >= '1.9' ? str.encoding : $KCODE
|
245
|
+
Utilities.q_value_decode(str)
|
254
246
|
end
|
255
247
|
|
256
248
|
# Gets the encoding type (Q or B) from the string.
|
@@ -258,24 +250,23 @@ module Mail
|
|
258
250
|
str[ENCODED_VALUE, 1]
|
259
251
|
end
|
260
252
|
|
261
|
-
#
|
262
|
-
# encoding (Q or B) can be joined together.
|
253
|
+
# Split header line into proper encoded and unencoded parts.
|
263
254
|
#
|
264
255
|
# String has to be of the format =?<encoding>?[QB]?<string>?=
|
256
|
+
#
|
257
|
+
# Omit unencoded space after an encoded-word.
|
265
258
|
def Encodings.collapse_adjacent_encodings(str)
|
266
259
|
results = []
|
267
|
-
|
260
|
+
last_encoded = nil # Track whether to preserve or drop whitespace
|
261
|
+
|
268
262
|
lines = str.split(FULL_ENCODED_VALUE)
|
269
263
|
lines.each_slice(2) do |unencoded, encoded|
|
270
|
-
if encoded
|
271
|
-
|
272
|
-
|
273
|
-
results.last << encoded
|
274
|
-
else
|
275
|
-
results << unencoded unless unencoded == EMPTY
|
276
|
-
results << encoded
|
264
|
+
if last_encoded = encoded
|
265
|
+
if !Utilities.blank?(unencoded) || (!last_encoded && unencoded != EMPTY)
|
266
|
+
results << unencoded
|
277
267
|
end
|
278
|
-
|
268
|
+
|
269
|
+
results << encoded
|
279
270
|
else
|
280
271
|
results << unencoded
|
281
272
|
end
|
@@ -283,5 +274,41 @@ module Mail
|
|
283
274
|
|
284
275
|
results
|
285
276
|
end
|
277
|
+
|
278
|
+
# Partition the string into bounded-size chunks without splitting
|
279
|
+
# multibyte characters.
|
280
|
+
def Encodings.each_base64_chunk_byterange(str, max_bytesize_per_base64_chunk, &block)
|
281
|
+
raise "size per chunk must be multiple of 4" if (max_bytesize_per_base64_chunk % 4).nonzero?
|
282
|
+
|
283
|
+
if block_given?
|
284
|
+
max_bytesize = ((3 * max_bytesize_per_base64_chunk) / 4.0).floor
|
285
|
+
each_chunk_byterange(str, max_bytesize, &block)
|
286
|
+
else
|
287
|
+
enum_for :each_base64_chunk_byterange, str, max_bytesize_per_base64_chunk
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# Partition the string into bounded-size chunks without splitting
|
292
|
+
# multibyte characters.
|
293
|
+
def Encodings.each_chunk_byterange(str, max_bytesize_per_chunk)
|
294
|
+
return enum_for(:each_chunk_byterange, str, max_bytesize_per_chunk) unless block_given?
|
295
|
+
|
296
|
+
offset = 0
|
297
|
+
chunksize = 0
|
298
|
+
|
299
|
+
str.each_char do |chr|
|
300
|
+
charsize = chr.bytesize
|
301
|
+
|
302
|
+
if chunksize + charsize > max_bytesize_per_chunk
|
303
|
+
yield Utilities.string_byteslice(str, offset, chunksize)
|
304
|
+
offset += chunksize
|
305
|
+
chunksize = charsize
|
306
|
+
else
|
307
|
+
chunksize += charsize
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
yield Utilities.string_byteslice(str, offset, chunksize)
|
312
|
+
end
|
286
313
|
end
|
287
314
|
end
|
data/lib/mail/envelope.rb
CHANGED
@@ -1,31 +1,28 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
|
-
#
|
3
|
+
#
|
4
4
|
# = Mail Envelope
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# The Envelope class provides a field for the first line in an
|
7
7
|
# mbox file, that looks like "From mikel@test.lindsaar.net DATETIME"
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# This envelope class reads that line, and turns it into an
|
10
10
|
# Envelope.from and Envelope.date for your use.
|
11
|
+
|
11
12
|
module Mail
|
12
|
-
class Envelope <
|
13
|
-
|
14
|
-
|
15
|
-
super(FIELD_NAME, strip_field(FIELD_NAME, args.last))
|
16
|
-
end
|
17
|
-
|
13
|
+
class Envelope < NamedStructuredField
|
14
|
+
NAME = 'Envelope-From'
|
15
|
+
|
18
16
|
def element
|
19
17
|
@element ||= Mail::EnvelopeFromElement.new(value)
|
20
18
|
end
|
21
|
-
|
22
|
-
def date
|
23
|
-
::DateTime.parse("#{element.date_time}")
|
24
|
-
end
|
25
19
|
|
26
20
|
def from
|
27
21
|
element.address
|
28
22
|
end
|
29
|
-
|
23
|
+
|
24
|
+
def date
|
25
|
+
element.date_time
|
26
|
+
end
|
30
27
|
end
|
31
28
|
end
|