mail 2.2.5 → 2.2.19

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 (152) hide show
  1. data/CHANGELOG.rdoc +163 -7
  2. data/README.rdoc +56 -65
  3. data/Rakefile +31 -6
  4. data/lib/VERSION +2 -2
  5. data/lib/mail/attachments_list.rb +4 -4
  6. data/lib/mail/body.rb +6 -2
  7. data/lib/mail/configuration.rb +7 -1
  8. data/lib/mail/core_extensions/shellwords.rb +55 -0
  9. data/lib/mail/core_extensions/smtp.rb +24 -0
  10. data/lib/mail/elements/address.rb +6 -6
  11. data/lib/mail/elements/content_disposition_element.rb +1 -1
  12. data/lib/mail/elements/content_type_element.rb +2 -2
  13. data/lib/mail/encodings.rb +55 -57
  14. data/lib/mail/field.rb +2 -1
  15. data/lib/mail/field_list.rb +1 -1
  16. data/lib/mail/fields/common/common_field.rb +10 -9
  17. data/lib/mail/fields/common/common_message_id.rb +6 -5
  18. data/lib/mail/fields/common/parameter_hash.rb +14 -4
  19. data/lib/mail/fields/content_disposition_field.rb +1 -1
  20. data/lib/mail/fields/content_type_field.rb +41 -28
  21. data/lib/mail/fields/date_field.rb +3 -1
  22. data/lib/mail/fields/received_field.rb +11 -3
  23. data/lib/mail/fields/resent_date_field.rb +1 -1
  24. data/lib/mail/fields/return_path_field.rb +1 -0
  25. data/lib/mail/fields/unstructured_field.rb +4 -1
  26. data/lib/mail/header.rb +8 -5
  27. data/lib/mail/mail.rb +71 -57
  28. data/lib/mail/message.rb +518 -391
  29. data/lib/mail/network/delivery_methods/sendmail.rb +15 -15
  30. data/lib/mail/network/delivery_methods/smtp.rb +33 -6
  31. data/lib/mail/network/delivery_methods/smtp_connection.rb +74 -0
  32. data/lib/mail/network/retriever_methods/base.rb +63 -0
  33. data/lib/mail/network/retriever_methods/imap.rb +147 -7
  34. data/lib/mail/network/retriever_methods/pop3.rb +25 -44
  35. data/lib/mail/network/retriever_methods/test_retriever.rb +40 -0
  36. data/lib/mail/network.rb +4 -0
  37. data/lib/mail/parsers/address_lists.rb +2 -2
  38. data/lib/mail/parsers/address_lists.treetop +2 -2
  39. data/lib/mail/parsers/content_disposition.rb +166 -18
  40. data/lib/mail/parsers/content_disposition.treetop +1 -1
  41. data/lib/mail/parsers/content_type.rb +477 -49
  42. data/lib/mail/parsers/content_type.treetop +12 -2
  43. data/lib/mail/parsers/rfc2822.rb +58 -35
  44. data/lib/mail/parsers/rfc2822.treetop +2 -2
  45. data/lib/mail/part.rb +2 -2
  46. data/lib/mail/parts_list.rb +16 -8
  47. data/lib/mail/patterns.rb +7 -2
  48. data/lib/mail/utilities.rb +31 -1
  49. data/lib/mail/version.rb +10 -8
  50. data/lib/mail/version_specific/ruby_1_8.rb +2 -2
  51. data/lib/mail/version_specific/ruby_1_9.rb +29 -8
  52. data/lib/mail.rb +8 -4
  53. metadata +44 -110
  54. data/lib/mail/attachments_list.rbc +0 -1983
  55. data/lib/mail/body.rbc +0 -3809
  56. data/lib/mail/configuration.rbc +0 -1112
  57. data/lib/mail/core_extensions/nil.rbc +0 -244
  58. data/lib/mail/core_extensions/string.rbc +0 -0
  59. data/lib/mail/elements/address.rbc +0 -4112
  60. data/lib/mail/elements/address_list.rbc +0 -1309
  61. data/lib/mail/elements/content_disposition_element.rbc +0 -701
  62. data/lib/mail/elements/content_location_element.rbc +0 -573
  63. data/lib/mail/elements/content_transfer_encoding_element.rbc +0 -535
  64. data/lib/mail/elements/content_type_element.rbc +0 -786
  65. data/lib/mail/elements/date_time_element.rbc +0 -583
  66. data/lib/mail/elements/envelope_from_element.rbc +0 -771
  67. data/lib/mail/elements/message_ids_element.rbc +0 -740
  68. data/lib/mail/elements/mime_version_element.rbc +0 -583
  69. data/lib/mail/elements/phrase_list.rbc +0 -562
  70. data/lib/mail/elements/received_element.rbc +0 -725
  71. data/lib/mail/elements.rbc +0 -362
  72. data/lib/mail/encodings/7bit.rbc +0 -538
  73. data/lib/mail/encodings/8bit.rbc +0 -541
  74. data/lib/mail/encodings/base64.rbc +0 -629
  75. data/lib/mail/encodings/binary.rbc +0 -529
  76. data/lib/mail/encodings/quoted_printable.rbc +0 -766
  77. data/lib/mail/encodings/transfer_encoding.rbc +0 -1134
  78. data/lib/mail/encodings.rbc +0 -0
  79. data/lib/mail/envelope.rbc +0 -719
  80. data/lib/mail/field.rbc +0 -4708
  81. data/lib/mail/field_list.rbc +0 -518
  82. data/lib/mail/fields/bcc_field.rbc +0 -564
  83. data/lib/mail/fields/cc_field.rbc +0 -579
  84. data/lib/mail/fields/comments_field.rbc +0 -383
  85. data/lib/mail/fields/common/address_container.rbc +0 -363
  86. data/lib/mail/fields/common/common_address.rbc +0 -3550
  87. data/lib/mail/fields/common/common_date.rbc +0 -908
  88. data/lib/mail/fields/common/common_field.rbc +0 -973
  89. data/lib/mail/fields/common/common_message_id.rbc +0 -1051
  90. data/lib/mail/fields/common/parameter_hash.rbc +0 -1335
  91. data/lib/mail/fields/content_description_field.rbc +0 -396
  92. data/lib/mail/fields/content_disposition_field.rbc +0 -1440
  93. data/lib/mail/fields/content_id_field.rbc +0 -1236
  94. data/lib/mail/fields/content_location_field.rbc +0 -892
  95. data/lib/mail/fields/content_transfer_encoding_field.rbc +0 -1184
  96. data/lib/mail/fields/content_type_field.rbc +0 -3958
  97. data/lib/mail/fields/date_field.rbc +0 -712
  98. data/lib/mail/fields/from_field.rbc +0 -579
  99. data/lib/mail/fields/in_reply_to_field.rbc +0 -579
  100. data/lib/mail/fields/keywords_field.rbc +0 -979
  101. data/lib/mail/fields/message_id_field.rbc +0 -1008
  102. data/lib/mail/fields/mime_version_field.rbc +0 -1107
  103. data/lib/mail/fields/optional_field.rbc +0 -153
  104. data/lib/mail/fields/received_field.rbc +0 -1137
  105. data/lib/mail/fields/references_field.rbc +0 -574
  106. data/lib/mail/fields/reply_to_field.rbc +0 -579
  107. data/lib/mail/fields/resent_bcc_field.rbc +0 -579
  108. data/lib/mail/fields/resent_cc_field.rbc +0 -579
  109. data/lib/mail/fields/resent_date_field.rbc +0 -656
  110. data/lib/mail/fields/resent_from_field.rbc +0 -579
  111. data/lib/mail/fields/resent_message_id_field.rbc +0 -639
  112. data/lib/mail/fields/resent_sender_field.rbc +0 -731
  113. data/lib/mail/fields/resent_to_field.rbc +0 -579
  114. data/lib/mail/fields/return_path_field.rbc +0 -737
  115. data/lib/mail/fields/sender_field.rbc +0 -799
  116. data/lib/mail/fields/structured_field.rbc +0 -671
  117. data/lib/mail/fields/subject_field.rbc +0 -378
  118. data/lib/mail/fields/to_field.rbc +0 -579
  119. data/lib/mail/fields/unstructured_field.rbc +0 -2292
  120. data/lib/mail/fields.rbc +0 -782
  121. data/lib/mail/header.rbc +0 -3720
  122. data/lib/mail/mail.rbc +0 -2168
  123. data/lib/mail/message.rbc +0 -19034
  124. data/lib/mail/network/delivery_methods/file_delivery.rbc +0 -722
  125. data/lib/mail/network/delivery_methods/sendmail.rbc +0 -800
  126. data/lib/mail/network/delivery_methods/smtp.rbc +0 -1081
  127. data/lib/mail/network/delivery_methods/test_mailer.rbc +0 -552
  128. data/lib/mail/network/retriever_methods/pop3.rbc +0 -2447
  129. data/lib/mail/network.rbc +0 -236
  130. data/lib/mail/parsers/address_lists.rbc +0 -1307
  131. data/lib/mail/parsers/content_disposition.rbc +0 -5968
  132. data/lib/mail/parsers/content_location.rbc +0 -2166
  133. data/lib/mail/parsers/content_transfer_encoding.rbc +0 -2591
  134. data/lib/mail/parsers/content_type.rbc +0 -7949
  135. data/lib/mail/parsers/date_time.rbc +0 -1836
  136. data/lib/mail/parsers/envelope_from.rbc +0 -3106
  137. data/lib/mail/parsers/message_ids.rbc +0 -989
  138. data/lib/mail/parsers/mime_version.rbc +0 -2254
  139. data/lib/mail/parsers/phrase_lists.rbc +0 -989
  140. data/lib/mail/parsers/received.rbc +0 -1267
  141. data/lib/mail/parsers/rfc2045.rbc +0 -5614
  142. data/lib/mail/parsers/rfc2822.rbc +0 -74848
  143. data/lib/mail/parsers/rfc2822_obsolete.rbc +0 -55220
  144. data/lib/mail/part.rbc +0 -2314
  145. data/lib/mail/parts_list.rbc +0 -832
  146. data/lib/mail/patterns.rbc +0 -0
  147. data/lib/mail/utilities.rbc +0 -2377
  148. data/lib/mail/version.rbc +0 -450
  149. data/lib/mail/version_specific/ruby_1_8.rbc +0 -2496
  150. data/lib/mail.rbc +0 -1151
  151. data/lib/tasks/corpus.rake.compiled.rbc +0 -2195
  152. data/lib/tasks/treetop.rake.compiled.rbc +0 -297
data/lib/mail/message.rb CHANGED
@@ -1,41 +1,43 @@
1
1
  # encoding: utf-8
2
+ require "yaml"
3
+
2
4
  module Mail
3
5
  # The Message class provides a single point of access to all things to do with an
4
6
  # email message.
5
- #
7
+ #
6
8
  # You create a new email message by calling the Mail::Message.new method, or just
7
9
  # Mail.new
8
- #
10
+ #
9
11
  # A Message object by default has the following objects inside it:
10
- #
12
+ #
11
13
  # * A Header object which contians all information and settings of the header of the email
12
14
  # * Body object which contains all parts of the email that are not part of the header, this
13
15
  # includes any attachments, body text, MIME parts etc.
14
- #
16
+ #
15
17
  # ==Per RFC2822
16
- #
18
+ #
17
19
  # 2.1. General Description
18
- #
20
+ #
19
21
  # At the most basic level, a message is a series of characters. A
20
22
  # message that is conformant with this standard is comprised of
21
23
  # characters with values in the range 1 through 127 and interpreted as
22
24
  # US-ASCII characters [ASCII]. For brevity, this document sometimes
23
25
  # refers to this range of characters as simply "US-ASCII characters".
24
- #
26
+ #
25
27
  # Note: This standard specifies that messages are made up of characters
26
28
  # in the US-ASCII range of 1 through 127. There are other documents,
27
29
  # specifically the MIME document series [RFC2045, RFC2046, RFC2047,
28
30
  # RFC2048, RFC2049], that extend this standard to allow for values
29
31
  # outside of that range. Discussion of those mechanisms is not within
30
32
  # the scope of this standard.
31
- #
33
+ #
32
34
  # Messages are divided into lines of characters. A line is a series of
33
35
  # characters that is delimited with the two characters carriage-return
34
36
  # and line-feed; that is, the carriage return (CR) character (ASCII
35
37
  # value 13) followed immediately by the line feed (LF) character (ASCII
36
38
  # value 10). (The carriage-return/line-feed pair is usually written in
37
39
  # this document as "CRLF".)
38
- #
40
+ #
39
41
  # A message consists of header fields (collectively called "the header
40
42
  # of the message") followed, optionally, by a body. The header is a
41
43
  # sequence of lines of characters with special syntax as defined in
@@ -43,82 +45,87 @@ module Mail
43
45
  # follows the header and is separated from the header by an empty line
44
46
  # (i.e., a line with nothing preceding the CRLF).
45
47
  class Message
46
-
48
+
47
49
  include Patterns
48
50
  include Utilities
49
51
 
50
52
  # ==Making an email
51
- #
53
+ #
52
54
  # You can make an new mail object via a block, passing a string, file or direct assignment.
53
- #
55
+ #
54
56
  # ===Making an email via a block
55
- #
57
+ #
56
58
  # mail = Mail.new do
57
59
  # from 'mikel@test.lindsaar.net'
58
60
  # to 'you@test.lindsaar.net'
59
61
  # subject 'This is a test email'
60
62
  # body File.read('body.txt')
61
63
  # end
62
- #
64
+ #
63
65
  # mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
64
66
  #
65
67
  # ===Making an email via passing a string
66
- #
68
+ #
67
69
  # mail = Mail.new("To: mikel@test.lindsaar.net\r\nSubject: Hello\r\n\r\nHi there!")
68
70
  # mail.body.to_s #=> 'Hi there!'
69
71
  # mail.subject #=> 'Hello'
70
72
  # mail.to #=> 'mikel@test.lindsaar.net'
71
- #
73
+ #
72
74
  # ===Making an email from a file
73
- #
75
+ #
74
76
  # mail = Mail.read('path/to/file.eml')
75
77
  # mail.body.to_s #=> 'Hi there!'
76
78
  # mail.subject #=> 'Hello'
77
79
  # mail.to #=> 'mikel@test.lindsaar.net'
78
- #
80
+ #
79
81
  # ===Making an email via assignment
80
- #
82
+ #
81
83
  # You can assign values to a mail object via four approaches:
82
- #
84
+ #
83
85
  # * Message#field_name=(value)
84
86
  # * Message#field_name(value)
85
87
  # * Message#['field_name']=(value)
86
88
  # * Message#[:field_name]=(value)
87
- #
89
+ #
88
90
  # Examples:
89
- #
91
+ #
90
92
  # mail = Mail.new
91
93
  # mail['from'] = 'mikel@test.lindsaar.net'
92
94
  # mail[:to] = 'you@test.lindsaar.net'
93
95
  # mail.subject 'This is a test email'
94
96
  # mail.body = 'This is a body'
95
- #
97
+ #
96
98
  # mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
97
- #
99
+ #
98
100
  def initialize(*args, &block)
99
101
  @body = nil
102
+ @body_raw = nil
103
+ @body_raw_index = nil
104
+ @separate_parts = false
100
105
  @text_part = nil
101
106
  @html_part = nil
102
107
  @errors = nil
103
108
  @header = nil
104
109
  @charset = 'UTF-8'
105
110
  @defaulted_charset = true
106
-
111
+
107
112
  @perform_deliveries = true
108
113
  @raise_delivery_errors = true
109
114
 
110
115
  @delivery_handler = nil
111
-
116
+
112
117
  @delivery_method = Mail.delivery_method.dup
113
-
118
+
114
119
  @transport_encoding = Mail::Encodings.get_encoding('7bit')
115
120
 
121
+ @mark_for_delete = false
122
+
116
123
  if args.flatten.first.respond_to?(:each_pair)
117
124
  init_with_hash(args.flatten.first)
118
125
  else
119
126
  init_with_string(args.flatten[0].to_s.strip)
120
127
  end
121
-
128
+
122
129
  if block_given?
123
130
  instance_eval(&block)
124
131
  end
@@ -127,12 +134,12 @@ module Mail
127
134
  end
128
135
 
129
136
  # If you assign a delivery handler, mail will call :deliver_mail on the
130
- # object you assign to delivery_handler, it will pass itself as the
137
+ # object you assign to delivery_handler, it will pass itself as the
131
138
  # single argument.
132
- #
139
+ #
133
140
  # If you define a delivery_handler, then you are responsible for the
134
141
  # following actions in the delivery cycle:
135
- #
142
+ #
136
143
  # * Appending the mail object to Mail.deliveries as you see fit.
137
144
  # * Checking the mail.perform_deliveries flag to decide if you should
138
145
  # actually call :deliver! the mail object or not.
@@ -140,28 +147,28 @@ module Mail
140
147
  # should raise delivery errors if they occur.
141
148
  # * Actually calling :deliver! (with the bang) on the mail object to
142
149
  # get it to deliver itself.
143
- #
150
+ #
144
151
  # A simplest implementation of a delivery_handler would be
145
- #
152
+ #
146
153
  # class MyObject
147
154
  #
148
155
  # def initialize
149
156
  # @mail = Mail.new('To: mikel@test.lindsaar.net')
150
157
  # @mail.delivery_handler = self
151
158
  # end
152
- #
159
+ #
153
160
  # attr_accessor :mail
154
- #
161
+ #
155
162
  # def deliver_mail(mail)
156
163
  # yield
157
164
  # end
158
165
  # end
159
- #
166
+ #
160
167
  # Then doing:
161
- #
168
+ #
162
169
  # obj = MyObject.new
163
170
  # obj.mail.deliver
164
- #
171
+ #
165
172
  # Would cause Mail to call obj.deliver_mail passing itself as a parameter,
166
173
  # which then can just yield and let Mail do it's own private do_delivery
167
174
  # method.
@@ -176,24 +183,24 @@ module Mail
176
183
  # mail.perform_deliveries = false
177
184
  # mail.deliver # Mail::SMTP not called here
178
185
  # Mail.deliveries.size #=> 0
179
- #
186
+ #
180
187
  # If you want to test and query the Mail.deliveries collection to see what
181
188
  # mail you sent, you should set perform_deliveries to true and use
182
189
  # the :test mail delivery_method:
183
- #
190
+ #
184
191
  # Mail.deliveries.size #=> 0
185
192
  # mail.delivery_method :test
186
193
  # mail.perform_deliveries = true
187
194
  # mail.deliver
188
195
  # Mail.deliveries.size #=> 1
189
- #
196
+ #
190
197
  # This setting is ignored by mail (though still available as a flag) if you
191
198
  # define a delivery_handler
192
199
  attr_accessor :perform_deliveries
193
200
 
194
201
  # If set to false, mail will silently catch and ignore any exceptions
195
202
  # raised through attempting to deliver an email.
196
- #
203
+ #
197
204
  # This setting is ignored by mail (though still available as a flag) if you
198
205
  # define a delivery_handler
199
206
  attr_accessor :raise_delivery_errors
@@ -202,19 +209,19 @@ module Mail
202
209
  STDERR.puts("Message#register_for_delivery_notification is deprecated, please call Mail.register_observer instead")
203
210
  Mail.register_observer(observer)
204
211
  end
205
-
212
+
206
213
  def inform_observers
207
214
  Mail.inform_observers(self)
208
215
  end
209
-
216
+
210
217
  def inform_interceptors
211
218
  Mail.inform_interceptors(self)
212
219
  end
213
-
220
+
214
221
  # Delivers an mail object.
215
- #
222
+ #
216
223
  # Examples:
217
- #
224
+ #
218
225
  # mail = Mail.read('file.eml')
219
226
  # mail.deliver
220
227
  def deliver
@@ -228,33 +235,71 @@ module Mail
228
235
  self
229
236
  end
230
237
 
231
- # This method bypasses checking perform_deliveries and raise_delivery_errors,
238
+ # This method bypasses checking perform_deliveries and raise_delivery_errors,
232
239
  # so use with caution.
233
- #
240
+ #
234
241
  # It still however fires callbacks to the observers if they are defined.
235
- #
242
+ #
236
243
  # Returns self
237
244
  def deliver!
238
- delivery_method.deliver!(self)
245
+ response = delivery_method.deliver!(self)
239
246
  inform_observers
240
- self
247
+ delivery_method.settings[:return_response] ? response : self
241
248
  end
242
-
249
+
243
250
  def delivery_method(method = nil, settings = {})
244
251
  unless method
245
252
  @delivery_method
246
253
  else
247
- @delivery_method = Mail::Configuration.instance.lookup_delivery_method(method).new(settings)
254
+ @delivery_method = Configuration.instance.lookup_delivery_method(method).new(settings)
255
+ end
256
+ end
257
+
258
+ def reply(*args, &block)
259
+ self.class.new.tap do |reply|
260
+ if message_id
261
+ bracketed_message_id = "<#{message_id}>"
262
+ reply.in_reply_to = bracketed_message_id
263
+ if !references.nil?
264
+ refs = [references].flatten.map { |r| "<#{r}>" }
265
+ refs << bracketed_message_id
266
+ reply.references = refs.join(' ')
267
+ elsif !in_reply_to.nil? && !in_reply_to.kind_of?(Array)
268
+ reply.references = "<#{in_reply_to}> #{bracketed_message_id}"
269
+ end
270
+ reply.references ||= bracketed_message_id
271
+ end
272
+ if subject
273
+ reply.subject = subject =~ /^Re:/i ? subject : "RE: #{subject}"
274
+ end
275
+ if reply_to || from
276
+ reply.to = self[reply_to ? :reply_to : :from].to_s
277
+ end
278
+ if to
279
+ reply.from = self[:to].formatted.first.to_s
280
+ end
281
+
282
+ unless args.empty?
283
+ if args.flatten.first.respond_to?(:each_pair)
284
+ reply.send(:init_with_hash, args.flatten.first)
285
+ else
286
+ reply.send(:init_with_string, args.flatten[0].to_s.strip)
287
+ end
288
+ end
289
+
290
+ if block_given?
291
+ reply.instance_eval(&block)
292
+ end
248
293
  end
249
294
  end
250
-
295
+
251
296
  # Provides the operator needed for sort et al.
252
- #
297
+ #
253
298
  # Compares this mail object with another mail object, this is done by date, so an
254
299
  # email that is older than another will appear first.
255
- #
300
+ #
256
301
  # Example:
257
- #
302
+ #
258
303
  # mail1 = Mail.new do
259
304
  # date(Time.now)
260
305
  # end
@@ -269,41 +314,41 @@ module Mail
269
314
  self.date <=> other.date
270
315
  end
271
316
  end
272
-
317
+
273
318
  # Two emails are the same if they have the same fields and body contents. One
274
319
  # gotcha here is that Mail will insert Message-IDs when calling encoded, so doing
275
320
  # mail1.encoded == mail2.encoded is most probably not going to return what you think
276
321
  # as the assigned Message-IDs by Mail (if not already defined as the same) will ensure
277
322
  # that the two objects are unique, and this comparison will ALWAYS return false.
278
- #
323
+ #
279
324
  # So the == operator has been defined like so: Two messages are the same if they have
280
325
  # the same content, ignoring the Message-ID field, unless BOTH emails have a defined and
281
326
  # different Message-ID value, then they are false.
282
- #
327
+ #
283
328
  # So, in practice the == operator works like this:
284
- #
329
+ #
285
330
  # m1 = Mail.new("Subject: Hello\r\n\r\nHello")
286
331
  # m2 = Mail.new("Subject: Hello\r\n\r\nHello")
287
332
  # m1 == m2 #=> true
288
- #
333
+ #
289
334
  # m1 = Mail.new("Subject: Hello\r\n\r\nHello")
290
335
  # m2 = Mail.new("Message-ID: <1234@test>\r\nSubject: Hello\r\n\r\nHello")
291
336
  # m1 == m2 #=> true
292
- #
337
+ #
293
338
  # m1 = Mail.new("Message-ID: <1234@test>\r\nSubject: Hello\r\n\r\nHello")
294
339
  # m2 = Mail.new("Subject: Hello\r\n\r\nHello")
295
340
  # m1 == m2 #=> true
296
- #
341
+ #
297
342
  # m1 = Mail.new("Message-ID: <1234@test>\r\nSubject: Hello\r\n\r\nHello")
298
343
  # m2 = Mail.new("Message-ID: <1234@test>\r\nSubject: Hello\r\n\r\nHello")
299
344
  # m1 == m2 #=> true
300
- #
345
+ #
301
346
  # m1 = Mail.new("Message-ID: <1234@test>\r\nSubject: Hello\r\n\r\nHello")
302
347
  # m2 = Mail.new("Message-ID: <DIFFERENT@test>\r\nSubject: Hello\r\n\r\nHello")
303
348
  # m1 == m2 #=> false
304
349
  def ==(other)
305
350
  return false unless other.respond_to?(:encoded)
306
-
351
+
307
352
  if self.message_id && other.message_id
308
353
  result = (self.encoded == other.encoded)
309
354
  else
@@ -315,44 +360,44 @@ module Mail
315
360
  result
316
361
  end
317
362
  end
318
-
363
+
319
364
  # Provides access to the raw source of the message as it was when it
320
365
  # was instantiated. This is set at initialization and so is untouched
321
366
  # by the parsers or decoder / encoders
322
367
  #
323
368
  # Example:
324
- #
369
+ #
325
370
  # mail = Mail.new('This is an invalid email message')
326
371
  # mail.raw_source #=> "This is an invalid email message"
327
372
  def raw_source
328
373
  @raw_source
329
374
  end
330
-
375
+
331
376
  # Sets the envelope from for the email
332
377
  def set_envelope( val )
333
378
  @raw_envelope = val
334
379
  @envelope = Mail::Envelope.new( val )
335
380
  end
336
-
381
+
337
382
  # The raw_envelope is the From mikel@test.lindsaar.net Mon May 2 16:07:05 2009
338
383
  # type field that you can see at the top of any email that has come
339
384
  # from a mailbox
340
385
  def raw_envelope
341
386
  @raw_envelope
342
387
  end
343
-
388
+
344
389
  def envelope_from
345
390
  @envelope ? @envelope.from : nil
346
391
  end
347
-
392
+
348
393
  def envelope_date
349
394
  @envelope ? @envelope.date : nil
350
395
  end
351
-
396
+
352
397
  # Sets the header of the message object.
353
- #
398
+ #
354
399
  # Example:
355
- #
400
+ #
356
401
  # mail.header = 'To: mikel@test.lindsaar.net\r\nFrom: Bob@bob.com'
357
402
  # mail.header #=> <#Mail::Header
358
403
  def header=(value)
@@ -361,80 +406,80 @@ module Mail
361
406
 
362
407
  # Returns the header object of the message object. Or, if passed
363
408
  # a parameter sets the value.
364
- #
409
+ #
365
410
  # Example:
366
- #
411
+ #
367
412
  # mail = Mail::Message.new('To: mikel\r\nFrom: you')
368
413
  # mail.header #=> #<Mail::Header:0x13ce14 @raw_source="To: mikel\r\nFr...
369
- #
414
+ #
370
415
  # mail.header #=> nil
371
416
  # mail.header 'To: mikel\r\nFrom: you'
372
417
  # mail.header #=> #<Mail::Header:0x13ce14 @raw_source="To: mikel\r\nFr...
373
418
  def header(value = nil)
374
419
  value ? self.header = value : @header
375
420
  end
376
-
421
+
377
422
  # Provides a way to set custom headers, by passing in a hash
378
423
  def headers(hash = {})
379
424
  hash.each_pair do |k,v|
380
425
  header[k] = v
381
426
  end
382
427
  end
383
-
428
+
384
429
  # Returns a list of parser errors on the header, each field that had an error
385
430
  # will be reparsed as an unstructured field to preserve the data inside, but
386
431
  # will not be used for further processing.
387
- #
432
+ #
388
433
  # It returns a nested array of [field_name, value, original_error_message]
389
434
  # per error found.
390
- #
435
+ #
391
436
  # Example:
392
- #
437
+ #
393
438
  # message = Mail.new("Content-Transfer-Encoding: weirdo\r\n")
394
439
  # message.errors.size #=> 1
395
440
  # message.errors.first[0] #=> "Content-Transfer-Encoding"
396
441
  # message.errors.first[1] #=> "weirdo"
397
442
  # message.errors.first[3] #=> <The original error message exception>
398
- #
443
+ #
399
444
  # This is a good first defence on detecting spam by the way. Some spammers send
400
445
  # invalid emails to try and get email parsers to give up parsing them.
401
446
  def errors
402
447
  header.errors
403
448
  end
404
-
405
- # Returns the Bcc value of the mail object as an array of strings of
449
+
450
+ # Returns the Bcc value of the mail object as an array of strings of
406
451
  # address specs.
407
452
  #
408
453
  # Example:
409
- #
454
+ #
410
455
  # mail.bcc = 'Mikel <mikel@test.lindsaar.net>'
411
456
  # mail.bcc #=> ['mikel@test.lindsaar.net']
412
457
  # mail.bcc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
413
458
  # mail.bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
414
- #
459
+ #
415
460
  # Also allows you to set the value by passing a value as a parameter
416
461
  #
417
462
  # Example:
418
- #
463
+ #
419
464
  # mail.bcc 'Mikel <mikel@test.lindsaar.net>'
420
465
  # mail.bcc #=> ['mikel@test.lindsaar.net']
421
- #
466
+ #
422
467
  # Additionally, you can append new addresses to the returned Array like
423
468
  # object.
424
- #
469
+ #
425
470
  # Example:
426
- #
471
+ #
427
472
  # mail.bcc 'Mikel <mikel@test.lindsaar.net>'
428
473
  # mail.bcc << 'ada@test.lindsaar.net'
429
474
  # mail.bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
430
475
  def bcc( val = nil )
431
476
  default :bcc, val
432
477
  end
433
-
478
+
434
479
  # Sets the Bcc value of the mail object, pass in a string of the field
435
480
  #
436
481
  # Example:
437
- #
482
+ #
438
483
  # mail.bcc = 'Mikel <mikel@test.lindsaar.net>'
439
484
  # mail.bcc #=> ['mikel@test.lindsaar.net']
440
485
  # mail.bcc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -442,40 +487,40 @@ module Mail
442
487
  def bcc=( val )
443
488
  header[:bcc] = val
444
489
  end
445
-
446
- # Returns the Cc value of the mail object as an array of strings of
490
+
491
+ # Returns the Cc value of the mail object as an array of strings of
447
492
  # address specs.
448
493
  #
449
494
  # Example:
450
- #
495
+ #
451
496
  # mail.cc = 'Mikel <mikel@test.lindsaar.net>'
452
497
  # mail.cc #=> ['mikel@test.lindsaar.net']
453
498
  # mail.cc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
454
499
  # mail.cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
455
- #
500
+ #
456
501
  # Also allows you to set the value by passing a value as a parameter
457
502
  #
458
503
  # Example:
459
- #
504
+ #
460
505
  # mail.cc 'Mikel <mikel@test.lindsaar.net>'
461
506
  # mail.cc #=> ['mikel@test.lindsaar.net']
462
- #
507
+ #
463
508
  # Additionally, you can append new addresses to the returned Array like
464
509
  # object.
465
- #
510
+ #
466
511
  # Example:
467
- #
512
+ #
468
513
  # mail.cc 'Mikel <mikel@test.lindsaar.net>'
469
514
  # mail.cc << 'ada@test.lindsaar.net'
470
515
  # mail.cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
471
516
  def cc( val = nil )
472
517
  default :cc, val
473
518
  end
474
-
519
+
475
520
  # Sets the Cc value of the mail object, pass in a string of the field
476
521
  #
477
522
  # Example:
478
- #
523
+ #
479
524
  # mail.cc = 'Mikel <mikel@test.lindsaar.net>'
480
525
  # mail.cc #=> ['mikel@test.lindsaar.net']
481
526
  # mail.cc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -483,71 +528,71 @@ module Mail
483
528
  def cc=( val )
484
529
  header[:cc] = val
485
530
  end
486
-
531
+
487
532
  def comments( val = nil )
488
533
  default :comments, val
489
534
  end
490
-
535
+
491
536
  def comments=( val )
492
537
  header[:comments] = val
493
538
  end
494
-
539
+
495
540
  def content_description( val = nil )
496
541
  default :content_description, val
497
542
  end
498
-
543
+
499
544
  def content_description=( val )
500
545
  header[:content_description] = val
501
546
  end
502
-
547
+
503
548
  def content_disposition( val = nil )
504
549
  default :content_disposition, val
505
550
  end
506
-
551
+
507
552
  def content_disposition=( val )
508
553
  header[:content_disposition] = val
509
554
  end
510
-
555
+
511
556
  def content_id( val = nil )
512
557
  default :content_id, val
513
558
  end
514
-
559
+
515
560
  def content_id=( val )
516
561
  header[:content_id] = val
517
562
  end
518
-
563
+
519
564
  def content_location( val = nil )
520
565
  default :content_location, val
521
566
  end
522
-
567
+
523
568
  def content_location=( val )
524
569
  header[:content_location] = val
525
570
  end
526
-
571
+
527
572
  def content_transfer_encoding( val = nil )
528
573
  default :content_transfer_encoding, val
529
574
  end
530
-
575
+
531
576
  def content_transfer_encoding=( val )
532
577
  header[:content_transfer_encoding] = val
533
578
  end
534
-
579
+
535
580
  def content_type( val = nil )
536
581
  default :content_type, val
537
582
  end
538
-
583
+
539
584
  def content_type=( val )
540
585
  header[:content_type] = val
541
586
  end
542
-
587
+
543
588
  def date( val = nil )
544
589
  default :date, val
545
590
  end
546
-
591
+
547
592
  def date=( val )
548
593
  header[:date] = val
549
594
  end
550
-
595
+
551
596
  def transport_encoding( val = nil)
552
597
  if val
553
598
  self.transport_encoding = val
@@ -559,40 +604,40 @@ module Mail
559
604
  def transport_encoding=( val )
560
605
  @transport_encoding = Mail::Encodings.get_encoding(val)
561
606
  end
562
-
563
- # Returns the From value of the mail object as an array of strings of
607
+
608
+ # Returns the From value of the mail object as an array of strings of
564
609
  # address specs.
565
610
  #
566
611
  # Example:
567
- #
612
+ #
568
613
  # mail.from = 'Mikel <mikel@test.lindsaar.net>'
569
614
  # mail.from #=> ['mikel@test.lindsaar.net']
570
615
  # mail.from = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
571
616
  # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
572
- #
617
+ #
573
618
  # Also allows you to set the value by passing a value as a parameter
574
619
  #
575
620
  # Example:
576
- #
621
+ #
577
622
  # mail.from 'Mikel <mikel@test.lindsaar.net>'
578
623
  # mail.from #=> ['mikel@test.lindsaar.net']
579
- #
624
+ #
580
625
  # Additionally, you can append new addresses to the returned Array like
581
626
  # object.
582
- #
627
+ #
583
628
  # Example:
584
- #
629
+ #
585
630
  # mail.from 'Mikel <mikel@test.lindsaar.net>'
586
631
  # mail.from << 'ada@test.lindsaar.net'
587
632
  # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
588
633
  def from( val = nil )
589
634
  default :from, val
590
635
  end
591
-
636
+
592
637
  # Sets the From value of the mail object, pass in a string of the field
593
638
  #
594
639
  # Example:
595
- #
640
+ #
596
641
  # mail.from = 'Mikel <mikel@test.lindsaar.net>'
597
642
  # mail.from #=> ['mikel@test.lindsaar.net']
598
643
  # mail.from = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -600,76 +645,76 @@ module Mail
600
645
  def from=( val )
601
646
  header[:from] = val
602
647
  end
603
-
648
+
604
649
  def in_reply_to( val = nil )
605
650
  default :in_reply_to, val
606
651
  end
607
-
652
+
608
653
  def in_reply_to=( val )
609
654
  header[:in_reply_to] = val
610
655
  end
611
-
656
+
612
657
  def keywords( val = nil )
613
658
  default :keywords, val
614
659
  end
615
-
660
+
616
661
  def keywords=( val )
617
662
  header[:keywords] = val
618
663
  end
619
-
664
+
620
665
  # Returns the Message-ID of the mail object. Note, per RFC 2822 the Message ID
621
666
  # consists of what is INSIDE the < > usually seen in the mail header, so this method
622
667
  # will return only what is inside.
623
- #
668
+ #
624
669
  # Example:
625
- #
670
+ #
626
671
  # mail.message_id = '<1234@message.id>'
627
672
  # mail.message_id #=> '1234@message.id'
628
- #
673
+ #
629
674
  # Also allows you to set the Message-ID by passing a string as a parameter
630
- #
675
+ #
631
676
  # mail.message_id '<1234@message.id>'
632
677
  # mail.message_id #=> '1234@message.id'
633
678
  def message_id( val = nil )
634
679
  default :message_id, val
635
680
  end
636
-
681
+
637
682
  # Sets the Message-ID. Note, per RFC 2822 the Message ID consists of what is INSIDE
638
683
  # the < > usually seen in the mail header, so this method will return only what is inside.
639
- #
684
+ #
640
685
  # mail.message_id = '<1234@message.id>'
641
686
  # mail.message_id #=> '1234@message.id'
642
687
  def message_id=( val )
643
688
  header[:message_id] = val
644
689
  end
645
-
690
+
646
691
  # Returns the MIME version of the email as a string
647
- #
692
+ #
648
693
  # Example:
649
- #
694
+ #
650
695
  # mail.mime_version = '1.0'
651
696
  # mail.mime_version #=> '1.0'
652
- #
697
+ #
653
698
  # Also allows you to set the MIME version by passing a string as a parameter.
654
- #
699
+ #
655
700
  # Example:
656
- #
701
+ #
657
702
  # mail.mime_version '1.0'
658
703
  # mail.mime_version #=> '1.0'
659
704
  def mime_version( val = nil )
660
705
  default :mime_version, val
661
706
  end
662
-
707
+
663
708
  # Sets the MIME version of the email by accepting a string
664
- #
709
+ #
665
710
  # Example:
666
- #
711
+ #
667
712
  # mail.mime_version = '1.0'
668
713
  # mail.mime_version #=> '1.0'
669
714
  def mime_version=( val )
670
715
  header[:mime_version] = val
671
716
  end
672
-
717
+
673
718
  def received( val = nil )
674
719
  if val
675
720
  header[:received] = val
@@ -677,52 +722,52 @@ module Mail
677
722
  header[:received]
678
723
  end
679
724
  end
680
-
725
+
681
726
  def received=( val )
682
727
  header[:received] = val
683
728
  end
684
-
729
+
685
730
  def references( val = nil )
686
731
  default :references, val
687
732
  end
688
-
733
+
689
734
  def references=( val )
690
735
  header[:references] = val
691
736
  end
692
-
693
- # Returns the Reply-To value of the mail object as an array of strings of
737
+
738
+ # Returns the Reply-To value of the mail object as an array of strings of
694
739
  # address specs.
695
740
  #
696
741
  # Example:
697
- #
742
+ #
698
743
  # mail.reply_to = 'Mikel <mikel@test.lindsaar.net>'
699
744
  # mail.reply_to #=> ['mikel@test.lindsaar.net']
700
745
  # mail.reply_to = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
701
746
  # mail.reply_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
702
- #
747
+ #
703
748
  # Also allows you to set the value by passing a value as a parameter
704
749
  #
705
750
  # Example:
706
- #
751
+ #
707
752
  # mail.reply_to 'Mikel <mikel@test.lindsaar.net>'
708
753
  # mail.reply_to #=> ['mikel@test.lindsaar.net']
709
- #
754
+ #
710
755
  # Additionally, you can append new addresses to the returned Array like
711
756
  # object.
712
- #
757
+ #
713
758
  # Example:
714
- #
759
+ #
715
760
  # mail.reply_to 'Mikel <mikel@test.lindsaar.net>'
716
761
  # mail.reply_to << 'ada@test.lindsaar.net'
717
762
  # mail.reply_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
718
763
  def reply_to( val = nil )
719
764
  default :reply_to, val
720
765
  end
721
-
766
+
722
767
  # Sets the Reply-To value of the mail object, pass in a string of the field
723
768
  #
724
769
  # Example:
725
- #
770
+ #
726
771
  # mail.reply_to = 'Mikel <mikel@test.lindsaar.net>'
727
772
  # mail.reply_to #=> ['mikel@test.lindsaar.net']
728
773
  # mail.reply_to = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -730,81 +775,81 @@ module Mail
730
775
  def reply_to=( val )
731
776
  header[:reply_to] = val
732
777
  end
733
-
734
- # Returns the Resent-Bcc value of the mail object as an array of strings of
778
+
779
+ # Returns the Resent-Bcc value of the mail object as an array of strings of
735
780
  # address specs.
736
- #
781
+ #
737
782
  # Example:
738
- #
783
+ #
739
784
  # mail.resent_bcc = 'Mikel <mikel@test.lindsaar.net>'
740
785
  # mail.resent_bcc #=> ['mikel@test.lindsaar.net']
741
786
  # mail.resent_bcc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
742
787
  # mail.resent_bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
743
- #
788
+ #
744
789
  # Also allows you to set the value by passing a value as a parameter
745
790
  #
746
791
  # Example:
747
- #
792
+ #
748
793
  # mail.resent_bcc 'Mikel <mikel@test.lindsaar.net>'
749
794
  # mail.resent_bcc #=> ['mikel@test.lindsaar.net']
750
- #
795
+ #
751
796
  # Additionally, you can append new addresses to the returned Array like
752
797
  # object.
753
- #
798
+ #
754
799
  # Example:
755
- #
800
+ #
756
801
  # mail.resent_bcc 'Mikel <mikel@test.lindsaar.net>'
757
802
  # mail.resent_bcc << 'ada@test.lindsaar.net'
758
803
  # mail.resent_bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
759
804
  def resent_bcc( val = nil )
760
805
  default :resent_bcc, val
761
806
  end
762
-
807
+
763
808
  # Sets the Resent-Bcc value of the mail object, pass in a string of the field
764
809
  #
765
810
  # Example:
766
- #
811
+ #
767
812
  # mail.resent_bcc = 'Mikel <mikel@test.lindsaar.net>'
768
813
  # mail.resent_bcc #=> ['mikel@test.lindsaar.net']
769
814
  # mail.resent_bcc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
770
- # mail.resent_bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
815
+ # mail.resent_bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
771
816
  def resent_bcc=( val )
772
817
  header[:resent_bcc] = val
773
818
  end
774
-
775
- # Returns the Resent-Cc value of the mail object as an array of strings of
819
+
820
+ # Returns the Resent-Cc value of the mail object as an array of strings of
776
821
  # address specs.
777
- #
822
+ #
778
823
  # Example:
779
- #
824
+ #
780
825
  # mail.resent_cc = 'Mikel <mikel@test.lindsaar.net>'
781
826
  # mail.resent_cc #=> ['mikel@test.lindsaar.net']
782
827
  # mail.resent_cc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
783
828
  # mail.resent_cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
784
- #
829
+ #
785
830
  # Also allows you to set the value by passing a value as a parameter
786
831
  #
787
832
  # Example:
788
- #
833
+ #
789
834
  # mail.resent_cc 'Mikel <mikel@test.lindsaar.net>'
790
835
  # mail.resent_cc #=> ['mikel@test.lindsaar.net']
791
- #
836
+ #
792
837
  # Additionally, you can append new addresses to the returned Array like
793
838
  # object.
794
- #
839
+ #
795
840
  # Example:
796
- #
841
+ #
797
842
  # mail.resent_cc 'Mikel <mikel@test.lindsaar.net>'
798
843
  # mail.resent_cc << 'ada@test.lindsaar.net'
799
844
  # mail.resent_cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
800
845
  def resent_cc( val = nil )
801
846
  default :resent_cc, val
802
847
  end
803
-
848
+
804
849
  # Sets the Resent-Cc value of the mail object, pass in a string of the field
805
850
  #
806
851
  # Example:
807
- #
852
+ #
808
853
  # mail.resent_cc = 'Mikel <mikel@test.lindsaar.net>'
809
854
  # mail.resent_cc #=> ['mikel@test.lindsaar.net']
810
855
  # mail.resent_cc = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -812,48 +857,48 @@ module Mail
812
857
  def resent_cc=( val )
813
858
  header[:resent_cc] = val
814
859
  end
815
-
860
+
816
861
  def resent_date( val = nil )
817
862
  default :resent_date, val
818
863
  end
819
-
864
+
820
865
  def resent_date=( val )
821
866
  header[:resent_date] = val
822
867
  end
823
-
824
- # Returns the Resent-From value of the mail object as an array of strings of
868
+
869
+ # Returns the Resent-From value of the mail object as an array of strings of
825
870
  # address specs.
826
871
  #
827
872
  # Example:
828
- #
873
+ #
829
874
  # mail.resent_from = 'Mikel <mikel@test.lindsaar.net>'
830
875
  # mail.resent_from #=> ['mikel@test.lindsaar.net']
831
876
  # mail.resent_from = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
832
877
  # mail.resent_from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
833
- #
878
+ #
834
879
  # Also allows you to set the value by passing a value as a parameter
835
880
  #
836
881
  # Example:
837
- #
882
+ #
838
883
  # mail.resent_from ['Mikel <mikel@test.lindsaar.net>']
839
884
  # mail.resent_from #=> 'mikel@test.lindsaar.net'
840
- #
885
+ #
841
886
  # Additionally, you can append new addresses to the returned Array like
842
887
  # object.
843
- #
888
+ #
844
889
  # Example:
845
- #
890
+ #
846
891
  # mail.resent_from 'Mikel <mikel@test.lindsaar.net>'
847
892
  # mail.resent_from << 'ada@test.lindsaar.net'
848
893
  # mail.resent_from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
849
894
  def resent_from( val = nil )
850
895
  default :resent_from, val
851
896
  end
852
-
897
+
853
898
  # Sets the Resent-From value of the mail object, pass in a string of the field
854
899
  #
855
900
  # Example:
856
- #
901
+ #
857
902
  # mail.resent_from = 'Mikel <mikel@test.lindsaar.net>'
858
903
  # mail.resent_from #=> ['mikel@test.lindsaar.net']
859
904
  # mail.resent_from = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -861,28 +906,28 @@ module Mail
861
906
  def resent_from=( val )
862
907
  header[:resent_from] = val
863
908
  end
864
-
909
+
865
910
  def resent_message_id( val = nil )
866
911
  default :resent_message_id, val
867
912
  end
868
-
913
+
869
914
  def resent_message_id=( val )
870
915
  header[:resent_message_id] = val
871
916
  end
872
-
917
+
873
918
  # Returns the Resent-Sender value of the mail object, as a single string of an address
874
919
  # spec. A sender per RFC 2822 must be a single address, so you can not append to
875
920
  # this address.
876
921
  #
877
922
  # Example:
878
- #
923
+ #
879
924
  # mail.resent_sender = 'Mikel <mikel@test.lindsaar.net>'
880
925
  # mail.resent_sender #=> 'mikel@test.lindsaar.net'
881
- #
926
+ #
882
927
  # Also allows you to set the value by passing a value as a parameter
883
928
  #
884
929
  # Example:
885
- #
930
+ #
886
931
  # mail.resent_sender 'Mikel <mikel@test.lindsaar.net>'
887
932
  # mail.resent_sender #=> 'mikel@test.lindsaar.net'
888
933
  def resent_sender( val = nil )
@@ -892,46 +937,46 @@ module Mail
892
937
  # Sets the Resent-Sender value of the mail object, pass in a string of the field
893
938
  #
894
939
  # Example:
895
- #
940
+ #
896
941
  # mail.sender = 'Mikel <mikel@test.lindsaar.net>'
897
942
  # mail.sender #=> 'mikel@test.lindsaar.net'
898
943
  def resent_sender=( val )
899
944
  header[:resent_sender] = val
900
945
  end
901
-
902
- # Returns the Resent-To value of the mail object as an array of strings of
946
+
947
+ # Returns the Resent-To value of the mail object as an array of strings of
903
948
  # address specs.
904
949
  #
905
950
  # Example:
906
- #
951
+ #
907
952
  # mail.resent_to = 'Mikel <mikel@test.lindsaar.net>'
908
953
  # mail.resent_to #=> ['mikel@test.lindsaar.net']
909
954
  # mail.resent_to = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
910
955
  # mail.resent_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
911
- #
956
+ #
912
957
  # Also allows you to set the value by passing a value as a parameter
913
958
  #
914
959
  # Example:
915
- #
960
+ #
916
961
  # mail.resent_to 'Mikel <mikel@test.lindsaar.net>'
917
962
  # mail.resent_to #=> ['mikel@test.lindsaar.net']
918
- #
963
+ #
919
964
  # Additionally, you can append new addresses to the returned Array like
920
965
  # object.
921
- #
966
+ #
922
967
  # Example:
923
- #
968
+ #
924
969
  # mail.resent_to 'Mikel <mikel@test.lindsaar.net>'
925
970
  # mail.resent_to << 'ada@test.lindsaar.net'
926
971
  # mail.resent_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
927
972
  def resent_to( val = nil )
928
973
  default :resent_to, val
929
974
  end
930
-
975
+
931
976
  # Sets the Resent-To value of the mail object, pass in a string of the field
932
977
  #
933
978
  # Example:
934
- #
979
+ #
935
980
  # mail.resent_to = 'Mikel <mikel@test.lindsaar.net>'
936
981
  # mail.resent_to #=> ['mikel@test.lindsaar.net']
937
982
  # mail.resent_to = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -939,107 +984,107 @@ module Mail
939
984
  def resent_to=( val )
940
985
  header[:resent_to] = val
941
986
  end
942
-
987
+
943
988
  # Returns the return path of the mail object, or sets it if you pass a string
944
989
  def return_path( val = nil )
945
990
  default :return_path, val
946
991
  end
947
-
992
+
948
993
  # Sets the return path of the object
949
994
  def return_path=( val )
950
995
  header[:return_path] = val
951
996
  end
952
-
997
+
953
998
  # Returns the Sender value of the mail object, as a single string of an address
954
999
  # spec. A sender per RFC 2822 must be a single address.
955
1000
  #
956
1001
  # Example:
957
- #
1002
+ #
958
1003
  # mail.sender = 'Mikel <mikel@test.lindsaar.net>'
959
1004
  # mail.sender #=> 'mikel@test.lindsaar.net'
960
- #
1005
+ #
961
1006
  # Also allows you to set the value by passing a value as a parameter
962
1007
  #
963
1008
  # Example:
964
- #
1009
+ #
965
1010
  # mail.sender 'Mikel <mikel@test.lindsaar.net>'
966
1011
  # mail.sender #=> 'mikel@test.lindsaar.net'
967
1012
  def sender( val = nil )
968
1013
  default :sender, val
969
1014
  end
970
-
1015
+
971
1016
  # Sets the Sender value of the mail object, pass in a string of the field
972
1017
  #
973
1018
  # Example:
974
- #
1019
+ #
975
1020
  # mail.sender = 'Mikel <mikel@test.lindsaar.net>'
976
1021
  # mail.sender #=> 'mikel@test.lindsaar.net'
977
1022
  def sender=( val )
978
1023
  header[:sender] = val
979
1024
  end
980
-
1025
+
981
1026
  # Returns the decoded value of the subject field, as a single string.
982
1027
  #
983
1028
  # Example:
984
- #
1029
+ #
985
1030
  # mail.subject = "G'Day mate"
986
1031
  # mail.subject #=> "G'Day mate"
987
1032
  # mail.subject = '=?UTF-8?Q?This_is_=E3=81=82_string?='
988
1033
  # mail.subject #=> "This is あ string"
989
- #
1034
+ #
990
1035
  # Also allows you to set the value by passing a value as a parameter
991
1036
  #
992
1037
  # Example:
993
- #
1038
+ #
994
1039
  # mail.subject "G'Day mate"
995
1040
  # mail.subject #=> "G'Day mate"
996
1041
  def subject( val = nil )
997
1042
  default :subject, val
998
1043
  end
999
-
1044
+
1000
1045
  # Sets the Subject value of the mail object, pass in a string of the field
1001
1046
  #
1002
1047
  # Example:
1003
- #
1048
+ #
1004
1049
  # mail.subject = '=?UTF-8?Q?This_is_=E3=81=82_string?='
1005
1050
  # mail.subject #=> "This is あ string"
1006
1051
  def subject=( val )
1007
1052
  header[:subject] = val
1008
1053
  end
1009
-
1010
- # Returns the To value of the mail object as an array of strings of
1054
+
1055
+ # Returns the To value of the mail object as an array of strings of
1011
1056
  # address specs.
1012
1057
  #
1013
1058
  # Example:
1014
- #
1059
+ #
1015
1060
  # mail.to = 'Mikel <mikel@test.lindsaar.net>'
1016
1061
  # mail.to #=> ['mikel@test.lindsaar.net']
1017
1062
  # mail.to = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
1018
1063
  # mail.to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
1019
- #
1064
+ #
1020
1065
  # Also allows you to set the value by passing a value as a parameter
1021
1066
  #
1022
1067
  # Example:
1023
- #
1068
+ #
1024
1069
  # mail.to 'Mikel <mikel@test.lindsaar.net>'
1025
1070
  # mail.to #=> ['mikel@test.lindsaar.net']
1026
- #
1071
+ #
1027
1072
  # Additionally, you can append new addresses to the returned Array like
1028
1073
  # object.
1029
- #
1074
+ #
1030
1075
  # Example:
1031
- #
1076
+ #
1032
1077
  # mail.to 'Mikel <mikel@test.lindsaar.net>'
1033
1078
  # mail.to << 'ada@test.lindsaar.net'
1034
1079
  # mail.to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
1035
1080
  def to( val = nil )
1036
1081
  default :to, val
1037
1082
  end
1038
-
1083
+
1039
1084
  # Sets the To value of the mail object, pass in a string of the field
1040
1085
  #
1041
1086
  # Example:
1042
- #
1087
+ #
1043
1088
  # mail.to = 'Mikel <mikel@test.lindsaar.net>'
1044
1089
  # mail.to #=> ['mikel@test.lindsaar.net']
1045
1090
  # mail.to = 'Mikel <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
@@ -1050,7 +1095,7 @@ module Mail
1050
1095
 
1051
1096
  # Returns the default value of the field requested as a symbol.
1052
1097
  #
1053
- # Each header field has a :default method which returns the most common use case for
1098
+ # Each header field has a :default method which returns the most common use case for
1054
1099
  # that field, for example, the date field types will return a DateTime object when
1055
1100
  # sent :default, the subject, or unstructured fields will return a decoded string of
1056
1101
  # their value, the address field types will return a single addr_spec or an array of
@@ -1062,63 +1107,56 @@ module Mail
1062
1107
  header[sym].default if header[sym]
1063
1108
  end
1064
1109
  end
1065
-
1110
+
1066
1111
  # Sets the body object of the message object.
1067
- #
1112
+ #
1068
1113
  # Example:
1069
- #
1114
+ #
1070
1115
  # mail.body = 'This is the body'
1071
1116
  # mail.body #=> #<Mail::Body:0x13919c @raw_source="This is the bo...
1072
- #
1117
+ #
1073
1118
  # You can also reset the body of an Message object by setting body to nil
1074
- #
1119
+ #
1075
1120
  # Example:
1076
- #
1121
+ #
1077
1122
  # mail.body = 'this is the body'
1078
1123
  # mail.body.encoded #=> 'this is the body'
1079
1124
  # mail.body = nil
1080
1125
  # mail.body.encoded #=> ''
1081
- #
1126
+ #
1082
1127
  # If you try and set the body of an email that is a multipart email, then instead
1083
1128
  # of deleting all the parts of your email, mail will add a text/plain part to
1084
1129
  # your email:
1085
- #
1130
+ #
1086
1131
  # mail.add_file 'somefilename.png'
1087
1132
  # mail.parts.length #=> 1
1088
1133
  # mail.body = "This is a body"
1089
1134
  # mail.parts.length #=> 2
1090
1135
  # mail.parts.last.content_type.content_type #=> 'This is a body'
1091
1136
  def body=(value)
1092
- case
1093
- when value == nil
1094
- @body = Mail::Body.new('')
1095
- when @body && @body.multipart?
1096
- @body << Mail::Part.new(value)
1097
- else
1098
- @body = Mail::Body.new(value)
1099
- end
1100
- add_encoding_to_body
1137
+ body_lazy(value, 0)
1101
1138
  end
1102
1139
 
1103
1140
  # Returns the body of the message object. Or, if passed
1104
1141
  # a parameter sets the value.
1105
- #
1142
+ #
1106
1143
  # Example:
1107
- #
1144
+ #
1108
1145
  # mail = Mail::Message.new('To: mikel\r\n\r\nThis is the body')
1109
1146
  # mail.body #=> #<Mail::Body:0x13919c @raw_source="This is the bo...
1110
- #
1147
+ #
1111
1148
  # mail.body 'This is another body'
1112
1149
  # mail.body #=> #<Mail::Body:0x13919c @raw_source="This is anothe...
1113
1150
  def body(value = nil)
1114
1151
  if value
1115
1152
  self.body = value
1116
- add_encoding_to_body
1153
+ # add_encoding_to_body
1117
1154
  else
1155
+ process_body_raw if @body_raw
1118
1156
  @body
1119
1157
  end
1120
1158
  end
1121
-
1159
+
1122
1160
  def body_encoding(value)
1123
1161
  if value.nil?
1124
1162
  body.encoding
@@ -1130,12 +1168,12 @@ module Mail
1130
1168
  def body_encoding=(value)
1131
1169
  body.encoding = value
1132
1170
  end
1133
-
1171
+
1134
1172
  # Returns the list of addresses this message should be sent to by
1135
1173
  # collecting the addresses off the to, cc and bcc fields.
1136
- #
1174
+ #
1137
1175
  # Example:
1138
- #
1176
+ #
1139
1177
  # mail.to = 'mikel@test.lindsaar.net'
1140
1178
  # mail.cc = 'sam@test.lindsaar.net'
1141
1179
  # mail.bcc = 'bob@test.lindsaar.net'
@@ -1150,27 +1188,27 @@ module Mail
1150
1188
  def from_addrs
1151
1189
  from ? [from].flatten : []
1152
1190
  end
1153
-
1191
+
1154
1192
  # Returns an array of addresses (the encoded value) in the To field,
1155
1193
  # if no To field, returns an empty array
1156
1194
  def to_addrs
1157
1195
  to ? [to].flatten : []
1158
1196
  end
1159
-
1197
+
1160
1198
  # Returns an array of addresses (the encoded value) in the Cc field,
1161
1199
  # if no Cc field, returns an empty array
1162
1200
  def cc_addrs
1163
1201
  cc ? [cc].flatten : []
1164
1202
  end
1165
-
1203
+
1166
1204
  # Returns an array of addresses (the encoded value) in the Bcc field,
1167
1205
  # if no Bcc field, returns an empty array
1168
1206
  def bcc_addrs
1169
1207
  bcc ? [bcc].flatten : []
1170
1208
  end
1171
-
1209
+
1172
1210
  # Allows you to add an arbitrary header
1173
- #
1211
+ #
1174
1212
  # Example:
1175
1213
  #
1176
1214
  # mail['foo'] = '1234'
@@ -1188,7 +1226,7 @@ module Mail
1188
1226
  end
1189
1227
 
1190
1228
  # Allows you to read an arbitrary header
1191
- #
1229
+ #
1192
1230
  # Example:
1193
1231
  #
1194
1232
  # mail['foo'] = '1234'
@@ -1196,14 +1234,14 @@ module Mail
1196
1234
  def [](name)
1197
1235
  header[underscoreize(name)]
1198
1236
  end
1199
-
1237
+
1200
1238
  # Method Missing in this implementation allows you to set any of the
1201
1239
  # standard fields directly as you would the "to", "subject" etc.
1202
- #
1240
+ #
1203
1241
  # Those fields used most often (to, subject et al) are given their
1204
- # own method for ease of documentation and also to avoid the hook
1242
+ # own method for ease of documentation and also to avoid the hook
1205
1243
  # call to method missing.
1206
- #
1244
+ #
1207
1245
  # This will only catch the known fields listed in:
1208
1246
  #
1209
1247
  # Mail::Field::KNOWN_FIELDS
@@ -1211,29 +1249,29 @@ module Mail
1211
1249
  # as per RFC 2822, any ruby string or method name could pretty much
1212
1250
  # be a field name, so we don't want to just catch ANYTHING sent to
1213
1251
  # a message object and interpret it as a header.
1214
- #
1252
+ #
1215
1253
  # This method provides all three types of header call to set, read
1216
1254
  # and explicitly set with the = operator
1217
- #
1255
+ #
1218
1256
  # Examples:
1219
- #
1257
+ #
1220
1258
  # mail.comments = 'These are some comments'
1221
1259
  # mail.comments #=> 'These are some comments'
1222
- #
1260
+ #
1223
1261
  # mail.comments 'These are other comments'
1224
1262
  # mail.comments #=> 'These are other comments'
1225
- #
1226
- #
1263
+ #
1264
+ #
1227
1265
  # mail.date = 'Tue, 1 Jul 2003 10:52:37 +0200'
1228
1266
  # mail.date.to_s #=> 'Tue, 1 Jul 2003 10:52:37 +0200'
1229
- #
1267
+ #
1230
1268
  # mail.date 'Tue, 1 Jul 2003 10:52:37 +0200'
1231
1269
  # mail.date.to_s #=> 'Tue, 1 Jul 2003 10:52:37 +0200'
1232
- #
1270
+ #
1233
1271
  #
1234
1272
  # mail.resent_msg_id = '<1234@resent_msg_id.lindsaar.net>'
1235
1273
  # mail.resent_msg_id #=> '<1234@resent_msg_id.lindsaar.net>'
1236
- #
1274
+ #
1237
1275
  # mail.resent_msg_id '<4567@resent_msg_id.lindsaar.net>'
1238
1276
  # mail.resent_msg_id #=> '<4567@resent_msg_id.lindsaar.net>'
1239
1277
  def method_missing(name, *args, &block)
@@ -1248,10 +1286,10 @@ module Mail
1248
1286
  header[field_name] = args.first
1249
1287
  end
1250
1288
  else
1251
- super # otherwise pass it on
1252
- end
1289
+ super # otherwise pass it on
1290
+ end
1253
1291
  #:startdoc:
1254
- end
1292
+ end
1255
1293
 
1256
1294
  # Returns an FieldList of all the fields in the header in the order that
1257
1295
  # they appear in the header
@@ -1276,19 +1314,21 @@ module Mail
1276
1314
  def has_mime_version?
1277
1315
  header.has_mime_version?
1278
1316
  end
1279
-
1317
+
1280
1318
  def has_content_type?
1281
- !!header[:content_type]
1319
+ tmp = header[:content_type].main_type rescue nil
1320
+ !!tmp
1282
1321
  end
1283
-
1322
+
1284
1323
  def has_charset?
1285
- !!(header[:content_type] && header[:content_type].parameters['charset'])
1324
+ tmp = header[:content_type].parameters rescue nil
1325
+ !!(has_content_type? && tmp && tmp['charset'])
1286
1326
  end
1287
-
1327
+
1288
1328
  def has_content_transfer_encoding?
1289
1329
  header[:content_transfer_encoding] && header[:content_transfer_encoding].errors.blank?
1290
1330
  end
1291
-
1331
+
1292
1332
  def has_transfer_encoding? # :nodoc:
1293
1333
  STDERR.puts(":has_transfer_encoding? is deprecated in Mail 1.4.3. Please use has_content_transfer_encoding?\n#{caller}")
1294
1334
  has_content_transfer_encoding?
@@ -1298,41 +1338,41 @@ module Mail
1298
1338
  # into the Header. The MessageIdField object will automatically generate
1299
1339
  # a unique message ID if you try and encode it or output it to_s without
1300
1340
  # specifying a message id.
1301
- #
1341
+ #
1302
1342
  # It will preserve the message ID you specify if you do.
1303
1343
  def add_message_id(msg_id_val = '')
1304
1344
  header['message-id'] = msg_id_val
1305
1345
  end
1306
-
1346
+
1307
1347
  # Creates a new empty Date field and inserts it in the correct order
1308
1348
  # into the Header. The DateField object will automatically generate
1309
1349
  # DateTime.now's date if you try and encode it or output it to_s without
1310
1350
  # specifying a date yourself.
1311
- #
1351
+ #
1312
1352
  # It will preserve any date you specify if you do.
1313
1353
  def add_date(date_val = '')
1314
1354
  header['date'] = date_val
1315
1355
  end
1316
-
1356
+
1317
1357
  # Creates a new empty Mime Version field and inserts it in the correct order
1318
1358
  # into the Header. The MimeVersion object will automatically generate
1319
1359
  # set itself to '1.0' if you try and encode it or output it to_s without
1320
1360
  # specifying a version yourself.
1321
- #
1361
+ #
1322
1362
  # It will preserve any date you specify if you do.
1323
1363
  def add_mime_version(ver_val = '')
1324
1364
  header['mime-version'] = ver_val
1325
1365
  end
1326
-
1366
+
1327
1367
  # Adds a content type and charset if the body is US-ASCII
1328
- #
1368
+ #
1329
1369
  # Otherwise raises a warning
1330
1370
  def add_content_type
1331
1371
  header[:content_type] = 'text/plain'
1332
1372
  end
1333
1373
 
1334
1374
  # Adds a content type and charset if the body is US-ASCII
1335
- #
1375
+ #
1336
1376
  # Otherwise raises a warning
1337
1377
  def add_charset
1338
1378
  if !body.empty?
@@ -1345,9 +1385,9 @@ module Mail
1345
1385
  header[:content_type].parameters['charset'] = @charset
1346
1386
  end
1347
1387
  end
1348
-
1388
+
1349
1389
  # Adds a content transfer encoding
1350
- #
1390
+ #
1351
1391
  # Otherwise raises a warning
1352
1392
  def add_content_transfer_encoding
1353
1393
  if body.only_us_ascii?
@@ -1358,27 +1398,27 @@ module Mail
1358
1398
  header[:content_transfer_encoding] = '8bit'
1359
1399
  end
1360
1400
  end
1361
-
1401
+
1362
1402
  def add_transfer_encoding # :nodoc:
1363
1403
  STDERR.puts(":add_transfer_encoding is deprecated in Mail 1.4.3. Please use add_content_transfer_encoding\n#{caller}")
1364
1404
  add_content_transfer_encoding
1365
1405
  end
1366
-
1406
+
1367
1407
  def transfer_encoding # :nodoc:
1368
1408
  STDERR.puts(":transfer_encoding is deprecated in Mail 1.4.3. Please use content_transfer_encoding\n#{caller}")
1369
1409
  content_transfer_encoding
1370
1410
  end
1371
-
1411
+
1372
1412
  # Returns the MIME media type of part we are on, this is taken from the content-type header
1373
1413
  def mime_type
1374
- content_type ? header[:content_type].string : nil
1414
+ content_type ? header[:content_type].string : nil rescue nil
1375
1415
  end
1376
-
1416
+
1377
1417
  def message_content_type
1378
1418
  STDERR.puts(":message_content_type is deprecated in Mail 1.4.3. Please use mime_type\n#{caller}")
1379
1419
  mime_type
1380
1420
  end
1381
-
1421
+
1382
1422
  # Returns the character set defined in the content type field
1383
1423
  def charset
1384
1424
  if @header
@@ -1394,60 +1434,60 @@ module Mail
1394
1434
  @charset = value
1395
1435
  @header.charset = value
1396
1436
  end
1397
-
1437
+
1398
1438
  # Returns the main content type
1399
1439
  def main_type
1400
- has_content_type? ? header[:content_type].main_type : nil
1440
+ has_content_type? ? header[:content_type].main_type : nil rescue nil
1401
1441
  end
1402
-
1442
+
1403
1443
  # Returns the sub content type
1404
1444
  def sub_type
1405
- has_content_type? ? header[:content_type].sub_type : nil
1445
+ has_content_type? ? header[:content_type].sub_type : nil rescue nil
1406
1446
  end
1407
-
1447
+
1408
1448
  # Returns the content type parameters
1409
1449
  def mime_parameters
1410
1450
  STDERR.puts(':mime_parameters is deprecated in Mail 1.4.3, please use :content_type_parameters instead')
1411
1451
  content_type_parameters
1412
1452
  end
1413
-
1453
+
1414
1454
  # Returns the content type parameters
1415
1455
  def content_type_parameters
1416
- has_content_type? ? header[:content_type].parameters : nil
1456
+ has_content_type? ? header[:content_type].parameters : nil rescue nil
1417
1457
  end
1418
-
1458
+
1419
1459
  # Returns true if the message is multipart
1420
1460
  def multipart?
1421
1461
  has_content_type? ? !!(main_type =~ /^multipart$/i) : false
1422
1462
  end
1423
-
1463
+
1424
1464
  # Returns true if the message is a multipart/report
1425
1465
  def multipart_report?
1426
1466
  multipart? && sub_type =~ /^report$/i
1427
1467
  end
1428
-
1468
+
1429
1469
  # Returns true if the message is a multipart/report; report-type=delivery-status;
1430
1470
  def delivery_status_report?
1431
1471
  multipart_report? && content_type_parameters['report-type'] =~ /^delivery-status$/i
1432
1472
  end
1433
-
1473
+
1434
1474
  # returns the part in a multipart/report email that has the content-type delivery-status
1435
1475
  def delivery_status_part
1436
1476
  @delivery_stats_part ||= parts.select { |p| p.delivery_status_report_part? }.first
1437
1477
  end
1438
-
1478
+
1439
1479
  def bounced?
1440
1480
  delivery_status_part and delivery_status_part.bounced?
1441
1481
  end
1442
-
1482
+
1443
1483
  def action
1444
1484
  delivery_status_part and delivery_status_part.action
1445
1485
  end
1446
-
1486
+
1447
1487
  def final_recipient
1448
1488
  delivery_status_part and delivery_status_part.final_recipient
1449
1489
  end
1450
-
1490
+
1451
1491
  def error_status
1452
1492
  delivery_status_part and delivery_status_part.error_status
1453
1493
  end
@@ -1455,59 +1495,59 @@ module Mail
1455
1495
  def diagnostic_code
1456
1496
  delivery_status_part and delivery_status_part.diagnostic_code
1457
1497
  end
1458
-
1498
+
1459
1499
  def remote_mta
1460
1500
  delivery_status_part and delivery_status_part.remote_mta
1461
1501
  end
1462
-
1502
+
1463
1503
  def retryable?
1464
1504
  delivery_status_part and delivery_status_part.retryable?
1465
1505
  end
1466
-
1506
+
1467
1507
  # Returns the current boundary for this message part
1468
1508
  def boundary
1469
1509
  content_type_parameters ? content_type_parameters['boundary'] : nil
1470
1510
  end
1471
-
1511
+
1472
1512
  # Returns a parts list object of all the parts in the message
1473
1513
  def parts
1474
1514
  body.parts
1475
1515
  end
1476
-
1516
+
1477
1517
  # Returns an AttachmentsList object, which holds all of the attachments in
1478
1518
  # the receiver object (either the entier email or a part within) and all
1479
1519
  # of it's descendants.
1480
- #
1520
+ #
1481
1521
  # It also allows you to add attachments to the mail object directly, like so:
1482
- #
1522
+ #
1483
1523
  # mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
1484
- #
1524
+ #
1485
1525
  # If you do this, then Mail will take the file name and work out the MIME media type
1486
- # set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
1526
+ # set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
1487
1527
  # base64 encode the contents of the attachment all for you.
1488
- #
1528
+ #
1489
1529
  # You can also specify overrides if you want by passing a hash instead of a string:
1490
- #
1530
+ #
1491
1531
  # mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
1492
1532
  # :content => File.read('/path/to/filename.jpg')}
1493
- #
1533
+ #
1494
1534
  # If you want to use a different encoding than Base64, you can pass an encoding in,
1495
1535
  # but then it is up to you to pass in the content pre-encoded, and don't expect
1496
1536
  # Mail to know how to decode this data:
1497
- #
1537
+ #
1498
1538
  # file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
1499
1539
  # mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
1500
1540
  # :encoding => 'SpecialEncoding',
1501
1541
  # :content => file_content }
1502
- #
1542
+ #
1503
1543
  # You can also search for specific attachments:
1504
- #
1544
+ #
1505
1545
  # # By Filename
1506
1546
  # mail.attachments['filename.jpg'] #=> Mail::Part object or nil
1507
- #
1547
+ #
1508
1548
  # # or by index
1509
1549
  # mail.attachments[0] #=> Mail::Part (first attachment)
1510
- #
1550
+ #
1511
1551
  def attachments
1512
1552
  parts.attachments
1513
1553
  end
@@ -1515,7 +1555,7 @@ module Mail
1515
1555
  def has_attachments?
1516
1556
  !attachments.empty?
1517
1557
  end
1518
-
1558
+
1519
1559
  # Accessor for html_part
1520
1560
  def html_part(&block)
1521
1561
  if block_given?
@@ -1526,7 +1566,7 @@ module Mail
1526
1566
  @html_part || find_first_mime_type('text/html')
1527
1567
  end
1528
1568
  end
1529
-
1569
+
1530
1570
  # Accessor for text_part
1531
1571
  def text_part(&block)
1532
1572
  if block_given?
@@ -1537,7 +1577,7 @@ module Mail
1537
1577
  @text_part || find_first_mime_type('text/plain')
1538
1578
  end
1539
1579
  end
1540
-
1580
+
1541
1581
  # Helper to add a html part to a multipart/alternative email. If this and
1542
1582
  # text_part are both defined in a message, then it will be a multipart/alternative
1543
1583
  # message and set itself that way.
@@ -1550,7 +1590,7 @@ module Mail
1550
1590
  add_multipart_alternate_header unless text_part.blank?
1551
1591
  add_part(@html_part)
1552
1592
  end
1553
-
1593
+
1554
1594
  # Helper to add a text part to a multipart/alternative email. If this and
1555
1595
  # html_part are both defined in a message, then it will be a multipart/alternative
1556
1596
  # message and set itself that way.
@@ -1577,9 +1617,9 @@ module Mail
1577
1617
  end
1578
1618
 
1579
1619
  # Allows you to add a part in block form to an existing mail message object
1580
- #
1620
+ #
1581
1621
  # Example:
1582
- #
1622
+ #
1583
1623
  # mail = Mail.new do
1584
1624
  # part :content_type => "multipart/alternative", :content_disposition => "inline" do |p|
1585
1625
  # p.part :content_type => "text/plain", :body => "test text\nline #2"
@@ -1591,26 +1631,26 @@ module Mail
1591
1631
  yield new_part if block_given?
1592
1632
  add_part(new_part)
1593
1633
  end
1594
-
1634
+
1595
1635
  # Adds a file to the message. You have two options with this method, you can
1596
1636
  # just pass in the absolute path to the file you want and Mail will read the file,
1597
1637
  # get the filename from the path you pass in and guess the MIME media type, or you
1598
1638
  # can pass in the filename as a string, and pass in the file content as a blob.
1599
- #
1639
+ #
1600
1640
  # Example:
1601
- #
1641
+ #
1602
1642
  # m = Mail.new
1603
1643
  # m.add_file('/path/to/filename.png')
1604
- #
1644
+ #
1605
1645
  # m = Mail.new
1606
1646
  # m.add_file(:filename => 'filename.png', :content => File.read('/path/to/file.jpg'))
1607
1647
  #
1608
1648
  # Note also that if you add a file to an existing message, Mail will convert that message
1609
1649
  # to a MIME multipart email, moving whatever plain text body you had into it's own text
1610
1650
  # plain part.
1611
- #
1651
+ #
1612
1652
  # Example:
1613
- #
1653
+ #
1614
1654
  # m = Mail.new do
1615
1655
  # body 'this is some text'
1616
1656
  # end
@@ -1619,26 +1659,27 @@ module Mail
1619
1659
  # m.multipart? #=> true
1620
1660
  # m.parts.first.content_type.content_type #=> 'text/plain'
1621
1661
  # m.parts.last.content_type.content_type #=> 'image/png'
1622
- #
1662
+ #
1623
1663
  # See also #attachments
1624
1664
  def add_file(values)
1625
1665
  convert_to_multipart unless self.multipart? || self.body.decoded.blank?
1626
1666
  add_multipart_mixed_header
1627
1667
  if values.is_a?(String)
1628
1668
  basename = File.basename(values)
1629
- filedata = File.read(values)
1669
+ filedata = File.open(values, 'rb') { |f| f.read }
1630
1670
  else
1631
1671
  basename = values[:filename]
1632
- filedata = values[:content] || File.read(values[:filename])
1672
+ filedata = values[:content] || File.open(values[:filename], 'rb') { |f| f.read }
1633
1673
  end
1634
1674
  self.attachments[basename] = filedata
1635
1675
  end
1636
1676
 
1637
1677
  def convert_to_multipart
1638
- text = @body.decoded
1678
+ text = body.decoded
1639
1679
  self.body = ''
1640
1680
  text_part = Mail::Part.new({:content_type => 'text/plain;',
1641
1681
  :body => text})
1682
+ text_part.charset = charset unless @defaulted_charset
1642
1683
  self.body << text_part
1643
1684
  end
1644
1685
 
@@ -1647,7 +1688,7 @@ module Mail
1647
1688
  def ready_to_send!
1648
1689
  identify_and_set_transfer_encoding
1649
1690
  parts.sort!([ "text/plain", "text/enriched", "text/html", "multipart/alternative" ])
1650
- parts.each do |part|
1691
+ parts.each do |part|
1651
1692
  part.transport_encoding = transport_encoding
1652
1693
  part.ready_to_send!
1653
1694
  end
@@ -1658,7 +1699,7 @@ module Mail
1658
1699
  STDERR.puts("Deprecated in 1.1.0 in favour of :ready_to_send! as it is less confusing with encoding and decoding.")
1659
1700
  ready_to_send!
1660
1701
  end
1661
-
1702
+
1662
1703
  # Outputs an encoded string representation of the mail message including
1663
1704
  # all headers, attachments, etc. This is an encoded email in US-ASCII,
1664
1705
  # so it is able to be directly sent to an email server.
@@ -1669,7 +1710,26 @@ module Mail
1669
1710
  buffer << body.encoded(content_transfer_encoding)
1670
1711
  buffer
1671
1712
  end
1672
-
1713
+
1714
+ def to_yaml
1715
+ ready_to_send!
1716
+ hash = {}
1717
+ header.fields.each do |field|
1718
+ hash[field.name] = field.value
1719
+ end
1720
+ hash['subject'] = subject
1721
+ hash['body'] = body.encoded(content_transfer_encoding)
1722
+ hash.to_yaml
1723
+ end
1724
+
1725
+ def self.from_yaml(str)
1726
+ from_hash(YAML::load(str))
1727
+ end
1728
+
1729
+ def self.from_hash(hash)
1730
+ Mail::Message.new(hash)
1731
+ end
1732
+
1673
1733
  def to_s
1674
1734
  encoded
1675
1735
  end
@@ -1700,17 +1760,18 @@ module Mail
1700
1760
  def decode_body
1701
1761
  body.decoded
1702
1762
  end
1703
-
1704
- # Returns true if this part is an attachment
1763
+
1764
+ # Returns true if this part is an attachment,
1765
+ # false otherwise.
1705
1766
  def attachment?
1706
- find_attachment
1767
+ !!find_attachment
1707
1768
  end
1708
-
1769
+
1709
1770
  # Returns the attachment data if there is any
1710
1771
  def attachment
1711
1772
  @attachment
1712
1773
  end
1713
-
1774
+
1714
1775
  # Returns the filename of the attachment
1715
1776
  def filename
1716
1777
  find_attachment
@@ -1721,9 +1782,38 @@ module Mail
1721
1782
  end
1722
1783
 
1723
1784
  def find_first_mime_type(mt)
1724
- all_parts.detect { |p| p.mime_type == mt }
1785
+ all_parts.detect { |p| p.mime_type == mt && !p.attachment? }
1786
+ end
1787
+
1788
+ # Skips the deletion of this message. All other messages
1789
+ # flagged for delete still will be deleted at session close (i.e. when
1790
+ # #find exits). Only has an effect if you're using #find_and_delete
1791
+ # or #find with :delete_after_find set to true.
1792
+ def skip_deletion
1793
+ @mark_for_delete = false
1794
+ end
1795
+
1796
+ # Sets whether this message should be deleted at session close (i.e.
1797
+ # after #find). Message will only be deleted if messages are retrieved
1798
+ # using the #find_and_delete method, or by calling #find with
1799
+ # :delete_after_find set to true.
1800
+ def mark_for_delete=(value = true)
1801
+ @mark_for_delete = value
1725
1802
  end
1726
-
1803
+
1804
+ # Returns whether message will be marked for deletion.
1805
+ # If so, the message will be deleted at session close (i.e. after #find
1806
+ # exits), but only if also using the #find_and_delete method, or by
1807
+ # calling #find with :delete_after_find set to true.
1808
+ #
1809
+ # Side-note: Just to be clear, this method will return true even if
1810
+ # the message hasn't yet been marked for delete on the mail server.
1811
+ # However, if this method returns true, it *will be* marked on the
1812
+ # server after each block yields back to #find or #find_and_delete.
1813
+ def is_marked_for_delete?
1814
+ return @mark_for_delete
1815
+ end
1816
+
1727
1817
  private
1728
1818
 
1729
1819
  # 2.1. General Description
@@ -1733,19 +1823,51 @@ module Mail
1733
1823
  # this standard. The body is simply a sequence of characters that
1734
1824
  # follows the header and is separated from the header by an empty line
1735
1825
  # (i.e., a line with nothing preceding the CRLF).
1736
- #
1826
+ #
1737
1827
  # Additionally, I allow for the case where someone might have put whitespace
1738
1828
  # on the "gap line"
1739
1829
  def parse_message
1740
1830
  header_part, body_part = raw_source.split(/#{CRLF}#{WSP}*#{CRLF}/m, 2)
1831
+ # index = raw_source.index(/#{CRLF}#{WSP}*#{CRLF}/m, 2)
1832
+ # self.header = (index) ? header_part[0,index] : nil
1833
+ # lazy_body ( [raw_source, index+1])
1741
1834
  self.header = header_part
1742
1835
  self.body = body_part
1743
1836
  end
1744
-
1837
+
1745
1838
  def raw_source=(value)
1746
1839
  @raw_source = value.to_crlf
1747
1840
  end
1748
-
1841
+
1842
+ # see comments to body=. We take data starting from index and process it lazily
1843
+ def body_lazy(value, index)
1844
+ process_body_raw if @body_raw && value
1845
+ case
1846
+ when value == nil || value.length<=index
1847
+ @body = Mail::Body.new('')
1848
+ @body_raw = nil
1849
+ @body_raw_index = nil
1850
+ add_encoding_to_body
1851
+ when @body && @body.multipart?
1852
+ @body << Mail::Part.new(value[index, value.length-index])
1853
+ add_encoding_to_body
1854
+ else
1855
+ @body_raw = value
1856
+ @body_raw_index = index
1857
+ # process_body_raw
1858
+ end
1859
+ end
1860
+
1861
+
1862
+ def process_body_raw
1863
+ @body = Mail::Body.new(@body_raw[@body_raw_index, @body_raw.length-@body_raw_index])
1864
+ @body_raw = nil
1865
+ @body_raw_index = nil
1866
+ separate_parts if @separate_parts
1867
+
1868
+ add_encoding_to_body
1869
+ end
1870
+
1749
1871
  def set_envelope_header
1750
1872
  if match_data = raw_source.to_s.match(/\AFrom\s(#{TEXT}+)#{CRLF}(.*)/m)
1751
1873
  set_envelope(match_data[1])
@@ -1756,10 +1878,10 @@ module Mail
1756
1878
  def separate_parts
1757
1879
  body.split!(boundary)
1758
1880
  end
1759
-
1881
+
1760
1882
  def add_encoding_to_body
1761
1883
  if has_content_transfer_encoding?
1762
- body.encoding = content_transfer_encoding
1884
+ @body.encoding = content_transfer_encoding
1763
1885
  end
1764
1886
  end
1765
1887
 
@@ -1770,10 +1892,10 @@ module Mail
1770
1892
  self.content_transfer_encoding = body.get_best_encoding(@transport_encoding)
1771
1893
  end
1772
1894
  end
1773
-
1895
+
1774
1896
  def add_required_fields
1775
1897
  add_multipart_mixed_header unless !body.multipart?
1776
- @body = Mail::Body.new('') if body.nil?
1898
+ body = nil if body.nil?
1777
1899
  add_message_id unless (has_message_id? || self.class == Mail::Part)
1778
1900
  add_date unless has_date?
1779
1901
  add_mime_version unless has_mime_version?
@@ -1781,13 +1903,13 @@ module Mail
1781
1903
  add_charset unless has_charset?
1782
1904
  add_content_transfer_encoding unless has_content_transfer_encoding?
1783
1905
  end
1784
-
1906
+
1785
1907
  def add_multipart_alternate_header
1786
1908
  header['content-type'] = ContentTypeField.with_boundary('multipart/alternative').value
1787
1909
  header['content_type'].parameters[:charset] = @charset
1788
1910
  body.boundary = boundary
1789
1911
  end
1790
-
1912
+
1791
1913
  def add_boundary
1792
1914
  unless body.boundary && boundary
1793
1915
  header['content-type'] = 'multipart/mixed' unless header['content-type']
@@ -1796,7 +1918,7 @@ module Mail
1796
1918
  body.boundary = boundary
1797
1919
  end
1798
1920
  end
1799
-
1921
+
1800
1922
  def add_multipart_mixed_header
1801
1923
  unless header['content-type']
1802
1924
  header['content-type'] = ContentTypeField.with_boundary('multipart/mixed').value
@@ -1804,13 +1926,14 @@ module Mail
1804
1926
  body.boundary = boundary
1805
1927
  end
1806
1928
  end
1807
-
1929
+
1808
1930
  def init_with_hash(hash)
1809
1931
  passed_in_options = hash.with_indifferent_access
1810
1932
  self.raw_source = ''
1811
1933
 
1812
1934
  @header = Mail::Header.new
1813
1935
  @body = Mail::Body.new
1936
+ @body_raw = nil
1814
1937
 
1815
1938
  # We need to store the body until last, as we need all headers added first
1816
1939
  body_content = nil
@@ -1833,26 +1956,30 @@ module Mail
1833
1956
  end
1834
1957
  end
1835
1958
  end
1836
-
1959
+
1837
1960
  def init_with_string(string)
1838
1961
  self.raw_source = string
1839
1962
  set_envelope_header
1840
1963
  parse_message
1841
- separate_parts if multipart?
1964
+ @separate_parts = multipart?
1842
1965
  end
1843
-
1966
+
1844
1967
  # Returns the filename of the attachment (if it exists) or returns nil
1845
1968
  def find_attachment
1969
+ content_type_name = header[:content_type].filename rescue nil
1970
+ content_disp_name = header[:content_disposition].filename rescue nil
1971
+ content_loc_name = header[:content_location].location rescue nil
1846
1972
  case
1847
- when content_type && header[:content_type].filename
1848
- filename = header[:content_type].filename
1849
- when content_disposition && header[:content_disposition].filename
1850
- filename = header[:content_disposition].filename
1851
- when content_location && header[:content_location].location
1852
- filename = header[:content_location].location
1973
+ when content_type && content_type_name
1974
+ filename = content_type_name
1975
+ when content_disposition && content_disp_name
1976
+ filename = content_disp_name
1977
+ when content_location && content_loc_name
1978
+ filename = content_loc_name
1853
1979
  else
1854
1980
  filename = nil
1855
1981
  end
1982
+ filename = Mail::Encodings.decode_encode(filename, :decode) if filename rescue filename
1856
1983
  filename
1857
1984
  end
1858
1985
 
@@ -1865,6 +1992,6 @@ module Mail
1865
1992
  raise e if raise_delivery_errors
1866
1993
  end
1867
1994
  end
1868
-
1995
+
1869
1996
  end
1870
1997
  end