mail 2.5.2 → 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 (151) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.rdoc +78 -0
  3. data/CONTRIBUTING.md +17 -4
  4. data/Dependencies.txt +0 -1
  5. data/Gemfile +10 -21
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +50 -29
  8. data/Rakefile +11 -22
  9. data/VERSION +4 -0
  10. data/lib/mail/attachments_list.rb +2 -2
  11. data/lib/mail/body.rb +5 -5
  12. data/lib/mail/check_delivery_params.rb +12 -22
  13. data/lib/mail/core_extensions/object.rb +8 -8
  14. data/lib/mail/core_extensions/smtp.rb +12 -13
  15. data/lib/mail/core_extensions/string.rb +16 -6
  16. data/lib/mail/elements/address.rb +43 -79
  17. data/lib/mail/elements/address_list.rb +19 -42
  18. data/lib/mail/elements/content_disposition_element.rb +3 -7
  19. data/lib/mail/elements/content_location_element.rb +2 -6
  20. data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
  21. data/lib/mail/elements/content_type_element.rb +4 -8
  22. data/lib/mail/elements/date_time_element.rb +3 -7
  23. data/lib/mail/elements/envelope_from_element.rb +18 -13
  24. data/lib/mail/elements/message_ids_element.rb +1 -6
  25. data/lib/mail/elements/mime_version_element.rb +3 -7
  26. data/lib/mail/elements/phrase_list.rb +2 -7
  27. data/lib/mail/elements/received_element.rb +3 -7
  28. data/lib/mail/encodings/quoted_printable.rb +4 -3
  29. data/lib/mail/encodings.rb +60 -28
  30. data/lib/mail/envelope.rb +0 -5
  31. data/lib/mail/field.rb +63 -28
  32. data/lib/mail/field_list.rb +18 -18
  33. data/lib/mail/fields/bcc_field.rb +2 -2
  34. data/lib/mail/fields/cc_field.rb +2 -2
  35. data/lib/mail/fields/comments_field.rb +1 -1
  36. data/lib/mail/fields/common/common_address.rb +26 -21
  37. data/lib/mail/fields/common/common_date.rb +0 -7
  38. data/lib/mail/fields/common/common_field.rb +5 -5
  39. data/lib/mail/fields/content_id_field.rb +1 -2
  40. data/lib/mail/fields/content_transfer_encoding_field.rb +2 -8
  41. data/lib/mail/fields/content_type_field.rb +1 -1
  42. data/lib/mail/fields/date_field.rb +14 -14
  43. data/lib/mail/fields/from_field.rb +2 -2
  44. data/lib/mail/fields/in_reply_to_field.rb +2 -1
  45. data/lib/mail/fields/message_id_field.rb +2 -3
  46. data/lib/mail/fields/references_field.rb +2 -1
  47. data/lib/mail/fields/reply_to_field.rb +2 -2
  48. data/lib/mail/fields/resent_bcc_field.rb +2 -2
  49. data/lib/mail/fields/resent_cc_field.rb +2 -2
  50. data/lib/mail/fields/resent_from_field.rb +2 -2
  51. data/lib/mail/fields/resent_sender_field.rb +3 -3
  52. data/lib/mail/fields/resent_to_field.rb +2 -2
  53. data/lib/mail/fields/sender_field.rb +8 -8
  54. data/lib/mail/fields/to_field.rb +2 -2
  55. data/lib/mail/fields/unstructured_field.rb +8 -2
  56. data/lib/mail/header.rb +13 -23
  57. data/lib/mail/mail.rb +12 -0
  58. data/lib/mail/matchers/has_sent_mail.rb +34 -1
  59. data/lib/mail/message.rb +151 -48
  60. data/lib/mail/multibyte/chars.rb +2 -2
  61. data/lib/mail/multibyte/unicode.rb +6 -4
  62. data/lib/mail/network/delivery_methods/exim.rb +1 -6
  63. data/lib/mail/network/delivery_methods/file_delivery.rb +1 -1
  64. data/lib/mail/network/delivery_methods/sendmail.rb +32 -10
  65. data/lib/mail/network/delivery_methods/smtp.rb +31 -34
  66. data/lib/mail/network/delivery_methods/smtp_connection.rb +6 -6
  67. data/lib/mail/network/delivery_methods/test_mailer.rb +2 -2
  68. data/lib/mail/network/retriever_methods/imap.rb +18 -13
  69. data/lib/mail/parsers/address_lists_parser.rb +132 -0
  70. data/lib/mail/parsers/content_disposition_parser.rb +67 -0
  71. data/lib/mail/parsers/content_location_parser.rb +35 -0
  72. data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
  73. data/lib/mail/parsers/content_type_parser.rb +64 -0
  74. data/lib/mail/parsers/date_time_parser.rb +36 -0
  75. data/lib/mail/parsers/envelope_from_parser.rb +45 -0
  76. data/lib/mail/parsers/message_ids_parser.rb +39 -0
  77. data/lib/mail/parsers/mime_version_parser.rb +41 -0
  78. data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
  79. data/lib/mail/parsers/ragel/common.rl +184 -0
  80. data/lib/mail/parsers/ragel/date_time.rl +30 -0
  81. data/lib/mail/parsers/ragel/parser_info.rb +61 -0
  82. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
  83. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
  84. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
  85. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
  86. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
  87. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
  88. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
  89. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
  90. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
  91. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
  92. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
  93. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
  94. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
  95. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
  96. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
  97. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
  98. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
  99. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
  100. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
  101. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
  102. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
  103. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
  104. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
  105. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
  106. data/lib/mail/parsers/ragel/ruby.rb +29 -0
  107. data/lib/mail/parsers/ragel.rb +17 -0
  108. data/lib/mail/parsers/received_parser.rb +47 -0
  109. data/lib/mail/parsers.rb +26 -0
  110. data/lib/mail/part.rb +6 -2
  111. data/lib/mail/parts_list.rb +5 -3
  112. data/lib/mail/patterns.rb +4 -1
  113. data/lib/mail/utilities.rb +28 -18
  114. data/lib/mail/version.rb +1 -1
  115. data/lib/mail/version_specific/ruby_1_8.rb +6 -2
  116. data/lib/mail/version_specific/ruby_1_9.rb +61 -21
  117. data/lib/mail.rb +1 -2
  118. metadata +112 -73
  119. data/lib/VERSION +0 -4
  120. data/lib/load_parsers.rb +0 -41
  121. data/lib/mail/core_extensions/shell_escape.rb +0 -56
  122. data/lib/mail/parsers/address_lists.rb +0 -64
  123. data/lib/mail/parsers/address_lists.treetop +0 -19
  124. data/lib/mail/parsers/content_disposition.rb +0 -535
  125. data/lib/mail/parsers/content_disposition.treetop +0 -46
  126. data/lib/mail/parsers/content_location.rb +0 -139
  127. data/lib/mail/parsers/content_location.treetop +0 -20
  128. data/lib/mail/parsers/content_transfer_encoding.rb +0 -162
  129. data/lib/mail/parsers/content_transfer_encoding.treetop +0 -20
  130. data/lib/mail/parsers/content_type.rb +0 -967
  131. data/lib/mail/parsers/content_type.treetop +0 -68
  132. data/lib/mail/parsers/date_time.rb +0 -114
  133. data/lib/mail/parsers/date_time.treetop +0 -11
  134. data/lib/mail/parsers/envelope_from.rb +0 -194
  135. data/lib/mail/parsers/envelope_from.treetop +0 -32
  136. data/lib/mail/parsers/message_ids.rb +0 -45
  137. data/lib/mail/parsers/message_ids.treetop +0 -15
  138. data/lib/mail/parsers/mime_version.rb +0 -144
  139. data/lib/mail/parsers/mime_version.treetop +0 -19
  140. data/lib/mail/parsers/phrase_lists.rb +0 -45
  141. data/lib/mail/parsers/phrase_lists.treetop +0 -15
  142. data/lib/mail/parsers/received.rb +0 -71
  143. data/lib/mail/parsers/received.treetop +0 -11
  144. data/lib/mail/parsers/rfc2045.rb +0 -464
  145. data/lib/mail/parsers/rfc2045.treetop +0 -36
  146. data/lib/mail/parsers/rfc2822.rb +0 -5397
  147. data/lib/mail/parsers/rfc2822.treetop +0 -410
  148. data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
  149. data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
  150. data/lib/tasks/corpus.rake +0 -125
  151. data/lib/tasks/treetop.rake +0 -10
@@ -6,7 +6,7 @@
6
6
  # field in the email.
7
7
  #
8
8
  # Sending resent_cc to a mail message will instantiate a Mail::Field object that
9
- # has a ResentCcField as it's field type. This includes all Mail::CommonAddress
9
+ # has a ResentCcField as its field type. This includes all Mail::CommonAddress
10
10
  # module instance metods.
11
11
  #
12
12
  # Only one Resent-Cc field can appear in a header, though it can have multiple
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # mail = Mail.new
18
18
  # mail.resent_cc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.resent_cc #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
19
+ # mail.resent_cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
20
20
  # mail[:resent_cc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentCcField:0x180e1c4
21
21
  # mail['resent-cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentCcField:0x180e1c4
22
22
  # mail['Resent-Cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentCcField:0x180e1c4
@@ -6,7 +6,7 @@
6
6
  # field in the email.
7
7
  #
8
8
  # Sending resent_from to a mail message will instantiate a Mail::Field object that
9
- # has a ResentFromField as it's field type. This includes all Mail::CommonAddress
9
+ # has a ResentFromField as its field type. This includes all Mail::CommonAddress
10
10
  # module instance metods.
11
11
  #
12
12
  # Only one Resent-From field can appear in a header, though it can have multiple
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # mail = Mail.new
18
18
  # mail.resent_from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.resent_from #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
19
+ # mail.resent_from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
20
20
  # mail[:resent_from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
21
21
  # mail['resent-from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
22
22
  # mail['Resent-From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
@@ -6,7 +6,7 @@
6
6
  # field in the email.
7
7
  #
8
8
  # Sending resent_sender to a mail message will instantiate a Mail::Field object that
9
- # has a ResentSenderField as it's field type. This includes all Mail::CommonAddress
9
+ # has a ResentSenderField as its field type. This includes all Mail::CommonAddress
10
10
  # module instance metods.
11
11
  #
12
12
  # Only one Resent-Sender field can appear in a header, though it can have multiple
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # mail = Mail.new
18
18
  # mail.resent_sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.resent_sender #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
19
+ # mail.resent_sender #=> ['mikel@test.lindsaar.net']
20
20
  # mail[:resent_sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
21
21
  # mail['resent-sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
22
22
  # mail['Resent-Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
@@ -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
@@ -6,7 +6,7 @@
6
6
  # field in the email.
7
7
  #
8
8
  # Sending resent_to to a mail message will instantiate a Mail::Field object that
9
- # has a ResentToField as it's field type. This includes all Mail::CommonAddress
9
+ # has a ResentToField as its field type. This includes all Mail::CommonAddress
10
10
  # module instance metods.
11
11
  #
12
12
  # Only one Resent-To field can appear in a header, though it can have multiple
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # mail = Mail.new
18
18
  # mail.resent_to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.resent_to #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
19
+ # mail.resent_to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
20
20
  # mail[:resent_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
21
21
  # mail['resent-to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
22
22
  # mail['Resent-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
@@ -6,7 +6,7 @@
6
6
  # field in the email.
7
7
  #
8
8
  # Sending sender to a mail message will instantiate a Mail::Field object that
9
- # has a SenderField as it's field type. This includes all Mail::CommonAddress
9
+ # has a SenderField as its field type. This includes all Mail::CommonAddress
10
10
  # module instance metods.
11
11
  #
12
12
  # Only one Sender field can appear in a header, though it can have multiple
@@ -15,16 +15,16 @@
15
15
  # == Examples:
16
16
  #
17
17
  # mail = Mail.new
18
- # mail.sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.sender #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
18
+ # mail.sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>'
19
+ # mail.sender #=> 'mikel@test.lindsaar.net'
20
20
  # mail[:sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
21
21
  # mail['sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
22
22
  # mail['Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
23
23
  #
24
- # mail[:sender].encoded #=> 'Sender: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
- # mail[:sender].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
- # mail[:sender].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
- # mail[:sender].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
24
+ # mail[:sender].encoded #=> "Sender: Mikel Lindsaar <mikel@test.lindsaar.net>\r\n"
25
+ # mail[:sender].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>'
26
+ # mail[:sender].addresses #=> ['mikel@test.lindsaar.net']
27
+ # mail[:sender].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>']
28
28
  #
29
29
  require 'mail/fields/common/common_address'
30
30
 
@@ -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
@@ -6,7 +6,7 @@
6
6
  # field in the email.
7
7
  #
8
8
  # Sending to to a mail message will instantiate a Mail::Field object that
9
- # has a ToField as it's field type. This includes all Mail::CommonAddress
9
+ # has a ToField as its field type. This includes all Mail::CommonAddress
10
10
  # module instance metods.
11
11
  #
12
12
  # Only one To field can appear in a header, though it can have multiple
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # mail = Mail.new
18
18
  # mail.to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.to #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
19
+ # mail.to #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
20
20
  # mail[:to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
21
21
  # mail['to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
22
22
  # mail['To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
@@ -144,9 +144,10 @@ 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
- word.encode!(charset) if defined?(Encoding) && charset
150
+ word.encode!(charset) if charset && word.respond_to?(:encode!)
150
151
  word = encode(word) if should_encode
151
152
  word = encode_crlf(word)
152
153
  # Skip to next line if we're going to go past the limit
@@ -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
- self.raw_source = header_text.to_crlf
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
@@ -154,6 +157,9 @@ module Mail
154
157
  # h['X-Mail-SPAM'] # => nil
155
158
  def []=(name, value)
156
159
  name = dasherize(name)
160
+ if name.include?(':')
161
+ raise ArgumentError, "Header names may not contain a colon: #{name.inspect}"
162
+ end
157
163
  fn = name.downcase
158
164
  selected = select_field_for(fn)
159
165
 
@@ -174,7 +180,7 @@ module Mail
174
180
  if dasherize(fn) == "content-type"
175
181
  # Update charset if specified in Content-Type
176
182
  params = self[:content_type].parameters rescue nil
177
- @charset = params && params[:charset]
183
+ @charset = params[:charset] if params && params[:charset]
178
184
  end
179
185
  end
180
186
 
@@ -198,6 +204,7 @@ module Mail
198
204
 
199
205
  def encoded
200
206
  buffer = ''
207
+ buffer.force_encoding('us-ascii') if buffer.respond_to?(:force_encoding)
201
208
  fields.each do |field|
202
209
  buffer << field.encoded
203
210
  end
@@ -242,27 +249,10 @@ module Mail
242
249
  @raw_source = val
243
250
  end
244
251
 
245
- # 2.2.3. Long Header Fields
246
- #
247
- # The process of moving from this folded multiple-line representation
248
- # of a header field to its single line representation is called
249
- # "unfolding". Unfolding is accomplished by simply removing any CRLF
250
- # that is immediately followed by WSP. Each header field should be
251
- # treated in its unfolded form for further syntactic and semantic
252
- # evaluation.
253
- def unfold(string)
254
- string.gsub(/#{CRLF}#{WSP}+/, ' ').gsub(/#{WSP}+/, ' ')
255
- end
256
-
257
- # Returns the header with all the folds removed
258
- def unfolded_header
259
- @unfolded_header ||= unfold(raw_source)
260
- end
261
-
262
252
  # Splits an unfolded and line break cleaned header into individual field
263
253
  # strings.
264
254
  def split_header
265
- self.fields = unfolded_header.split(CRLF)
255
+ self.fields = raw_source.split(HEADER_SPLIT)
266
256
  end
267
257
 
268
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')