mail 2.5.5 → 2.6.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 +4 -4
- data/CHANGELOG.rdoc +8 -9
- data/CONTRIBUTING.md +13 -0
- data/Dependencies.txt +0 -1
- data/Gemfile +7 -24
- data/README.md +36 -15
- data/Rakefile +10 -2
- data/VERSION +4 -0
- data/lib/mail.rb +1 -1
- data/lib/mail/body.rb +2 -2
- data/lib/mail/check_delivery_params.rb +10 -47
- data/lib/mail/core_extensions/string.rb +12 -2
- data/lib/mail/elements/address.rb +38 -82
- data/lib/mail/elements/address_list.rb +19 -42
- data/lib/mail/elements/content_disposition_element.rb +3 -7
- data/lib/mail/elements/content_location_element.rb +2 -6
- data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
- data/lib/mail/elements/content_type_element.rb +4 -8
- data/lib/mail/elements/date_time_element.rb +3 -7
- data/lib/mail/elements/envelope_from_element.rb +3 -11
- data/lib/mail/elements/message_ids_element.rb +1 -6
- data/lib/mail/elements/mime_version_element.rb +3 -7
- data/lib/mail/elements/phrase_list.rb +2 -7
- data/lib/mail/elements/received_element.rb +3 -7
- data/lib/mail/encodings.rb +0 -1
- data/lib/mail/envelope.rb +0 -5
- data/lib/mail/field.rb +53 -17
- data/lib/mail/field_list.rb +18 -18
- data/lib/mail/fields/common/common_address.rb +15 -20
- data/lib/mail/fields/common/common_date.rb +0 -7
- data/lib/mail/fields/common/common_field.rb +1 -1
- data/lib/mail/fields/content_transfer_encoding_field.rb +0 -6
- data/lib/mail/fields/resent_sender_field.rb +1 -1
- data/lib/mail/fields/sender_field.rb +1 -1
- data/lib/mail/fields/unstructured_field.rb +7 -1
- data/lib/mail/header.rb +8 -22
- data/lib/mail/mail.rb +12 -0
- data/lib/mail/matchers/has_sent_mail.rb +34 -1
- data/lib/mail/message.rb +18 -11
- data/lib/mail/multibyte/unicode.rb +1 -1
- data/lib/mail/network/delivery_methods/exim.rb +10 -6
- data/lib/mail/network/delivery_methods/file_delivery.rb +8 -4
- data/lib/mail/network/delivery_methods/sendmail.rb +7 -9
- data/lib/mail/network/delivery_methods/smtp.rb +5 -2
- data/lib/mail/network/delivery_methods/smtp_connection.rb +6 -2
- data/lib/mail/network/delivery_methods/test_mailer.rb +8 -5
- data/lib/mail/network/retriever_methods/imap.rb +18 -13
- data/lib/mail/parsers.rb +26 -0
- data/lib/mail/parsers/address_lists_parser.rb +132 -0
- data/lib/mail/parsers/content_disposition_parser.rb +67 -0
- data/lib/mail/parsers/content_location_parser.rb +35 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
- data/lib/mail/parsers/content_type_parser.rb +64 -0
- data/lib/mail/parsers/date_time_parser.rb +36 -0
- data/lib/mail/parsers/envelope_from_parser.rb +45 -0
- data/lib/mail/parsers/message_ids_parser.rb +39 -0
- data/lib/mail/parsers/mime_version_parser.rb +41 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
- data/lib/mail/parsers/ragel.rb +17 -0
- data/lib/mail/parsers/ragel/common.rl +184 -0
- data/lib/mail/parsers/ragel/date_time.rl +30 -0
- data/lib/mail/parsers/ragel/parser_info.rb +61 -0
- data/lib/mail/parsers/ragel/ruby.rb +29 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
- data/lib/mail/parsers/received_parser.rb +47 -0
- data/lib/mail/parts_list.rb +4 -2
- data/lib/mail/patterns.rb +3 -1
- data/lib/mail/utilities.rb +3 -1
- data/lib/mail/version.rb +1 -1
- data/lib/mail/version_specific/ruby_1_8.rb +1 -1
- data/lib/mail/version_specific/ruby_1_9.rb +13 -1
- metadata +55 -51
- data/lib/VERSION +0 -4
- data/lib/load_parsers.rb +0 -35
- data/lib/mail/parsers/address_lists.rb +0 -64
- data/lib/mail/parsers/address_lists.treetop +0 -19
- data/lib/mail/parsers/content_disposition.rb +0 -535
- data/lib/mail/parsers/content_disposition.treetop +0 -46
- data/lib/mail/parsers/content_location.rb +0 -139
- data/lib/mail/parsers/content_location.treetop +0 -20
- data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
- data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
- data/lib/mail/parsers/content_type.rb +0 -971
- data/lib/mail/parsers/content_type.treetop +0 -68
- data/lib/mail/parsers/date_time.rb +0 -114
- data/lib/mail/parsers/date_time.treetop +0 -11
- data/lib/mail/parsers/envelope_from.rb +0 -194
- data/lib/mail/parsers/envelope_from.treetop +0 -32
- data/lib/mail/parsers/message_ids.rb +0 -45
- data/lib/mail/parsers/message_ids.treetop +0 -15
- data/lib/mail/parsers/mime_version.rb +0 -144
- data/lib/mail/parsers/mime_version.treetop +0 -19
- data/lib/mail/parsers/phrase_lists.rb +0 -45
- data/lib/mail/parsers/phrase_lists.treetop +0 -15
- data/lib/mail/parsers/received.rb +0 -71
- data/lib/mail/parsers/received.treetop +0 -11
- data/lib/mail/parsers/rfc2045.rb +0 -421
- data/lib/mail/parsers/rfc2045.treetop +0 -35
- data/lib/mail/parsers/rfc2822.rb +0 -5397
- data/lib/mail/parsers/rfc2822.treetop +0 -408
- data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
- data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
- data/lib/tasks/corpus.rake +0 -125
- data/lib/tasks/treetop.rake +0 -10
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mail
|
3
3
|
class AddressList # :nodoc:
|
4
|
-
|
4
|
+
|
5
5
|
# Mail::AddressList is the class that parses To, From and other address fields from
|
6
6
|
# emails passed into Mail.
|
7
7
|
#
|
@@ -18,57 +18,34 @@ module Mail
|
|
18
18
|
# a.addresses #=> [#<Mail::Address:14943130 Address: |ada@test.lindsaar.net...
|
19
19
|
# a.group_names #=> ["My Group"]
|
20
20
|
def initialize(string)
|
21
|
-
|
22
|
-
|
23
|
-
return self
|
24
|
-
end
|
25
|
-
parser = Mail::AddressListsParser.new
|
26
|
-
if tree = parser.parse(string)
|
27
|
-
@address_nodes = tree.addresses
|
28
|
-
else
|
29
|
-
raise Mail::Field::ParseError.new(AddressListsParser, string, parser.failure_reason)
|
30
|
-
end
|
21
|
+
@addresses_grouped_by_group = nil
|
22
|
+
@address_list = Parsers::AddressListsParser.new.parse(string)
|
31
23
|
end
|
32
24
|
|
33
25
|
# Returns a list of address objects from the parsed line
|
34
26
|
def addresses
|
35
|
-
@addresses ||=
|
36
|
-
Mail::Address.new(
|
27
|
+
@addresses ||= @address_list.addresses.map do |address_data|
|
28
|
+
Mail::Address.new(address_data)
|
37
29
|
end
|
38
30
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
31
|
+
|
32
|
+
def addresses_grouped_by_group
|
33
|
+
return @addresses_grouped_by_group if @addresses_grouped_by_group
|
34
|
+
|
35
|
+
@addresses_grouped_by_group = {}
|
36
|
+
|
37
|
+
@address_list.addresses.each do |address_data|
|
38
|
+
if group = address_data.group
|
39
|
+
@addresses_grouped_by_group[group] ||= []
|
40
|
+
@addresses_grouped_by_group[group] << Mail::Address.new(address_data)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@addresses_grouped_by_group
|
48
44
|
end
|
49
45
|
|
50
46
|
# Returns the names as an array of strings of all groups
|
51
47
|
def group_names # :nodoc:
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
# Returns a list of address syntax trees
|
56
|
-
def address_nodes # :nodoc:
|
57
|
-
@address_nodes
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def get_addresses
|
63
|
-
(individual_recipients + group_recipients.map { |g| get_group_addresses(g) }).flatten
|
64
|
-
end
|
65
|
-
|
66
|
-
def get_group_addresses(g)
|
67
|
-
if g.group_list.respond_to?(:addresses)
|
68
|
-
g.group_list.addresses
|
69
|
-
else
|
70
|
-
[]
|
71
|
-
end
|
48
|
+
@address_list.group_names
|
72
49
|
end
|
73
50
|
end
|
74
51
|
end
|
@@ -5,13 +5,9 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@parameters = tree.parameters
|
12
|
-
else
|
13
|
-
raise Mail::Field::ParseError.new(ContentDispositionElement, string, parser.failure_reason)
|
14
|
-
end
|
8
|
+
content_disposition = Mail::Parsers::ContentDispositionParser.new.parse(cleaned(string))
|
9
|
+
@disposition_type = content_disposition.disposition_type
|
10
|
+
@parameters = content_disposition.parameters
|
15
11
|
end
|
16
12
|
|
17
13
|
def disposition_type
|
@@ -5,12 +5,8 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
@location = tree.location.text_value
|
11
|
-
else
|
12
|
-
raise Mail::Field::ParseError.new(ContentLocationElement, string, parser.failure_reason)
|
13
|
-
end
|
8
|
+
content_location = Mail::Parsers::ContentLocationParser.new.parse(string)
|
9
|
+
@location = content_location.location
|
14
10
|
end
|
15
11
|
|
16
12
|
def location
|
@@ -4,16 +4,9 @@ module Mail
|
|
4
4
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
|
9
|
-
|
10
|
-
when string.blank?
|
11
|
-
@encoding = ''
|
12
|
-
when tree = parser.parse(string.to_s.downcase)
|
13
|
-
@encoding = tree.encoding.text_value
|
14
|
-
else
|
15
|
-
raise Mail::Field::ParseError.new(ContentTransferEncodingElement, string, parser.failure_reason)
|
16
|
-
end
|
7
|
+
def initialize(string)
|
8
|
+
content_transfer_encoding = Mail::Parsers::ContentTransferEncodingParser.new.parse(string)
|
9
|
+
@encoding = content_transfer_encoding.encoding
|
17
10
|
end
|
18
11
|
|
19
12
|
def encoding
|
@@ -5,14 +5,10 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@parameters = tree.parameters
|
13
|
-
else
|
14
|
-
raise Mail::Field::ParseError.new(ContentTypeElement, string, parser.failure_reason)
|
15
|
-
end
|
8
|
+
content_type = Mail::Parsers::ContentTypeParser.new.parse(cleaned(string))
|
9
|
+
@main_type = content_type.main_type
|
10
|
+
@sub_type = content_type.sub_type
|
11
|
+
@parameters = content_type.parameters
|
16
12
|
end
|
17
13
|
|
18
14
|
def main_type
|
@@ -5,13 +5,9 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@time_string = tree.time.text_value
|
12
|
-
else
|
13
|
-
raise Mail::Field::ParseError.new(DateTimeElement, string, parser.failure_reason)
|
14
|
-
end
|
8
|
+
date_time = Mail::Parsers::DateTimeParser.new.parse(string)
|
9
|
+
@date_string = date_time.date_string
|
10
|
+
@time_string = date_time.time_string
|
15
11
|
end
|
16
12
|
|
17
13
|
def date_string
|
@@ -5,17 +5,9 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@date_time = ::DateTime.parse("#{tree.ctime_date.text_value}")
|
12
|
-
else
|
13
|
-
raise Mail::Field::ParseError.new(EnvelopeFromElement, string, parser.failure_reason)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def tree
|
18
|
-
@tree
|
8
|
+
@envelope_from = Mail::Parsers::EnvelopeFromParser.new.parse(string)
|
9
|
+
@address = @envelope_from.address
|
10
|
+
@date_time = ::DateTime.parse(@envelope_from.ctime_date)
|
19
11
|
end
|
20
12
|
|
21
13
|
def date_time
|
@@ -5,12 +5,7 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize(string)
|
8
|
-
|
9
|
-
if tree = parser.parse(string)
|
10
|
-
@message_ids = tree.message_ids.map { |msg_id| clean_msg_id(msg_id.text_value) }
|
11
|
-
else
|
12
|
-
raise Mail::Field::ParseError.new(MessageIdsElement, string, parser.failure_reason)
|
13
|
-
end
|
8
|
+
@message_ids = Mail::Parsers::MessageIdsParser.new.parse(string).message_ids.map { |msg_id| clean_msg_id(msg_id) }
|
14
9
|
end
|
15
10
|
|
16
11
|
def message_ids
|
@@ -5,13 +5,9 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@minor = tree.minor.text_value
|
12
|
-
else
|
13
|
-
raise Mail::Field::ParseError.new(MimeVersionElement, string, parser.failure_reason)
|
14
|
-
end
|
8
|
+
mime_version = Mail::Parsers::MimeVersionParser.new.parse(string)
|
9
|
+
@major = mime_version.major
|
10
|
+
@minor = mime_version.minor
|
15
11
|
end
|
16
12
|
|
17
13
|
def major
|
@@ -5,16 +5,11 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize(string)
|
8
|
-
|
9
|
-
if tree = parser.parse(string)
|
10
|
-
@phrases = tree.phrases
|
11
|
-
else
|
12
|
-
raise Mail::Field::ParseError.new(PhraseList, string, parser.failure_reason)
|
13
|
-
end
|
8
|
+
@phrase_lists = Mail::Parsers::PhraseListsParser.new.parse(string)
|
14
9
|
end
|
15
10
|
|
16
11
|
def phrases
|
17
|
-
@phrases.map { |p| unquote(p
|
12
|
+
@phrase_lists.phrases.map { |p| unquote(p) }
|
18
13
|
end
|
19
14
|
|
20
15
|
end
|
@@ -5,13 +5,9 @@ module Mail
|
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
def initialize( string )
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@info = tree.name_val_list.text_value
|
12
|
-
else
|
13
|
-
raise Mail::Field::ParseError.new(ReceivedElement, string, parser.failure_reason)
|
14
|
-
end
|
8
|
+
received = Mail::Parsers::ReceivedParser.new.parse(string)
|
9
|
+
@date_time = ::DateTime.parse("#{received.date} #{received.time}")
|
10
|
+
@info = received.info
|
15
11
|
end
|
16
12
|
|
17
13
|
def date_time
|
data/lib/mail/encodings.rb
CHANGED
data/lib/mail/envelope.rb
CHANGED
@@ -14,11 +14,6 @@ module Mail
|
|
14
14
|
super(FIELD_NAME, strip_field(FIELD_NAME, args.last))
|
15
15
|
end
|
16
16
|
|
17
|
-
def tree
|
18
|
-
@element ||= Mail::EnvelopeFromElement.new(value)
|
19
|
-
@tree ||= @element.tree
|
20
|
-
end
|
21
|
-
|
22
17
|
def element
|
23
18
|
@element ||= Mail::EnvelopeFromElement.new(value)
|
24
19
|
end
|
data/lib/mail/field.rb
CHANGED
@@ -22,7 +22,7 @@ module Mail
|
|
22
22
|
#
|
23
23
|
class Field
|
24
24
|
|
25
|
-
include
|
25
|
+
include Utilities
|
26
26
|
include Comparable
|
27
27
|
|
28
28
|
STRUCTURED_FIELDS = %w[ bcc cc content-description content-disposition
|
@@ -67,6 +67,10 @@ module Mail
|
|
67
67
|
"content-location" => ContentLocationField,
|
68
68
|
}
|
69
69
|
|
70
|
+
FIELD_NAME_MAP = FIELDS_MAP.inject({}) do |map, (field, field_klass)|
|
71
|
+
map.update(field => field_klass::CAPITALIZED_FIELD)
|
72
|
+
end
|
73
|
+
|
70
74
|
# Generic Field Exception
|
71
75
|
class FieldError < StandardError
|
72
76
|
end
|
@@ -110,15 +114,22 @@ module Mail
|
|
110
114
|
def initialize(name, value = nil, charset = 'utf-8')
|
111
115
|
case
|
112
116
|
when name =~ /:/ # Field.new("field-name: field data")
|
113
|
-
charset = value
|
114
|
-
name
|
115
|
-
|
117
|
+
@charset = value.blank? ? charset : value
|
118
|
+
@name = name[FIELD_PREFIX]
|
119
|
+
@raw_value = name
|
120
|
+
@value = nil
|
116
121
|
when name !~ /:/ && value.blank? # Field.new("field-name")
|
117
|
-
|
122
|
+
@name = name
|
123
|
+
@value = nil
|
124
|
+
@raw_value = nil
|
125
|
+
@charset = charset
|
118
126
|
else # Field.new("field-name", "value")
|
119
|
-
|
127
|
+
@name = name
|
128
|
+
@value = value
|
129
|
+
@raw_value = nil
|
130
|
+
@charset = charset
|
120
131
|
end
|
121
|
-
|
132
|
+
@name = FIELD_NAME_MAP[@name.to_s.downcase] || @name
|
122
133
|
end
|
123
134
|
|
124
135
|
def field=(value)
|
@@ -126,11 +137,12 @@ module Mail
|
|
126
137
|
end
|
127
138
|
|
128
139
|
def field
|
129
|
-
@
|
140
|
+
_, @value = split(@raw_value) if @raw_value && !@value
|
141
|
+
@field ||= create_field(@name, @value, @charset)
|
130
142
|
end
|
131
143
|
|
132
144
|
def name
|
133
|
-
|
145
|
+
@name
|
134
146
|
end
|
135
147
|
|
136
148
|
def value
|
@@ -138,19 +150,29 @@ module Mail
|
|
138
150
|
end
|
139
151
|
|
140
152
|
def value=(val)
|
141
|
-
create_field(name, val, charset)
|
153
|
+
@field = create_field(name, val, @charset)
|
142
154
|
end
|
143
155
|
|
144
156
|
def to_s
|
145
157
|
field.to_s
|
146
158
|
end
|
147
159
|
|
160
|
+
def inspect
|
161
|
+
"#<#{self.class.name} 0x#{(object_id * 2).to_s(16)} #{instance_variables.map do |ivar|
|
162
|
+
"#{ivar}=#{instance_variable_get(ivar).inspect}"
|
163
|
+
end.join(" ")}>"
|
164
|
+
end
|
165
|
+
|
148
166
|
def update(name, value)
|
149
|
-
create_field(name, value, charset)
|
167
|
+
@field = create_field(name, value, @charset)
|
150
168
|
end
|
151
169
|
|
152
170
|
def same( other )
|
153
|
-
match_to_s(other.name,
|
171
|
+
match_to_s(other.name, self.name)
|
172
|
+
end
|
173
|
+
|
174
|
+
def responsible_for?( val )
|
175
|
+
name.to_s.casecmp(val.to_s) == 0
|
154
176
|
end
|
155
177
|
|
156
178
|
alias_method :==, :same
|
@@ -182,18 +204,32 @@ module Mail
|
|
182
204
|
|
183
205
|
def split(raw_field)
|
184
206
|
match_data = raw_field.mb_chars.match(FIELD_SPLIT)
|
185
|
-
[match_data[1].to_s.mb_chars.strip, match_data[2].to_s.mb_chars.strip]
|
207
|
+
[match_data[1].to_s.mb_chars.strip, match_data[2].to_s.mb_chars.strip.to_s]
|
186
208
|
rescue
|
187
209
|
STDERR.puts "WARNING: Could not parse (and so ignoring) '#{raw_field}'"
|
188
210
|
end
|
189
211
|
|
212
|
+
# 2.2.3. Long Header Fields
|
213
|
+
#
|
214
|
+
# The process of moving from this folded multiple-line representation
|
215
|
+
# of a header field to its single line representation is called
|
216
|
+
# "unfolding". Unfolding is accomplished by simply removing any CRLF
|
217
|
+
# that is immediately followed by WSP. Each header field should be
|
218
|
+
# treated in its unfolded form for further syntactic and semantic
|
219
|
+
# evaluation.
|
220
|
+
def unfold(string)
|
221
|
+
string.gsub(/[\r\n \t]+/m, ' ')
|
222
|
+
end
|
223
|
+
|
190
224
|
def create_field(name, value, charset)
|
225
|
+
value = unfold(value) if value.is_a?(String)
|
226
|
+
|
191
227
|
begin
|
192
|
-
|
228
|
+
new_field(name, value, charset)
|
193
229
|
rescue Mail::Field::ParseError => e
|
194
|
-
|
195
|
-
|
196
|
-
|
230
|
+
field = Mail::UnstructuredField.new(name, value)
|
231
|
+
field.errors << [name, value, e]
|
232
|
+
field
|
197
233
|
end
|
198
234
|
end
|
199
235
|
|
data/lib/mail/field_list.rb
CHANGED
@@ -8,26 +8,26 @@ module Mail
|
|
8
8
|
|
9
9
|
include Enumerable
|
10
10
|
|
11
|
+
# Insert the field in sorted order.
|
12
|
+
#
|
13
|
+
# Heavily based on bisect.insort from Python, which is:
|
14
|
+
# Copyright (C) 2001-2013 Python Software Foundation.
|
15
|
+
# Licensed under <http://docs.python.org/license.html>
|
16
|
+
# From <http://hg.python.org/cpython/file/2.7/Lib/bisect.py>
|
11
17
|
def <<( new_field )
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
when 0
|
22
|
-
next
|
23
|
-
when 1
|
24
|
-
insert_idx = idx
|
25
|
-
break
|
26
|
-
end
|
18
|
+
lo = 0
|
19
|
+
hi = size
|
20
|
+
|
21
|
+
while lo < hi
|
22
|
+
mid = (lo + hi) / 2
|
23
|
+
if new_field < self[mid]
|
24
|
+
hi = mid
|
25
|
+
else
|
26
|
+
lo = mid + 1
|
27
27
|
end
|
28
|
-
insert(insert_idx, new_field)
|
29
28
|
end
|
29
|
+
|
30
|
+
insert(lo, new_field)
|
30
31
|
end
|
31
|
-
|
32
32
|
end
|
33
|
-
end
|
33
|
+
end
|