mail 2.6.4 → 2.9.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 +5 -5
- data/README.md +208 -156
- data/lib/mail/attachments_list.rb +13 -10
- data/lib/mail/body.rb +96 -107
- data/lib/mail/configuration.rb +2 -0
- data/lib/mail/constants.rb +27 -5
- data/lib/mail/elements/address.rb +61 -50
- 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 +4 -2
- data/lib/mail/encodings.rb +83 -56
- data/lib/mail/envelope.rb +11 -14
- data/lib/mail/field.rb +181 -130
- data/lib/mail/field_list.rb +61 -8
- data/lib/mail/fields/bcc_field.rb +33 -52
- data/lib/mail/fields/cc_field.rb +27 -49
- data/lib/mail/fields/comments_field.rb +26 -37
- data/lib/mail/fields/common_address_field.rb +162 -0
- data/lib/mail/fields/common_date_field.rb +56 -0
- data/lib/mail/fields/common_field.rb +77 -0
- data/lib/mail/fields/common_message_id_field.rb +41 -0
- data/lib/mail/fields/content_description_field.rb +6 -14
- data/lib/mail/fields/content_disposition_field.rb +11 -38
- data/lib/mail/fields/content_id_field.rb +23 -51
- data/lib/mail/fields/content_location_field.rb +10 -25
- data/lib/mail/fields/content_transfer_encoding_field.rb +30 -31
- data/lib/mail/fields/content_type_field.rb +53 -84
- data/lib/mail/fields/date_field.rb +22 -52
- data/lib/mail/fields/from_field.rb +27 -49
- data/lib/mail/fields/in_reply_to_field.rb +37 -49
- data/lib/mail/fields/keywords_field.rb +17 -31
- data/lib/mail/fields/message_id_field.rb +24 -71
- data/lib/mail/fields/mime_version_field.rb +18 -30
- data/lib/mail/fields/named_structured_field.rb +10 -0
- data/lib/mail/fields/named_unstructured_field.rb +10 -0
- data/lib/mail/fields/optional_field.rb +9 -8
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +13 -11
- data/lib/mail/fields/received_field.rb +42 -57
- data/lib/mail/fields/references_field.rb +34 -49
- data/lib/mail/fields/reply_to_field.rb +27 -49
- data/lib/mail/fields/resent_bcc_field.rb +27 -49
- data/lib/mail/fields/resent_cc_field.rb +27 -49
- data/lib/mail/fields/resent_date_field.rb +4 -30
- data/lib/mail/fields/resent_from_field.rb +27 -49
- data/lib/mail/fields/resent_message_id_field.rb +4 -29
- data/lib/mail/fields/resent_sender_field.rb +26 -56
- data/lib/mail/fields/resent_to_field.rb +27 -49
- data/lib/mail/fields/return_path_field.rb +49 -54
- data/lib/mail/fields/sender_field.rb +33 -55
- data/lib/mail/fields/structured_field.rb +2 -30
- data/lib/mail/fields/subject_field.rb +8 -11
- data/lib/mail/fields/to_field.rb +27 -49
- data/lib/mail/fields/unstructured_field.rb +31 -47
- data/lib/mail/fields.rb +9 -0
- data/lib/mail/header.rb +71 -110
- data/lib/mail/mail.rb +34 -37
- data/lib/mail/matchers/attachment_matchers.rb +15 -0
- data/lib/mail/matchers/has_sent_mail.rb +21 -1
- data/lib/mail/message.rb +126 -127
- data/lib/mail/multibyte/chars.rb +24 -181
- data/lib/mail/multibyte/unicode.rb +11 -11
- data/lib/mail/multibyte/utils.rb +26 -43
- data/lib/mail/multibyte.rb +55 -16
- data/lib/mail/network/delivery_methods/exim.rb +8 -11
- data/lib/mail/network/delivery_methods/file_delivery.rb +15 -18
- data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +32 -35
- data/lib/mail/network/delivery_methods/smtp.rb +125 -68
- data/lib/mail/network/delivery_methods/smtp_connection.rb +11 -16
- data/lib/mail/network/delivery_methods/test_mailer.rb +12 -13
- data/lib/mail/network/retriever_methods/base.rb +13 -13
- data/lib/mail/network/retriever_methods/imap.rb +25 -9
- data/lib/mail/network/retriever_methods/pop3.rb +25 -23
- data/lib/mail/network/retriever_methods/test_retriever.rb +3 -2
- data/lib/mail/network.rb +1 -0
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +33228 -116
- data/lib/mail/parsers/address_lists_parser.rl +183 -0
- data/lib/mail/parsers/content_disposition_parser.rb +885 -49
- data/lib/mail/parsers/content_disposition_parser.rl +93 -0
- data/lib/mail/parsers/content_location_parser.rb +812 -23
- data/lib/mail/parsers/content_location_parser.rl +82 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +512 -21
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +75 -0
- data/lib/mail/parsers/content_type_parser.rb +1039 -55
- data/lib/mail/parsers/content_type_parser.rl +94 -0
- data/lib/mail/parsers/date_time_parser.rb +880 -25
- data/lib/mail/parsers/date_time_parser.rl +73 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3672 -40
- data/lib/mail/parsers/envelope_from_parser.rl +93 -0
- data/lib/mail/parsers/message_ids_parser.rb +5149 -25
- data/lib/mail/parsers/message_ids_parser.rl +97 -0
- data/lib/mail/parsers/mime_version_parser.rb +500 -26
- data/lib/mail/parsers/mime_version_parser.rl +72 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +873 -22
- data/lib/mail/parsers/phrase_lists_parser.rl +94 -0
- data/lib/mail/parsers/received_parser.rb +8779 -43
- data/lib/mail/parsers/received_parser.rl +95 -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 +25 -29
- data/lib/mail/parts_list.rb +62 -6
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +361 -74
- data/lib/mail/version.rb +2 -2
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +4 -37
- metadata +125 -67
- data/CHANGELOG.rdoc +0 -787
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -2
- data/Gemfile +0 -11
- data/Rakefile +0 -29
- data/TODO.rdoc +0 -9
- data/lib/mail/check_delivery_params.rb +0 -21
- 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 -223
|
@@ -1,45 +1,44 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
#
|
|
3
|
+
|
|
6
4
|
module Mail
|
|
7
|
-
class ContentTransferEncodingField <
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def initialize(value = nil, charset = 'utf-8')
|
|
13
|
-
self.charset = charset
|
|
14
|
-
value = '7bit' if value.to_s =~ /7-?bits?/i
|
|
15
|
-
value = '8bit' if value.to_s =~ /8-?bits?/i
|
|
16
|
-
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
|
17
|
-
self.parse
|
|
18
|
-
self
|
|
5
|
+
class ContentTransferEncodingField < NamedStructuredField #:nodoc:
|
|
6
|
+
NAME = 'Content-Transfer-Encoding'
|
|
7
|
+
|
|
8
|
+
def self.singular?
|
|
9
|
+
true
|
|
19
10
|
end
|
|
20
|
-
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
|
|
12
|
+
def self.normalize_content_transfer_encoding(value)
|
|
13
|
+
case value
|
|
14
|
+
when /7-?bits?/i
|
|
15
|
+
'7bit'
|
|
16
|
+
when /8-?bits?/i
|
|
17
|
+
'8bit'
|
|
18
|
+
else
|
|
19
|
+
value
|
|
24
20
|
end
|
|
25
21
|
end
|
|
26
|
-
|
|
22
|
+
|
|
23
|
+
def initialize(value = nil, charset = nil)
|
|
24
|
+
super self.class.normalize_content_transfer_encoding(value), charset
|
|
25
|
+
end
|
|
26
|
+
|
|
27
27
|
def element
|
|
28
28
|
@element ||= Mail::ContentTransferEncodingElement.new(value)
|
|
29
29
|
end
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
def encoding
|
|
32
32
|
element.encoding
|
|
33
33
|
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
def do_encode
|
|
37
|
+
"#{name}: #{encoding}\r\n"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def do_decode
|
|
41
|
+
encoding
|
|
42
|
+
end
|
|
44
43
|
end
|
|
45
44
|
end
|
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
require 'mail/fields/common/parameter_hash'
|
|
4
3
|
|
|
5
4
|
module Mail
|
|
6
|
-
class ContentTypeField <
|
|
5
|
+
class ContentTypeField < NamedStructuredField #:nodoc:
|
|
6
|
+
NAME = 'Content-Type'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
class << self
|
|
9
|
+
def singular?
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def with_boundary(type)
|
|
14
|
+
new "#{type}; boundary=#{generate_boundary}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def generate_boundary
|
|
18
|
+
"--==_mimepart_#{Mail.random_tag}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
10
21
|
|
|
11
|
-
def initialize(value = nil, charset =
|
|
12
|
-
|
|
13
|
-
if value.class == Array
|
|
22
|
+
def initialize(value = nil, charset = nil)
|
|
23
|
+
if value.is_a? Array
|
|
14
24
|
@main_type = value[0]
|
|
15
25
|
@sub_type = value[1]
|
|
16
26
|
@parameters = ParameterHash.new.merge!(value.last)
|
|
17
27
|
else
|
|
18
28
|
@main_type = nil
|
|
19
29
|
@sub_type = nil
|
|
20
|
-
|
|
21
|
-
value = strip_field(FIELD_NAME, value)
|
|
30
|
+
value = value.to_s
|
|
22
31
|
end
|
|
23
|
-
value = ensure_filename_quoted(value)
|
|
24
|
-
super(CAPITALIZED_FIELD, value, charset)
|
|
25
|
-
self.parse
|
|
26
|
-
self
|
|
27
|
-
end
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
unless Utilities.blank?(val)
|
|
31
|
-
self.value = val
|
|
32
|
-
@element = nil
|
|
33
|
-
element
|
|
34
|
-
end
|
|
33
|
+
super ensure_filename_quoted(value), charset
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def element
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
@element ||=
|
|
38
|
+
begin
|
|
39
|
+
Mail::ContentTypeElement.new(value)
|
|
40
|
+
rescue Mail::Field::ParseError
|
|
41
|
+
attempt_to_clean
|
|
42
|
+
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def attempt_to_clean
|
|
46
46
|
# Sanitize the value, handle special cases
|
|
47
|
-
|
|
48
|
-
rescue
|
|
47
|
+
Mail::ContentTypeElement.new(sanitize(value))
|
|
48
|
+
rescue Mail::Field::ParseError
|
|
49
49
|
# All else fails, just get the MIME media type
|
|
50
|
-
|
|
50
|
+
Mail::ContentTypeElement.new(get_mime_type(value))
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def main_type
|
|
@@ -61,31 +61,22 @@ module Mail
|
|
|
61
61
|
def string
|
|
62
62
|
"#{main_type}/#{sub_type}"
|
|
63
63
|
end
|
|
64
|
+
alias_method :content_type, :string
|
|
64
65
|
|
|
65
66
|
def default
|
|
66
67
|
decoded
|
|
67
68
|
end
|
|
68
69
|
|
|
69
|
-
alias :content_type :string
|
|
70
|
-
|
|
71
70
|
def parameters
|
|
72
|
-
unless @parameters
|
|
71
|
+
unless defined? @parameters
|
|
73
72
|
@parameters = ParameterHash.new
|
|
74
73
|
element.parameters.each { |p| @parameters.merge!(p) }
|
|
75
74
|
end
|
|
76
75
|
@parameters
|
|
77
76
|
end
|
|
78
77
|
|
|
79
|
-
def ContentTypeField.with_boundary(type)
|
|
80
|
-
new("#{type}; boundary=#{generate_boundary}")
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def ContentTypeField.generate_boundary
|
|
84
|
-
"--==_mimepart_#{Mail.random_tag}"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
78
|
def value
|
|
88
|
-
if @value.
|
|
79
|
+
if @value.is_a? Array
|
|
89
80
|
"#{@main_type}/#{@sub_type}; #{stringify(parameters)}"
|
|
90
81
|
else
|
|
91
82
|
@value
|
|
@@ -97,34 +88,17 @@ module Mail
|
|
|
97
88
|
end
|
|
98
89
|
|
|
99
90
|
def filename
|
|
100
|
-
|
|
101
|
-
when parameters['filename']
|
|
102
|
-
@filename = parameters['filename']
|
|
103
|
-
when parameters['name']
|
|
104
|
-
@filename = parameters['name']
|
|
105
|
-
else
|
|
106
|
-
@filename = nil
|
|
107
|
-
end
|
|
108
|
-
@filename
|
|
91
|
+
@filename ||= parameters['filename'] || parameters['name']
|
|
109
92
|
end
|
|
110
93
|
|
|
111
|
-
# TODO: Fix this up
|
|
112
94
|
def encoded
|
|
113
|
-
if parameters.length > 0
|
|
114
|
-
|
|
115
|
-
else
|
|
116
|
-
p = ""
|
|
117
|
-
end
|
|
118
|
-
"#{CAPITALIZED_FIELD}: #{content_type}#{p}\r\n"
|
|
95
|
+
p = ";\r\n\s#{parameters.encoded}" if parameters && parameters.length > 0
|
|
96
|
+
"#{name}: #{content_type}#{p}\r\n"
|
|
119
97
|
end
|
|
120
98
|
|
|
121
99
|
def decoded
|
|
122
|
-
if parameters.length > 0
|
|
123
|
-
|
|
124
|
-
else
|
|
125
|
-
p = ""
|
|
126
|
-
end
|
|
127
|
-
"#{content_type}" + p
|
|
100
|
+
p = "; #{parameters.decoded}" if parameters && parameters.length > 0
|
|
101
|
+
"#{content_type}#{p}"
|
|
128
102
|
end
|
|
129
103
|
|
|
130
104
|
private
|
|
@@ -140,39 +114,34 @@ module Mail
|
|
|
140
114
|
|
|
141
115
|
# Various special cases from random emails found that I am not going to change
|
|
142
116
|
# the parser for
|
|
143
|
-
def
|
|
144
|
-
|
|
117
|
+
def sanitize(val)
|
|
145
118
|
# TODO: check if there are cases where whitespace is not a separator
|
|
146
119
|
val = val.
|
|
147
120
|
gsub(/\s*=\s*/,'='). # remove whitespaces around equal sign
|
|
148
|
-
|
|
149
|
-
squeeze(';').
|
|
150
|
-
gsub(';', '; '). #use '; ' as a separator (or EOL)
|
|
121
|
+
gsub(/[; ]+/, '; '). #use '; ' as a separator (or EOL)
|
|
151
122
|
gsub(/;\s*$/,'') #remove trailing to keep examples below
|
|
152
123
|
|
|
153
|
-
if val =~ /(boundary=(\S*))/i
|
|
154
|
-
val = "#{$`.downcase}
|
|
124
|
+
if val =~ /((boundary|name|filename)=(\S*))/i
|
|
125
|
+
val = "#{$`.downcase}#{$2}=#{$3}#{$'.downcase}"
|
|
155
126
|
else
|
|
156
127
|
val.downcase!
|
|
157
128
|
end
|
|
158
129
|
|
|
130
|
+
val_chomp = val.chomp
|
|
159
131
|
case
|
|
160
|
-
when
|
|
161
|
-
# Handles 'text/plain;; format="flowed"' (double semi colon)
|
|
162
|
-
"#{$1}/#{$2}; #{$3}"
|
|
163
|
-
when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
|
|
132
|
+
when val_chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
|
|
164
133
|
# Microsoft helper:
|
|
165
134
|
# Handles 'type/subtype;ISO-8559-1'
|
|
166
|
-
"#{$1}/#{$2}; charset=#{quote_atom($3)}"
|
|
167
|
-
when
|
|
135
|
+
"#{$1}/#{$2}; charset=#{Utilities.quote_atom($3)}"
|
|
136
|
+
when /^text;?$/i.match?(val_chomp)
|
|
168
137
|
# Handles 'text;' and 'text'
|
|
169
138
|
"text/plain;"
|
|
170
|
-
when
|
|
139
|
+
when val_chomp =~ /^(\w+);\s(.*)$/i
|
|
171
140
|
# Handles 'text; <parameters>'
|
|
172
141
|
"text/plain; #{$2}"
|
|
173
142
|
when val =~ /([\w\-]+\/[\w\-]+);\scharset="charset="(\w+)""/i
|
|
174
143
|
# Handles text/html; charset="charset="GB2312""
|
|
175
|
-
"#{$1}; charset=#{quote_atom($2)}"
|
|
144
|
+
"#{$1}; charset=#{Utilities.quote_atom($2)}"
|
|
176
145
|
when val =~ /([\w\-]+\/[\w\-]+);\s+(.*)/i
|
|
177
146
|
type = $1
|
|
178
147
|
# Handles misquoted param values
|
|
@@ -180,19 +149,19 @@ module Mail
|
|
|
180
149
|
# and: audio/x-midi;\r\n\sname=Part .exe
|
|
181
150
|
params = $2.to_s.split(/\s+/)
|
|
182
151
|
params = params.map { |i| i.to_s.chomp.strip }
|
|
183
|
-
params = params.map { |i| i.split(/\s*\=\s
|
|
184
|
-
params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
|
|
152
|
+
params = params.map { |i| i.split(/\s*\=\s*/, 2) }
|
|
153
|
+
params = params.map { |i| "#{i[0]}=#{Utilities.dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
|
|
185
154
|
"#{type}; #{params}"
|
|
186
|
-
when
|
|
155
|
+
when /^\s*$/.match?(val)
|
|
187
156
|
'text/plain'
|
|
188
157
|
else
|
|
189
|
-
|
|
158
|
+
val
|
|
190
159
|
end
|
|
191
160
|
end
|
|
192
161
|
|
|
193
|
-
def get_mime_type(
|
|
194
|
-
case
|
|
195
|
-
when
|
|
162
|
+
def get_mime_type(val)
|
|
163
|
+
case val
|
|
164
|
+
when /^([\w\-]+)\/([\w\-]+);.+$/i
|
|
196
165
|
"#{$1}/#{$2}"
|
|
197
166
|
else
|
|
198
167
|
'text/plain'
|
|
@@ -1,58 +1,28 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
#
|
|
4
|
-
# = Date Field
|
|
5
|
-
#
|
|
6
|
-
# The Date field inherits from StructuredField and handles the Date: header
|
|
7
|
-
# field in the email.
|
|
8
|
-
#
|
|
9
|
-
# Sending date to a mail message will instantiate a Mail::Field object that
|
|
10
|
-
# has a DateField as its field type. This includes all Mail::CommonAddress
|
|
11
|
-
# module instance methods.
|
|
12
|
-
#
|
|
13
|
-
# There must be excatly one Date field in an RFC2822 email.
|
|
14
|
-
#
|
|
15
|
-
# == Examples:
|
|
16
|
-
#
|
|
17
|
-
# mail = Mail.new
|
|
18
|
-
# mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
19
|
-
# mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
|
|
20
|
-
# mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
21
|
-
# mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
22
|
-
# mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
23
|
-
# mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
24
|
-
#
|
|
25
|
-
require 'mail/fields/common/common_date'
|
|
26
3
|
|
|
27
4
|
module Mail
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
do_encode(CAPITALIZED_FIELD)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def decoded
|
|
54
|
-
do_decode
|
|
55
|
-
end
|
|
56
|
-
|
|
5
|
+
# = Date Field
|
|
6
|
+
#
|
|
7
|
+
# The Date field inherits from StructuredField and handles the Date: header
|
|
8
|
+
# field in the email.
|
|
9
|
+
#
|
|
10
|
+
# Sending date to a mail message will instantiate a Mail::Field object that
|
|
11
|
+
# has a DateField as its field type. This includes all Mail::CommonAddress
|
|
12
|
+
# module instance methods.
|
|
13
|
+
#
|
|
14
|
+
# There must be excatly one Date field in an RFC2822 email.
|
|
15
|
+
#
|
|
16
|
+
# == Examples:
|
|
17
|
+
#
|
|
18
|
+
# mail = Mail.new
|
|
19
|
+
# mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
20
|
+
# mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
|
|
21
|
+
# mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
22
|
+
# mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
23
|
+
# mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
24
|
+
# mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
25
|
+
class DateField < CommonDateField #:nodoc:
|
|
26
|
+
NAME = 'Date'
|
|
57
27
|
end
|
|
58
28
|
end
|
|
@@ -1,55 +1,33 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
#
|
|
4
|
-
# = From Field
|
|
5
|
-
#
|
|
6
|
-
# The From field inherits from StructuredField and handles the From: header
|
|
7
|
-
# field in the email.
|
|
8
|
-
#
|
|
9
|
-
# Sending from to a mail message will instantiate a Mail::Field object that
|
|
10
|
-
# has a FromField as its field type. This includes all Mail::CommonAddress
|
|
11
|
-
# module instance metods.
|
|
12
|
-
#
|
|
13
|
-
# Only one From field can appear in a header, though it can have multiple
|
|
14
|
-
# addresses and groups of addresses.
|
|
15
|
-
#
|
|
16
|
-
# == Examples:
|
|
17
|
-
#
|
|
18
|
-
# mail = Mail.new
|
|
19
|
-
# mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
20
|
-
# mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
21
|
-
# mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
22
|
-
# mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
23
|
-
# mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
24
|
-
#
|
|
25
|
-
# mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
26
|
-
# mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
27
|
-
# mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
28
|
-
# mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
29
|
-
#
|
|
30
|
-
require 'mail/fields/common/common_address'
|
|
31
3
|
|
|
32
4
|
module Mail
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
5
|
+
# = From Field
|
|
6
|
+
#
|
|
7
|
+
# The From field inherits from StructuredField and handles the From: header
|
|
8
|
+
# field in the email.
|
|
9
|
+
#
|
|
10
|
+
# Sending from to a mail message will instantiate a Mail::Field object that
|
|
11
|
+
# has a FromField as its field type. This includes all Mail::CommonAddress
|
|
12
|
+
# module instance metods.
|
|
13
|
+
#
|
|
14
|
+
# Only one From field can appear in a header, though it can have multiple
|
|
15
|
+
# addresses and groups of addresses.
|
|
16
|
+
#
|
|
17
|
+
# == Examples:
|
|
18
|
+
#
|
|
19
|
+
# mail = Mail.new
|
|
20
|
+
# mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
21
|
+
# mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
22
|
+
# mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
23
|
+
# mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
24
|
+
# mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
25
|
+
#
|
|
26
|
+
# mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
27
|
+
# mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
28
|
+
# mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
29
|
+
# mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
30
|
+
class FromField < CommonAddressField #:nodoc:
|
|
31
|
+
NAME = 'From'
|
|
54
32
|
end
|
|
55
33
|
end
|
|
@@ -1,57 +1,45 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
#
|
|
4
|
-
# = In-Reply-To Field
|
|
5
|
-
#
|
|
6
|
-
# The In-Reply-To field inherits from StructuredField and handles the
|
|
7
|
-
# In-Reply-To: header field in the email.
|
|
8
|
-
#
|
|
9
|
-
# Sending in_reply_to to a mail message will instantiate a Mail::Field object that
|
|
10
|
-
# has a InReplyToField as its field type. This includes all Mail::CommonMessageId
|
|
11
|
-
# module instance metods.
|
|
12
|
-
#
|
|
13
|
-
# Note that, the #message_ids method will return an array of message IDs without the
|
|
14
|
-
# enclosing angle brackets which per RFC are not syntactically part of the message id.
|
|
15
|
-
#
|
|
16
|
-
# Only one InReplyTo field can appear in a header, though it can have multiple
|
|
17
|
-
# Message IDs.
|
|
18
|
-
#
|
|
19
|
-
# == Examples:
|
|
20
|
-
#
|
|
21
|
-
# mail = Mail.new
|
|
22
|
-
# mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
|
|
23
|
-
# mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
|
|
24
|
-
# mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
25
|
-
# mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
26
|
-
# mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
27
|
-
#
|
|
28
|
-
# mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
|
|
29
|
-
#
|
|
30
|
-
require 'mail/fields/common/common_message_id'
|
|
31
3
|
|
|
32
4
|
module Mail
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
5
|
+
# = In-Reply-To Field
|
|
6
|
+
#
|
|
7
|
+
# The In-Reply-To field inherits from StructuredField and handles the
|
|
8
|
+
# In-Reply-To: header field in the email.
|
|
9
|
+
#
|
|
10
|
+
# Sending in_reply_to to a mail message will instantiate a Mail::Field object that
|
|
11
|
+
# has a InReplyToField as its field type. This includes all Mail::CommonMessageId
|
|
12
|
+
# module instance metods.
|
|
13
|
+
#
|
|
14
|
+
# Note that, the #message_ids method will return an array of message IDs without the
|
|
15
|
+
# enclosing angle brackets which per RFC are not syntactically part of the message id.
|
|
16
|
+
#
|
|
17
|
+
# Only one InReplyTo field can appear in a header, though it can have multiple
|
|
18
|
+
# Message IDs.
|
|
19
|
+
#
|
|
20
|
+
# == Examples:
|
|
21
|
+
#
|
|
22
|
+
# mail = Mail.new
|
|
23
|
+
# mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
|
|
24
|
+
# mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
|
|
25
|
+
# mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
26
|
+
# mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
27
|
+
# mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
28
|
+
#
|
|
29
|
+
# mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
|
|
30
|
+
class InReplyToField < CommonMessageIdField #:nodoc:
|
|
31
|
+
NAME = 'In-Reply-To'
|
|
32
|
+
|
|
33
|
+
def self.singular?
|
|
34
|
+
true
|
|
50
35
|
end
|
|
51
|
-
|
|
52
|
-
def
|
|
53
|
-
|
|
36
|
+
|
|
37
|
+
def initialize(value = nil, charset = nil)
|
|
38
|
+
if value.is_a?(Array)
|
|
39
|
+
super value.join("\r\n\s"), charset
|
|
40
|
+
else
|
|
41
|
+
super
|
|
42
|
+
end
|
|
54
43
|
end
|
|
55
|
-
|
|
56
44
|
end
|
|
57
45
|
end
|
|
@@ -1,44 +1,30 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# keywords = "Keywords:" phrase *("," phrase) CRLF
|
|
3
|
+
|
|
5
4
|
module Mail
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
CAPITALIZED_FIELD = 'Keywords'
|
|
10
|
-
|
|
11
|
-
def initialize(value = nil, charset = 'utf-8')
|
|
12
|
-
self.charset = charset
|
|
13
|
-
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
|
|
14
|
-
self
|
|
15
|
-
end
|
|
5
|
+
# keywords = "Keywords:" phrase *("," phrase) CRLF
|
|
6
|
+
class KeywordsField < NamedStructuredField #:nodoc:
|
|
7
|
+
NAME = 'Keywords'
|
|
16
8
|
|
|
17
|
-
def
|
|
18
|
-
|
|
19
|
-
@phrase_list ||= PhraseList.new(value)
|
|
20
|
-
end
|
|
9
|
+
def element
|
|
10
|
+
@element ||= PhraseList.new(value)
|
|
21
11
|
end
|
|
22
|
-
|
|
23
|
-
def phrase_list
|
|
24
|
-
@phrase_list ||= PhraseList.new(value)
|
|
25
|
-
end
|
|
26
|
-
|
|
12
|
+
|
|
27
13
|
def keywords
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def encoded
|
|
32
|
-
"#{CAPITALIZED_FIELD}: #{keywords.join(",\r\n ")}\r\n"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def decoded
|
|
36
|
-
keywords.join(', ')
|
|
14
|
+
element.phrases
|
|
37
15
|
end
|
|
38
16
|
|
|
39
17
|
def default
|
|
40
18
|
keywords
|
|
41
19
|
end
|
|
42
|
-
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
def do_decode
|
|
23
|
+
keywords.join(', ')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def do_encode
|
|
27
|
+
"#{name}: #{keywords.join(",\r\n ")}\r\n"
|
|
28
|
+
end
|
|
43
29
|
end
|
|
44
30
|
end
|