mail 2.6.1 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +150 -107
  4. data/lib/mail/attachments_list.rb +13 -10
  5. data/lib/mail/body.rb +104 -90
  6. data/lib/mail/check_delivery_params.rb +55 -10
  7. data/lib/mail/configuration.rb +3 -0
  8. data/lib/mail/constants.rb +79 -0
  9. data/lib/mail/elements/address.rb +96 -108
  10. data/lib/mail/elements/address_list.rb +13 -30
  11. data/lib/mail/elements/content_disposition_element.rb +10 -16
  12. data/lib/mail/elements/content_location_element.rb +9 -13
  13. data/lib/mail/elements/content_transfer_encoding_element.rb +7 -11
  14. data/lib/mail/elements/content_type_element.rb +17 -23
  15. data/lib/mail/elements/date_time_element.rb +8 -15
  16. data/lib/mail/elements/envelope_from_element.rb +23 -23
  17. data/lib/mail/elements/message_ids_element.rb +22 -15
  18. data/lib/mail/elements/mime_version_element.rb +8 -15
  19. data/lib/mail/elements/phrase_list.rb +13 -10
  20. data/lib/mail/elements/received_element.rb +28 -19
  21. data/lib/mail/elements.rb +1 -0
  22. data/lib/mail/encodings/7bit.rb +10 -14
  23. data/lib/mail/encodings/8bit.rb +5 -18
  24. data/lib/mail/encodings/base64.rb +15 -10
  25. data/lib/mail/encodings/binary.rb +4 -22
  26. data/lib/mail/encodings/identity.rb +24 -0
  27. data/lib/mail/encodings/quoted_printable.rb +13 -7
  28. data/lib/mail/encodings/transfer_encoding.rb +47 -28
  29. data/lib/mail/encodings/unix_to_unix.rb +20 -0
  30. data/lib/mail/encodings.rb +102 -92
  31. data/lib/mail/envelope.rb +12 -14
  32. data/lib/mail/field.rb +121 -85
  33. data/lib/mail/field_list.rb +62 -8
  34. data/lib/mail/fields/bcc_field.rb +42 -48
  35. data/lib/mail/fields/cc_field.rb +29 -50
  36. data/lib/mail/fields/comments_field.rb +28 -37
  37. data/lib/mail/fields/common_address_field.rb +170 -0
  38. data/lib/mail/fields/common_date_field.rb +58 -0
  39. data/lib/mail/fields/common_field.rb +77 -0
  40. data/lib/mail/fields/common_message_id_field.rb +42 -0
  41. data/lib/mail/fields/content_description_field.rb +8 -14
  42. data/lib/mail/fields/content_disposition_field.rb +20 -44
  43. data/lib/mail/fields/content_id_field.rb +25 -51
  44. data/lib/mail/fields/content_location_field.rb +12 -25
  45. data/lib/mail/fields/content_transfer_encoding_field.rb +32 -31
  46. data/lib/mail/fields/content_type_field.rb +51 -80
  47. data/lib/mail/fields/date_field.rb +24 -52
  48. data/lib/mail/fields/from_field.rb +29 -50
  49. data/lib/mail/fields/in_reply_to_field.rb +39 -49
  50. data/lib/mail/fields/keywords_field.rb +19 -32
  51. data/lib/mail/fields/message_id_field.rb +26 -71
  52. data/lib/mail/fields/mime_version_field.rb +20 -30
  53. data/lib/mail/fields/named_structured_field.rb +11 -0
  54. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  55. data/lib/mail/fields/optional_field.rb +10 -7
  56. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +16 -13
  57. data/lib/mail/fields/received_field.rb +44 -57
  58. data/lib/mail/fields/references_field.rb +36 -49
  59. data/lib/mail/fields/reply_to_field.rb +29 -50
  60. data/lib/mail/fields/resent_bcc_field.rb +29 -50
  61. data/lib/mail/fields/resent_cc_field.rb +29 -50
  62. data/lib/mail/fields/resent_date_field.rb +6 -30
  63. data/lib/mail/fields/resent_from_field.rb +29 -50
  64. data/lib/mail/fields/resent_message_id_field.rb +6 -29
  65. data/lib/mail/fields/resent_sender_field.rb +28 -57
  66. data/lib/mail/fields/resent_to_field.rb +29 -50
  67. data/lib/mail/fields/return_path_field.rb +51 -55
  68. data/lib/mail/fields/sender_field.rb +35 -56
  69. data/lib/mail/fields/structured_field.rb +4 -30
  70. data/lib/mail/fields/subject_field.rb +10 -11
  71. data/lib/mail/fields/to_field.rb +29 -50
  72. data/lib/mail/fields/unstructured_field.rb +36 -50
  73. data/lib/mail/fields.rb +1 -0
  74. data/lib/mail/header.rb +73 -110
  75. data/lib/mail/indifferent_hash.rb +1 -0
  76. data/lib/mail/mail.rb +6 -11
  77. data/lib/mail/matchers/attachment_matchers.rb +44 -0
  78. data/lib/mail/matchers/has_sent_mail.rb +53 -9
  79. data/lib/mail/message.rb +132 -136
  80. data/lib/mail/multibyte/chars.rb +24 -180
  81. data/lib/mail/multibyte/unicode.rb +31 -26
  82. data/lib/mail/multibyte/utils.rb +27 -43
  83. data/lib/mail/multibyte.rb +56 -16
  84. data/lib/mail/network/delivery_methods/exim.rb +9 -11
  85. data/lib/mail/network/delivery_methods/file_delivery.rb +14 -16
  86. data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  87. data/lib/mail/network/delivery_methods/sendmail.rb +68 -24
  88. data/lib/mail/network/delivery_methods/smtp.rb +77 -54
  89. data/lib/mail/network/delivery_methods/smtp_connection.rb +5 -9
  90. data/lib/mail/network/delivery_methods/test_mailer.rb +9 -9
  91. data/lib/mail/network/retriever_methods/base.rb +9 -8
  92. data/lib/mail/network/retriever_methods/imap.rb +21 -7
  93. data/lib/mail/network/retriever_methods/pop3.rb +6 -3
  94. data/lib/mail/network/retriever_methods/test_retriever.rb +4 -2
  95. data/lib/mail/network.rb +2 -0
  96. data/lib/mail/parser_tools.rb +15 -0
  97. data/lib/mail/parsers/address_lists_parser.rb +33226 -116
  98. data/lib/mail/parsers/address_lists_parser.rl +179 -0
  99. data/lib/mail/parsers/content_disposition_parser.rb +883 -49
  100. data/lib/mail/parsers/content_disposition_parser.rl +89 -0
  101. data/lib/mail/parsers/content_location_parser.rb +810 -23
  102. data/lib/mail/parsers/content_location_parser.rl +78 -0
  103. data/lib/mail/parsers/content_transfer_encoding_parser.rb +510 -21
  104. data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
  105. data/lib/mail/parsers/content_type_parser.rb +1031 -47
  106. data/lib/mail/parsers/content_type_parser.rl +90 -0
  107. data/lib/mail/parsers/date_time_parser.rb +879 -24
  108. data/lib/mail/parsers/date_time_parser.rl +69 -0
  109. data/lib/mail/parsers/envelope_from_parser.rb +3670 -40
  110. data/lib/mail/parsers/envelope_from_parser.rl +89 -0
  111. data/lib/mail/parsers/message_ids_parser.rb +5147 -25
  112. data/lib/mail/parsers/message_ids_parser.rl +93 -0
  113. data/lib/mail/parsers/mime_version_parser.rb +498 -26
  114. data/lib/mail/parsers/mime_version_parser.rl +68 -0
  115. data/lib/mail/parsers/phrase_lists_parser.rb +872 -21
  116. data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
  117. data/lib/mail/parsers/received_parser.rb +8777 -42
  118. data/lib/mail/parsers/received_parser.rl +91 -0
  119. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  120. data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  121. data/lib/mail/parsers/rfc2045_mime.rl +16 -0
  122. data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  123. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  124. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  125. data/lib/mail/parsers/rfc5322.rl +74 -0
  126. data/lib/mail/parsers/rfc5322_address.rl +72 -0
  127. data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
  128. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  129. data/lib/mail/parsers.rb +12 -25
  130. data/lib/mail/part.rb +11 -12
  131. data/lib/mail/parts_list.rb +88 -14
  132. data/lib/mail/smtp_envelope.rb +57 -0
  133. data/lib/mail/utilities.rb +377 -40
  134. data/lib/mail/values/unicode_tables.dat +0 -0
  135. data/lib/mail/version.rb +8 -15
  136. data/lib/mail/yaml.rb +30 -0
  137. data/lib/mail.rb +9 -32
  138. metadata +138 -94
  139. data/CHANGELOG.rdoc +0 -752
  140. data/CONTRIBUTING.md +0 -60
  141. data/Dependencies.txt +0 -2
  142. data/Gemfile +0 -15
  143. data/Rakefile +0 -29
  144. data/TODO.rdoc +0 -9
  145. data/VERSION +0 -4
  146. data/lib/mail/core_extensions/nil.rb +0 -19
  147. data/lib/mail/core_extensions/object.rb +0 -13
  148. data/lib/mail/core_extensions/smtp.rb +0 -24
  149. data/lib/mail/core_extensions/string/access.rb +0 -145
  150. data/lib/mail/core_extensions/string/multibyte.rb +0 -78
  151. data/lib/mail/core_extensions/string.rb +0 -43
  152. data/lib/mail/fields/common/address_container.rb +0 -16
  153. data/lib/mail/fields/common/common_address.rb +0 -135
  154. data/lib/mail/fields/common/common_date.rb +0 -35
  155. data/lib/mail/fields/common/common_field.rb +0 -57
  156. data/lib/mail/fields/common/common_message_id.rb +0 -48
  157. data/lib/mail/multibyte/exceptions.rb +0 -8
  158. data/lib/mail/parsers/ragel/common.rl +0 -184
  159. data/lib/mail/parsers/ragel/parser_info.rb +0 -61
  160. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
  161. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
  162. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
  163. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
  164. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
  165. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
  166. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
  167. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
  168. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
  169. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
  170. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
  171. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
  172. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2129
  173. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
  174. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
  175. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
  176. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
  177. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
  178. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
  179. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
  180. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
  181. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
  182. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
  183. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
  184. data/lib/mail/parsers/ragel/ruby.rb +0 -39
  185. data/lib/mail/parsers/ragel.rb +0 -17
  186. data/lib/mail/patterns.rb +0 -37
  187. data/lib/mail/version_specific/ruby_1_8.rb +0 -119
  188. data/lib/mail/version_specific/ruby_1_9.rb +0 -159
@@ -1,57 +1,29 @@
1
1
  # encoding: utf-8
2
- #
3
- # = Date Field
4
- #
5
- # The Date field inherits from StructuredField and handles the Date: header
6
- # field in the email.
7
- #
8
- # Sending date to a mail message will instantiate a Mail::Field object that
9
- # has a DateField as its field type. This includes all Mail::CommonAddress
10
- # module instance methods.
11
- #
12
- # There must be excatly one Date field in an RFC2822 email.
13
- #
14
- # == Examples:
15
- #
16
- # mail = Mail.new
17
- # mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
18
- # mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
19
- # mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
20
- # mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
21
- # mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
22
- # mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
23
- #
24
- require 'mail/fields/common/common_date'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_date_field'
25
4
 
26
5
  module Mail
27
- class DateField < StructuredField
28
-
29
- include Mail::CommonDate
30
-
31
- FIELD_NAME = 'date'
32
- CAPITALIZED_FIELD = "Date"
33
-
34
- def initialize(value = nil, charset = 'utf-8')
35
- self.charset = charset
36
- if value.blank?
37
- value = ::DateTime.now.strftime('%a, %d %b %Y %H:%M:%S %z')
38
- else
39
- value = strip_field(FIELD_NAME, value)
40
- value.to_s.gsub!(/\(.*?\)/, '')
41
- value = ::DateTime.parse(value.to_s.squeeze(" ")).strftime('%a, %d %b %Y %H:%M:%S %z')
42
- end
43
- super(CAPITALIZED_FIELD, value, charset)
44
- rescue ArgumentError => e
45
- raise e unless "invalid date"==e.message
46
- end
47
-
48
- def encoded
49
- do_encode(CAPITALIZED_FIELD)
50
- end
51
-
52
- def decoded
53
- do_decode
54
- end
55
-
6
+ # = Date Field
7
+ #
8
+ # The Date field inherits from StructuredField and handles the Date: header
9
+ # field in the email.
10
+ #
11
+ # Sending date to a mail message will instantiate a Mail::Field object that
12
+ # has a DateField as its field type. This includes all Mail::CommonAddress
13
+ # module instance methods.
14
+ #
15
+ # There must be excatly one Date field in an RFC2822 email.
16
+ #
17
+ # == Examples:
18
+ #
19
+ # mail = Mail.new
20
+ # mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
21
+ # mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
22
+ # mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
23
+ # mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
24
+ # mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
25
+ # mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
26
+ class DateField < CommonDateField #:nodoc:
27
+ NAME = 'Date'
56
28
  end
57
29
  end
@@ -1,55 +1,34 @@
1
1
  # encoding: utf-8
2
- #
3
- # = From Field
4
- #
5
- # The From field inherits from StructuredField and handles the From: header
6
- # field in the email.
7
- #
8
- # Sending from to a mail message will instantiate a Mail::Field object that
9
- # has a FromField as its field type. This includes all Mail::CommonAddress
10
- # module instance metods.
11
- #
12
- # Only one From field can appear in a header, though it can have multiple
13
- # addresses and groups of addresses.
14
- #
15
- # == Examples:
16
- #
17
- # mail = Mail.new
18
- # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
20
- # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
21
- # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
22
- # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
23
- #
24
- # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
- # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
- # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
- # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
28
- #
29
- require 'mail/fields/common/common_address'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_address_field'
30
4
 
31
5
  module Mail
32
- class FromField < StructuredField
33
-
34
- include Mail::CommonAddress
35
-
36
- FIELD_NAME = 'from'
37
- CAPITALIZED_FIELD = 'From'
38
-
39
- def initialize(value = nil, charset = 'utf-8')
40
- self.charset = charset
41
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
42
- self.parse
43
- self
44
- end
45
-
46
- def encoded
47
- do_encode(CAPITALIZED_FIELD)
48
- end
49
-
50
- def decoded
51
- do_decode
52
- end
53
-
6
+ # = From Field
7
+ #
8
+ # The From field inherits from StructuredField and handles the From: header
9
+ # field in the email.
10
+ #
11
+ # Sending from to a mail message will instantiate a Mail::Field object that
12
+ # has a FromField as its field type. This includes all Mail::CommonAddress
13
+ # module instance metods.
14
+ #
15
+ # Only one From field can appear in a header, though it can have multiple
16
+ # addresses and groups of addresses.
17
+ #
18
+ # == Examples:
19
+ #
20
+ # mail = Mail.new
21
+ # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
22
+ # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
23
+ # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
24
+ # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
25
+ # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
26
+ #
27
+ # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
28
+ # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
29
+ # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
30
+ # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
31
+ class FromField < CommonAddressField #:nodoc:
32
+ NAME = 'From'
54
33
  end
55
34
  end
@@ -1,56 +1,46 @@
1
1
  # encoding: utf-8
2
- #
3
- # = In-Reply-To Field
4
- #
5
- # The In-Reply-To field inherits from StructuredField and handles the
6
- # In-Reply-To: header field in the email.
7
- #
8
- # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
9
- # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
10
- # module instance metods.
11
- #
12
- # Note that, the #message_ids method will return an array of message IDs without the
13
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
14
- #
15
- # Only one InReplyTo field can appear in a header, though it can have multiple
16
- # Message IDs.
17
- #
18
- # == Examples:
19
- #
20
- # mail = Mail.new
21
- # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
22
- # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
23
- # mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
24
- # mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
25
- # mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
26
- #
27
- # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
28
- #
29
- require 'mail/fields/common/common_message_id'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_message_id_field'
30
4
 
31
5
  module Mail
32
- class InReplyToField < StructuredField
33
-
34
- include Mail::CommonMessageId
35
-
36
- FIELD_NAME = 'in-reply-to'
37
- CAPITALIZED_FIELD = 'In-Reply-To'
38
-
39
- def initialize(value = nil, charset = 'utf-8')
40
- self.charset = charset
41
- value = value.join("\r\n\s") if value.is_a?(Array)
42
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
43
- self.parse
44
- self
45
- end
46
-
47
- def encoded
48
- do_encode(CAPITALIZED_FIELD)
6
+ # = In-Reply-To Field
7
+ #
8
+ # The In-Reply-To field inherits from StructuredField and handles the
9
+ # In-Reply-To: header field in the email.
10
+ #
11
+ # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
12
+ # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
13
+ # module instance metods.
14
+ #
15
+ # Note that, the #message_ids method will return an array of message IDs without the
16
+ # enclosing angle brackets which per RFC are not syntactically part of the message id.
17
+ #
18
+ # Only one InReplyTo field can appear in a header, though it can have multiple
19
+ # Message IDs.
20
+ #
21
+ # == Examples:
22
+ #
23
+ # mail = Mail.new
24
+ # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
25
+ # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
26
+ # mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
27
+ # mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
28
+ # mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
29
+ #
30
+ # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
31
+ class InReplyToField < CommonMessageIdField #:nodoc:
32
+ NAME = 'In-Reply-To'
33
+
34
+ def self.singular?
35
+ true
49
36
  end
50
-
51
- def decoded
52
- do_decode
37
+
38
+ def initialize(value = nil, charset = nil)
39
+ if value.is_a?(Array)
40
+ super value.join("\r\n\s"), charset
41
+ else
42
+ super
43
+ end
53
44
  end
54
-
55
45
  end
56
46
  end
@@ -1,44 +1,31 @@
1
1
  # encoding: utf-8
2
- #
3
- # keywords = "Keywords:" phrase *("," phrase) CRLF
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+
4
5
  module Mail
5
- class KeywordsField < StructuredField
6
-
7
- FIELD_NAME = 'keywords'
8
- CAPITALIZED_FIELD = 'Keywords'
9
-
10
- def initialize(value = nil, charset = 'utf-8')
11
- self.charset = charset
12
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
13
- self.parse
14
- self
15
- end
6
+ # keywords = "Keywords:" phrase *("," phrase) CRLF
7
+ class KeywordsField < NamedStructuredField #:nodoc:
8
+ NAME = 'Keywords'
16
9
 
17
- def parse(val = value)
18
- unless val.blank?
19
- @phrase_list ||= PhraseList.new(value)
20
- end
10
+ def element
11
+ @element ||= PhraseList.new(value)
21
12
  end
22
-
23
- def phrase_list
24
- @phrase_list ||= PhraseList.new(value)
25
- end
26
-
13
+
27
14
  def keywords
28
- phrase_list.phrases
29
- end
30
-
31
- def encoded
32
- "#{CAPITALIZED_FIELD}: #{keywords.join(",\r\n ")}\r\n"
33
- end
34
-
35
- def decoded
36
- keywords.join(', ')
15
+ element.phrases
37
16
  end
38
17
 
39
18
  def default
40
19
  keywords
41
20
  end
42
-
21
+
22
+ private
23
+ def do_decode
24
+ keywords.join(', ')
25
+ end
26
+
27
+ def do_encode
28
+ "#{name}: #{keywords.join(",\r\n ")}\r\n"
29
+ end
43
30
  end
44
31
  end
@@ -1,82 +1,37 @@
1
1
  # encoding: utf-8
2
- #
3
- # = Message-ID Field
4
- #
5
- # The Message-ID field inherits from StructuredField and handles the
6
- # Message-ID: header field in the email.
7
- #
8
- # Sending message_id to a mail message will instantiate a Mail::Field object that
9
- # has a MessageIdField as its field type. This includes all Mail::CommonMessageId
10
- # module instance metods.
11
- #
12
- # Only one MessageId field can appear in a header, and syntactically it can only have
13
- # one Message ID. The message_ids method call has been left in however as it will only
14
- # return the one message id, ie, an array of length 1.
15
- #
16
- # Note that, the #message_ids method will return an array of message IDs without the
17
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
18
- #
19
- # == Examples:
20
- #
21
- # mail = Mail.new
22
- # mail.message_id = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
23
- # mail.message_id #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
24
- # mail[:message_id] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
25
- # mail['message_id'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
26
- # mail['Message-ID'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
27
- #
28
- # mail[:message_id].message_id #=> 'F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom'
29
- # mail[:message_id].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
30
- #
31
- require 'mail/fields/common/common_message_id'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_message_id_field'
4
+ require 'mail/utilities'
32
5
 
33
6
  module Mail
34
- class MessageIdField < StructuredField
35
-
36
- include Mail::CommonMessageId
37
-
38
- FIELD_NAME = 'message-id'
39
- CAPITALIZED_FIELD = 'Message-ID'
40
-
41
- def initialize(value = nil, charset = 'utf-8')
42
- self.charset = charset
43
- @uniq = 1
44
- if value.blank?
45
- self.name = CAPITALIZED_FIELD
46
- self.value = generate_message_id
47
- else
48
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
49
- end
50
- self.parse
51
- self
7
+ # Only one Message-ID field may appear in a header.
8
+ #
9
+ # Note that parsed Message IDs do not contain their enclosing angle
10
+ # brackets which, per RFC, are not part of the ID.
11
+ #
12
+ # mail = Mail.new
13
+ # mail.message_id = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
14
+ # mail.message_id #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
15
+ # mail[:message_id] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
16
+ # mail['message_id'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
17
+ # mail['Message-ID'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
18
+ #
19
+ # mail[:message_id].message_id #=> 'F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom'
20
+ # mail[:message_id].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
21
+ class MessageIdField < CommonMessageIdField #:nodoc:
22
+ NAME = 'Message-ID'
52
23
 
24
+ def self.singular?
25
+ true
53
26
  end
54
-
55
- def name
56
- 'Message-ID'
27
+
28
+ def initialize(value = nil, charset = nil)
29
+ value = Mail::Utilities.generate_message_id if Utilities.blank?(value)
30
+ super value, charset
57
31
  end
58
-
32
+
59
33
  def message_ids
60
34
  [message_id]
61
35
  end
62
-
63
- def to_s
64
- "<#{message_id}>"
65
- end
66
-
67
- def encoded
68
- do_encode(CAPITALIZED_FIELD)
69
- end
70
-
71
- def decoded
72
- do_decode
73
- end
74
-
75
- private
76
-
77
- def generate_message_id
78
- "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
79
- end
80
-
81
36
  end
82
37
  end
@@ -1,34 +1,25 @@
1
1
  # encoding: utf-8
2
- #
3
- #
4
- #
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/utilities'
5
+
5
6
  module Mail
6
- class MimeVersionField < StructuredField
7
-
8
- FIELD_NAME = 'mime-version'
9
- CAPITALIZED_FIELD = 'Mime-Version'
10
-
11
- def initialize(value = nil, charset = 'utf-8')
12
- self.charset = charset
13
- if value.blank?
14
- value = '1.0'
15
- end
16
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
17
- self.parse
18
- self
19
-
20
- end
21
-
22
- def parse(val = value)
23
- unless val.blank?
24
- @element = Mail::MimeVersionElement.new(val)
25
- end
26
- end
27
-
7
+ class MimeVersionField < NamedStructuredField #:nodoc:
8
+ NAME = 'Mime-Version'
9
+
10
+ def self.singular?
11
+ true
12
+ end
13
+
14
+ def initialize(value = nil, charset = nil)
15
+ value = '1.0' if Utilities.blank?(value)
16
+ super value, charset
17
+ end
18
+
28
19
  def element
29
20
  @element ||= Mail::MimeVersionElement.new(value)
30
21
  end
31
-
22
+
32
23
  def version
33
24
  "#{element.major}.#{element.minor}"
34
25
  end
@@ -40,14 +31,13 @@ module Mail
40
31
  def minor
41
32
  element.minor.to_i
42
33
  end
43
-
34
+
44
35
  def encoded
45
- "#{CAPITALIZED_FIELD}: #{version}\r\n"
36
+ "#{name}: #{version}\r\n"
46
37
  end
47
-
38
+
48
39
  def decoded
49
40
  version
50
41
  end
51
-
52
42
  end
53
43
  end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/structured_field'
4
+
5
+ module Mail
6
+ class NamedStructuredField < StructuredField #:nodoc:
7
+ def initialize(value = nil, charset = nil)
8
+ super self.class::NAME, value, charset
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/unstructured_field'
4
+
5
+ module Mail
6
+ class NamedUnstructuredField < UnstructuredField #:nodoc:
7
+ def initialize(value = nil, charset = nil)
8
+ super self.class::NAME, value, charset
9
+ end
10
+ end
11
+ end
@@ -1,13 +1,16 @@
1
1
  # encoding: utf-8
2
- #
3
- # The field names of any optional-field MUST NOT be identical to any
4
- # field name specified elsewhere in this standard.
5
- #
6
- # optional-field = field-name ":" unstructured CRLF
2
+ # frozen_string_literal: true
7
3
  require 'mail/fields/unstructured_field'
8
4
 
9
5
  module Mail
10
- class OptionalField < UnstructuredField
11
-
6
+ # The field names of any optional-field MUST NOT be identical to any
7
+ # field name specified elsewhere in this standard.
8
+ #
9
+ # optional-field = field-name ":" unstructured CRLF
10
+ class OptionalField < UnstructuredField #:nodoc:
11
+ private
12
+ def do_encode
13
+ "#{wrapped_value}\r\n"
14
+ end
12
15
  end
13
16
  end
@@ -1,35 +1,38 @@
1
1
  # encoding: utf-8
2
- module Mail
2
+ # frozen_string_literal: true
3
+ require 'mail/constants'
4
+ require 'mail/indifferent_hash'
5
+ require 'mail/encodings'
3
6
 
7
+ module Mail
4
8
  # ParameterHash is an intelligent Hash that allows you to add
5
9
  # parameter values including the MIME extension paramaters that
6
10
  # have the name*0="blah", name*1="bleh" keys, and will just return
7
11
  # a single key called name="blahbleh" and do any required un-encoding
8
12
  # to make that happen
9
- # Parameters are defined in RFC2045, split keys are in RFC2231
10
-
11
- class ParameterHash < IndifferentHash
12
-
13
- include Mail::Utilities
14
-
13
+ #
14
+ # Parameters are defined in RFC2045. Split keys are in RFC2231.
15
+ class ParameterHash < IndifferentHash #:nodoc:
15
16
  def [](key_name)
16
17
  key_pattern = Regexp.escape(key_name.to_s)
17
18
  pairs = []
18
19
  exact = nil
20
+
19
21
  each do |k,v|
20
22
  if k =~ /^#{key_pattern}(\*|$)/i
21
- if $1 == '*'
23
+ if $1 == Constants::ASTERISK
22
24
  pairs << [k, v]
23
25
  else
24
26
  exact = k
25
27
  end
26
28
  end
27
29
  end
30
+
28
31
  if pairs.empty? # Just dealing with a single value pair
29
32
  super(exact || key_name)
30
33
  else # Dealing with a multiple value pair or a single encoded value pair
31
34
  string = pairs.sort { |a,b| a.first.to_s <=> b.first.to_s }.map { |v| v.last }.join('')
32
- if mt = string.match(/([\w\-]+)'(\w\w)'(.*)/)
35
+ if mt = string.match(/([\w\-]+)?'(\w\w)?'(.*)/)
33
36
  string = mt[3]
34
37
  encoding = mt[1]
35
38
  else
@@ -40,18 +43,18 @@ module Mail
40
43
  end
41
44
 
42
45
  def encoded
43
- map.sort { |a,b| a.first.to_s <=> b.first.to_s }.map do |key_name, value|
46
+ map.sort_by { |a| a.first.to_s }.map! do |key_name, value|
44
47
  unless value.ascii_only?
45
48
  value = Mail::Encodings.param_encode(value)
46
49
  key_name = "#{key_name}*"
47
50
  end
48
- %Q{#{key_name}=#{quote_token(value)}}
51
+ %Q{#{key_name}=#{Utilities.quote_token(value)}}
49
52
  end.join(";\r\n\s")
50
53
  end
51
54
 
52
55
  def decoded
53
- map.sort { |a,b| a.first.to_s <=> b.first.to_s }.map do |key_name, value|
54
- %Q{#{key_name}=#{quote_token(value)}}
56
+ map.sort_by { |a| a.first.to_s }.map! do |key_name, value|
57
+ %Q{#{key_name}=#{Utilities.quote_token(value)}}
55
58
  end.join("; ")
56
59
  end
57
60
  end