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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +8 -9
  3. data/CONTRIBUTING.md +13 -0
  4. data/Dependencies.txt +0 -1
  5. data/Gemfile +7 -24
  6. data/README.md +36 -15
  7. data/Rakefile +10 -2
  8. data/VERSION +4 -0
  9. data/lib/mail.rb +1 -1
  10. data/lib/mail/body.rb +2 -2
  11. data/lib/mail/check_delivery_params.rb +10 -47
  12. data/lib/mail/core_extensions/string.rb +12 -2
  13. data/lib/mail/elements/address.rb +38 -82
  14. data/lib/mail/elements/address_list.rb +19 -42
  15. data/lib/mail/elements/content_disposition_element.rb +3 -7
  16. data/lib/mail/elements/content_location_element.rb +2 -6
  17. data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
  18. data/lib/mail/elements/content_type_element.rb +4 -8
  19. data/lib/mail/elements/date_time_element.rb +3 -7
  20. data/lib/mail/elements/envelope_from_element.rb +3 -11
  21. data/lib/mail/elements/message_ids_element.rb +1 -6
  22. data/lib/mail/elements/mime_version_element.rb +3 -7
  23. data/lib/mail/elements/phrase_list.rb +2 -7
  24. data/lib/mail/elements/received_element.rb +3 -7
  25. data/lib/mail/encodings.rb +0 -1
  26. data/lib/mail/envelope.rb +0 -5
  27. data/lib/mail/field.rb +53 -17
  28. data/lib/mail/field_list.rb +18 -18
  29. data/lib/mail/fields/common/common_address.rb +15 -20
  30. data/lib/mail/fields/common/common_date.rb +0 -7
  31. data/lib/mail/fields/common/common_field.rb +1 -1
  32. data/lib/mail/fields/content_transfer_encoding_field.rb +0 -6
  33. data/lib/mail/fields/resent_sender_field.rb +1 -1
  34. data/lib/mail/fields/sender_field.rb +1 -1
  35. data/lib/mail/fields/unstructured_field.rb +7 -1
  36. data/lib/mail/header.rb +8 -22
  37. data/lib/mail/mail.rb +12 -0
  38. data/lib/mail/matchers/has_sent_mail.rb +34 -1
  39. data/lib/mail/message.rb +18 -11
  40. data/lib/mail/multibyte/unicode.rb +1 -1
  41. data/lib/mail/network/delivery_methods/exim.rb +10 -6
  42. data/lib/mail/network/delivery_methods/file_delivery.rb +8 -4
  43. data/lib/mail/network/delivery_methods/sendmail.rb +7 -9
  44. data/lib/mail/network/delivery_methods/smtp.rb +5 -2
  45. data/lib/mail/network/delivery_methods/smtp_connection.rb +6 -2
  46. data/lib/mail/network/delivery_methods/test_mailer.rb +8 -5
  47. data/lib/mail/network/retriever_methods/imap.rb +18 -13
  48. data/lib/mail/parsers.rb +26 -0
  49. data/lib/mail/parsers/address_lists_parser.rb +132 -0
  50. data/lib/mail/parsers/content_disposition_parser.rb +67 -0
  51. data/lib/mail/parsers/content_location_parser.rb +35 -0
  52. data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
  53. data/lib/mail/parsers/content_type_parser.rb +64 -0
  54. data/lib/mail/parsers/date_time_parser.rb +36 -0
  55. data/lib/mail/parsers/envelope_from_parser.rb +45 -0
  56. data/lib/mail/parsers/message_ids_parser.rb +39 -0
  57. data/lib/mail/parsers/mime_version_parser.rb +41 -0
  58. data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
  59. data/lib/mail/parsers/ragel.rb +17 -0
  60. data/lib/mail/parsers/ragel/common.rl +184 -0
  61. data/lib/mail/parsers/ragel/date_time.rl +30 -0
  62. data/lib/mail/parsers/ragel/parser_info.rb +61 -0
  63. data/lib/mail/parsers/ragel/ruby.rb +29 -0
  64. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
  65. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
  66. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
  67. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
  68. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
  69. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
  70. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
  71. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
  72. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
  73. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
  74. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
  75. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
  76. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
  77. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
  78. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
  79. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
  80. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
  81. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
  82. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
  83. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
  84. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
  85. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
  86. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
  87. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
  88. data/lib/mail/parsers/received_parser.rb +47 -0
  89. data/lib/mail/parts_list.rb +4 -2
  90. data/lib/mail/patterns.rb +3 -1
  91. data/lib/mail/utilities.rb +3 -1
  92. data/lib/mail/version.rb +1 -1
  93. data/lib/mail/version_specific/ruby_1_8.rb +1 -1
  94. data/lib/mail/version_specific/ruby_1_9.rb +13 -1
  95. metadata +55 -51
  96. data/lib/VERSION +0 -4
  97. data/lib/load_parsers.rb +0 -35
  98. data/lib/mail/parsers/address_lists.rb +0 -64
  99. data/lib/mail/parsers/address_lists.treetop +0 -19
  100. data/lib/mail/parsers/content_disposition.rb +0 -535
  101. data/lib/mail/parsers/content_disposition.treetop +0 -46
  102. data/lib/mail/parsers/content_location.rb +0 -139
  103. data/lib/mail/parsers/content_location.treetop +0 -20
  104. data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
  105. data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
  106. data/lib/mail/parsers/content_type.rb +0 -971
  107. data/lib/mail/parsers/content_type.treetop +0 -68
  108. data/lib/mail/parsers/date_time.rb +0 -114
  109. data/lib/mail/parsers/date_time.treetop +0 -11
  110. data/lib/mail/parsers/envelope_from.rb +0 -194
  111. data/lib/mail/parsers/envelope_from.treetop +0 -32
  112. data/lib/mail/parsers/message_ids.rb +0 -45
  113. data/lib/mail/parsers/message_ids.treetop +0 -15
  114. data/lib/mail/parsers/mime_version.rb +0 -144
  115. data/lib/mail/parsers/mime_version.treetop +0 -19
  116. data/lib/mail/parsers/phrase_lists.rb +0 -45
  117. data/lib/mail/parsers/phrase_lists.treetop +0 -15
  118. data/lib/mail/parsers/received.rb +0 -71
  119. data/lib/mail/parsers/received.treetop +0 -11
  120. data/lib/mail/parsers/rfc2045.rb +0 -421
  121. data/lib/mail/parsers/rfc2045.treetop +0 -35
  122. data/lib/mail/parsers/rfc2822.rb +0 -5397
  123. data/lib/mail/parsers/rfc2822.treetop +0 -408
  124. data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
  125. data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
  126. data/lib/tasks/corpus.rake +0 -125
  127. data/lib/tasks/treetop.rake +0 -10
@@ -6,7 +6,7 @@ module Mail
6
6
 
7
7
  def parse(val = value)
8
8
  unless val.blank?
9
- @tree = AddressList.new(encode_if_needed(val))
9
+ @address_list = AddressList.new(encode_if_needed(val))
10
10
  else
11
11
  nil
12
12
  end
@@ -20,44 +20,40 @@ module Mail
20
20
  Encodings.address_encode(val, charset)
21
21
  end
22
22
 
23
- # Allows you to iterate through each address object in the syntax tree
23
+ # Allows you to iterate through each address object in the address_list
24
24
  def each
25
- tree.addresses.each do |address|
25
+ address_list.addresses.each do |address|
26
26
  yield(address)
27
27
  end
28
28
  end
29
29
 
30
30
  # Returns the address string of all the addresses in the address list
31
31
  def addresses
32
- list = tree.addresses.map { |a| a.address }
32
+ list = address_list.addresses.map { |a| a.address }
33
33
  Mail::AddressContainer.new(self, list)
34
34
  end
35
35
 
36
36
  # Returns the formatted string of all the addresses in the address list
37
37
  def formatted
38
- list = tree.addresses.map { |a| a.format }
38
+ list = address_list.addresses.map { |a| a.format }
39
39
  Mail::AddressContainer.new(self, list)
40
40
  end
41
41
 
42
42
  # Returns the display name of all the addresses in the address list
43
43
  def display_names
44
- list = tree.addresses.map { |a| a.display_name }
44
+ list = address_list.addresses.map { |a| a.display_name }
45
45
  Mail::AddressContainer.new(self, list)
46
46
  end
47
47
 
48
48
  # Returns the actual address objects in the address list
49
49
  def addrs
50
- list = tree.addresses
50
+ list = address_list.addresses
51
51
  Mail::AddressContainer.new(self, list)
52
52
  end
53
53
 
54
54
  # Returns a hash of group name => address strings for the address list
55
55
  def groups
56
- @groups = Hash.new
57
- tree.group_recipients.each do |group|
58
- @groups[group.group_name.text_value.to_str] = get_group_addresses(group.group_list)
59
- end
60
- @groups
56
+ address_list.addresses_grouped_by_group
61
57
  end
62
58
 
63
59
  # Returns the addresses that are part of groups
@@ -77,7 +73,7 @@ module Mail
77
73
 
78
74
  # Returns the name of all the groups in a string
79
75
  def group_names # :nodoc:
80
- tree.group_names
76
+ address_list.group_names
81
77
  end
82
78
 
83
79
  def default
@@ -104,7 +100,7 @@ module Mail
104
100
 
105
101
  def do_encode(field_name)
106
102
  return '' if value.blank?
107
- address_array = tree.addresses.reject { |a| encoded_group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
103
+ address_array = address_list.addresses.reject { |a| encoded_group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
108
104
  address_text = address_array.join(", \r\n\s")
109
105
  group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.encoded }.join(", \r\n\s")};" }
110
106
  group_text = group_array.join(" \r\n\s")
@@ -114,7 +110,7 @@ module Mail
114
110
 
115
111
  def do_decode
116
112
  return nil if value.blank?
117
- address_array = tree.addresses.reject { |a| decoded_group_addresses.include?(a.decoded) }.map { |a| a.decoded }
113
+ address_array = address_list.addresses.reject { |a| decoded_group_addresses.include?(a.decoded) }.map { |a| a.decoded }
118
114
  address_text = address_array.join(", ")
119
115
  group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.decoded }.join(", ")};" }
120
116
  group_text = group_array.join(" ")
@@ -122,15 +118,14 @@ module Mail
122
118
  return_array.join(", ")
123
119
  end
124
120
 
125
- # Returns the syntax tree of the Addresses
126
- def tree # :nodoc:
127
- @tree ||= AddressList.new(value)
121
+ def address_list # :nodoc:
122
+ @address_list ||= AddressList.new(value)
128
123
  end
129
124
 
130
125
  def get_group_addresses(group_list)
131
126
  if group_list.respond_to?(:addresses)
132
- group_list.addresses.map do |address_tree|
133
- Mail::Address.new(address_tree)
127
+ group_list.addresses.map do |address|
128
+ Mail::Address.new(address)
134
129
  end
135
130
  else
136
131
  []
@@ -13,7 +13,6 @@ module Mail
13
13
  def parse(val = value)
14
14
  unless val.blank?
15
15
  @element = Mail::DateTimeElement.new(val)
16
- @tree = @element.tree
17
16
  else
18
17
  nil
19
18
  end
@@ -32,11 +31,5 @@ module Mail
32
31
  def element
33
32
  @element ||= Mail::DateTimeElement.new(value)
34
33
  end
35
-
36
- # Returns the syntax tree of the Date
37
- def tree
38
- @tree ||= element.tree
39
- end
40
-
41
34
  end
42
35
  end
@@ -43,7 +43,7 @@ module Mail
43
43
  if value.is_a?(Array)
44
44
  value
45
45
  else
46
- value.to_s.gsub(/#{field_name}:\s+/i, '')
46
+ value.to_s.sub(/#{field_name}:\s+/i, '')
47
47
  end
48
48
  end
49
49
 
@@ -23,12 +23,6 @@ module Mail
23
23
  end
24
24
  end
25
25
 
26
- def tree
27
- STDERR.puts("tree is deprecated. Please use encoding to get parse result\n#{caller}")
28
- @element ||= Mail::ContentTransferEncodingElement.new(value)
29
- @tree ||= @element.tree
30
- end
31
-
32
26
  def element
33
27
  @element ||= Mail::ContentTransferEncodingElement.new(value)
34
28
  end
@@ -47,7 +47,7 @@ module Mail
47
47
  end
48
48
 
49
49
  def address
50
- tree.addresses.first
50
+ address_list.addresses.first
51
51
  end
52
52
 
53
53
  def encoded
@@ -48,7 +48,7 @@ module Mail
48
48
  end
49
49
 
50
50
  def address
51
- tree.addresses.first
51
+ address_list.addresses.first
52
52
  end
53
53
 
54
54
  def encoded
@@ -144,6 +144,7 @@ module Mail
144
144
  limit = 78 - prepend
145
145
  limit = limit - 7 - encoding.length if should_encode
146
146
  line = ""
147
+ first_word = true
147
148
  while !words.empty?
148
149
  break unless word = words.first.dup
149
150
  word.encode!(charset) if charset && word.respond_to?(:encode!)
@@ -158,7 +159,12 @@ module Mail
158
159
  # Remove the word from the queue ...
159
160
  words.shift
160
161
  # Add word separator
161
- line << " " unless (line.empty? || should_encode)
162
+ if first_word
163
+ first_word = false
164
+ else
165
+ line << " " if !should_encode
166
+ end
167
+
162
168
  # ... add it in encoded form to the current line
163
169
  line << word
164
170
  end
data/lib/mail/header.rb CHANGED
@@ -48,11 +48,15 @@ module Mail
48
48
  # these cases, please make a patch and send it in, or at the least, send
49
49
  # me the example so we can fix it.
50
50
  def initialize(header_text = nil, charset = nil)
51
- @errors = []
52
51
  @charset = charset
53
52
  self.raw_source = header_text.to_crlf.lstrip
54
53
  split_header if header_text
55
54
  end
55
+
56
+ def initialize_copy(original)
57
+ super
58
+ @fields = @fields.dup
59
+ end
56
60
 
57
61
  # The preserved raw source of the header as you passed it in, untouched
58
62
  # for your Regexing glory.
@@ -91,7 +95,6 @@ module Mail
91
95
  unfolded_fields[0..(self.class.maximum_amount-1)].each do |field|
92
96
 
93
97
  field = Field.new(field, nil, charset)
94
- field.errors.each { |error| self.errors << error }
95
98
  if limited_field?(field.name) && (selected = select_field_for(field.name)) && selected.any?
96
99
  selected.first.update(field.name, field.value)
97
100
  else
@@ -102,7 +105,7 @@ module Mail
102
105
  end
103
106
 
104
107
  def errors
105
- @errors
108
+ @fields.map(&:errors).flatten(1)
106
109
  end
107
110
 
108
111
  # 3.6. Field definitions
@@ -177,7 +180,7 @@ module Mail
177
180
  if dasherize(fn) == "content-type"
178
181
  # Update charset if specified in Content-Type
179
182
  params = self[:content_type].parameters rescue nil
180
- @charset = params && params[:charset]
183
+ @charset = params[:charset] if params && params[:charset]
181
184
  end
182
185
  end
183
186
 
@@ -246,27 +249,10 @@ module Mail
246
249
  @raw_source = val
247
250
  end
248
251
 
249
- # 2.2.3. Long Header Fields
250
- #
251
- # The process of moving from this folded multiple-line representation
252
- # of a header field to its single line representation is called
253
- # "unfolding". Unfolding is accomplished by simply removing any CRLF
254
- # that is immediately followed by WSP. Each header field should be
255
- # treated in its unfolded form for further syntactic and semantic
256
- # evaluation.
257
- def unfold(string)
258
- string.gsub(/#{CRLF}#{WSP}+/, ' ').gsub(/#{WSP}+/, ' ')
259
- end
260
-
261
- # Returns the header with all the folds removed
262
- def unfolded_header
263
- @unfolded_header ||= unfold(raw_source)
264
- end
265
-
266
252
  # Splits an unfolded and line break cleaned header into individual field
267
253
  # strings.
268
254
  def split_header
269
- self.fields = unfolded_header.split(CRLF)
255
+ self.fields = raw_source.split(HEADER_SPLIT)
270
256
  end
271
257
 
272
258
  def select_field_for(name)
data/lib/mail/mail.rb CHANGED
@@ -206,6 +206,12 @@ module Mail
206
206
  end
207
207
  end
208
208
 
209
+ # Unregister the given observer, allowing mail to resume operations
210
+ # without it.
211
+ def self.unregister_observer(observer)
212
+ @@delivery_notification_observers.delete(observer)
213
+ end
214
+
209
215
  # You can register an object to be given every mail object that will be sent,
210
216
  # before it is sent. So if you want to add special headers or modify any
211
217
  # email that gets sent through the Mail library, you can do so.
@@ -219,6 +225,12 @@ module Mail
219
225
  end
220
226
  end
221
227
 
228
+ # Unregister the given interceptor, allowing mail to resume operations
229
+ # without it.
230
+ def self.unregister_interceptor(interceptor)
231
+ @@delivery_interceptors.delete(interceptor)
232
+ end
233
+
222
234
  def self.inform_observers(mail)
223
235
  @@delivery_notification_observers.each do |observer|
224
236
  observer.delivered_email(mail)
@@ -29,6 +29,29 @@ module Mail
29
29
  self
30
30
  end
31
31
 
32
+ def cc(recipient_or_list)
33
+ @copy_recipients ||= []
34
+
35
+ if recipient_or_list.kind_of?(Array)
36
+ @copy_recipients += recipient_or_list
37
+ else
38
+ @copy_recipients << recipient_or_list
39
+ end
40
+ self
41
+ end
42
+
43
+ def bcc(recipient_or_list)
44
+ @blind_copy_recipients ||= []
45
+
46
+ if recipient_or_list.kind_of?(Array)
47
+ @blind_copy_recipients += recipient_or_list
48
+ else
49
+ @blind_copy_recipients << recipient_or_list
50
+ end
51
+ self
52
+ end
53
+
54
+
32
55
  def with_subject(subject)
33
56
  @subject = subject
34
57
  self
@@ -73,7 +96,7 @@ module Mail
73
96
  def filter_matched_deliveries(deliveries)
74
97
  candidate_deliveries = deliveries
75
98
 
76
- %w(sender recipients subject subject_matcher body body_matcher).each do |modifier_name|
99
+ %w(sender recipients copy_recipients blind_copy_recipients subject subject_matcher body body_matcher).each do |modifier_name|
77
100
  next unless instance_variable_defined?("@#{modifier_name}")
78
101
  candidate_deliveries = candidate_deliveries.select{|matching_delivery| self.send("matches_on_#{modifier_name}?", matching_delivery)}
79
102
  end
@@ -89,6 +112,14 @@ module Mail
89
112
  @recipients.all? {|recipient| delivery.to.include?(recipient) }
90
113
  end
91
114
 
115
+ def matches_on_copy_recipients?(delivery)
116
+ @copy_recipients.all? {|recipient| delivery.cc.include?(recipient) }
117
+ end
118
+
119
+ def matches_on_blind_copy_recipients?(delivery)
120
+ @blind_copy_recipients.all? {|recipient| delivery.bcc.include?(recipient) }
121
+ end
122
+
92
123
  def matches_on_subject?(delivery)
93
124
  delivery.subject == @subject
94
125
  end
@@ -109,6 +140,8 @@ module Mail
109
140
  result = ''
110
141
  result += "from #{@sender} " if instance_variable_defined?('@sender')
111
142
  result += "to #{@recipients.inspect} " if instance_variable_defined?('@recipients')
143
+ result += "cc #{@copy_recipients.inspect} " if instance_variable_defined?('@copy_recipients')
144
+ result += "bcc #{@blind_copy_recipients.inspect} " if instance_variable_defined?('@blind_copy_recipients')
112
145
  result += "with subject \"#{@subject}\" " if instance_variable_defined?('@subject')
113
146
  result += "with subject matching \"#{@subject_matcher}\" " if instance_variable_defined?('@subject_matcher')
114
147
  result += "with body \"#{@body}\" " if instance_variable_defined?('@body')
data/lib/mail/message.rb CHANGED
@@ -240,7 +240,7 @@ module Mail
240
240
  # This method bypasses checking perform_deliveries and raise_delivery_errors,
241
241
  # so use with caution.
242
242
  #
243
- # It still however fires off the intercepters and calls the observers callbacks if they are defined.
243
+ # It still however fires off the interceptors and calls the observers callbacks if they are defined.
244
244
  #
245
245
  # Returns self
246
246
  def deliver!
@@ -353,17 +353,23 @@ module Mail
353
353
  return false unless other.respond_to?(:encoded)
354
354
 
355
355
  if self.message_id && other.message_id
356
- result = (self.encoded == other.encoded)
356
+ self.encoded == other.encoded
357
357
  else
358
358
  self_message_id, other_message_id = self.message_id, other.message_id
359
- self.message_id, other.message_id = '<temp@test>', '<temp@test>'
360
- result = self.encoded == other.encoded
361
- self.message_id = "<#{self_message_id}>" if self_message_id
362
- other.message_id = "<#{other_message_id}>" if other_message_id
363
- result
359
+ begin
360
+ self.message_id, other.message_id = '<temp@test>', '<temp@test>'
361
+ self.encoded == other.encoded
362
+ ensure
363
+ self.message_id, other.message_id = self_message_id, other_message_id
364
+ end
364
365
  end
365
366
  end
366
367
 
368
+ def initialize_copy(original)
369
+ super
370
+ @header = @header.dup
371
+ end
372
+
367
373
  # Provides access to the raw source of the message as it was when it
368
374
  # was instantiated. This is set at initialization and so is untouched
369
375
  # by the parsers or decoder / encoders
@@ -1388,7 +1394,7 @@ module Mail
1388
1394
  header.has_date?
1389
1395
  end
1390
1396
 
1391
- # Returns true if the message has a Date field, the field may or may
1397
+ # Returns true if the message has a Mime-Version field, the field may or may
1392
1398
  # not have a value, but the field exists or not.
1393
1399
  def has_mime_version?
1394
1400
  header.has_mime_version?
@@ -1594,7 +1600,7 @@ module Mail
1594
1600
  end
1595
1601
 
1596
1602
  # Returns an AttachmentsList object, which holds all of the attachments in
1597
- # the receiver object (either the entier email or a part within) and all
1603
+ # the receiver object (either the entire email or a part within) and all
1598
1604
  # of its descendants.
1599
1605
  #
1600
1606
  # It also allows you to add attachments to the mail object directly, like so:
@@ -1974,8 +1980,9 @@ module Mail
1974
1980
  end
1975
1981
 
1976
1982
  def raw_source=(value)
1977
- value.force_encoding("binary") if RUBY_VERSION >= "1.9.1"
1978
1983
  @raw_source = value.to_crlf
1984
+ @raw_source.force_encoding("binary") if RUBY_VERSION >= "1.9.1"
1985
+ @raw_source
1979
1986
  end
1980
1987
 
1981
1988
  # see comments to body=. We take data and process it lazily
@@ -2128,7 +2135,7 @@ module Mail
2128
2135
  if perform_deliveries
2129
2136
  delivery_method.deliver!(self)
2130
2137
  end
2131
- rescue Exception => e # Net::SMTP errors or sendmail pipe errors
2138
+ rescue => e # Net::SMTP errors or sendmail pipe errors
2132
2139
  raise e if raise_delivery_errors
2133
2140
  end
2134
2141
  end
@@ -341,7 +341,7 @@ module Mail
341
341
  def load
342
342
  begin
343
343
  @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
344
- rescue Exception => e
344
+ rescue => e
345
345
  raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), Mail::Multibyte is unusable")
346
346
  end
347
347
 
@@ -36,13 +36,17 @@ module Mail
36
36
  #
37
37
  # mail.deliver!
38
38
  class Exim < Sendmail
39
- DEFAULTS = {
40
- :location => '/usr/sbin/exim',
41
- :arguments => '-i -t'
42
- }
39
+ def initialize(values)
40
+ self.settings = { :location => '/usr/sbin/exim',
41
+ :arguments => '-i -t' }.merge(values)
42
+ end
43
43
 
44
- def self.call(path, arguments, destinations, encoded_message)
45
- super path, arguments, nil, encoded_message
44
+ def self.call(path, arguments, destinations, mail)
45
+ popen "#{path} #{arguments}" do |io|
46
+ io.puts mail.encoded.to_lf
47
+ io.flush
48
+ end
46
49
  end
50
+
47
51
  end
48
52
  end