rack-mail_exception 0.0.1

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