mail 2.6.4 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +111 -118
  3. data/lib/mail/attachments_list.rb +11 -10
  4. data/lib/mail/body.rb +73 -84
  5. data/lib/mail/check_delivery_params.rb +54 -10
  6. data/lib/mail/configuration.rb +2 -0
  7. data/lib/mail/constants.rb +27 -5
  8. data/lib/mail/elements/address.rb +61 -50
  9. data/lib/mail/elements/address_list.rb +11 -19
  10. data/lib/mail/elements/content_disposition_element.rb +9 -16
  11. data/lib/mail/elements/content_location_element.rb +6 -11
  12. data/lib/mail/elements/content_transfer_encoding_element.rb +6 -11
  13. data/lib/mail/elements/content_type_element.rb +16 -23
  14. data/lib/mail/elements/date_time_element.rb +7 -15
  15. data/lib/mail/elements/envelope_from_element.rb +22 -23
  16. data/lib/mail/elements/message_ids_element.rb +18 -13
  17. data/lib/mail/elements/mime_version_element.rb +7 -15
  18. data/lib/mail/elements/phrase_list.rb +12 -10
  19. data/lib/mail/elements/received_element.rb +27 -19
  20. data/lib/mail/encodings/7bit.rb +9 -14
  21. data/lib/mail/encodings/8bit.rb +2 -21
  22. data/lib/mail/encodings/base64.rb +11 -12
  23. data/lib/mail/encodings/binary.rb +3 -22
  24. data/lib/mail/encodings/identity.rb +24 -0
  25. data/lib/mail/encodings/quoted_printable.rb +6 -6
  26. data/lib/mail/encodings/transfer_encoding.rb +38 -29
  27. data/lib/mail/encodings/unix_to_unix.rb +3 -1
  28. data/lib/mail/encodings.rb +81 -54
  29. data/lib/mail/envelope.rb +11 -14
  30. data/lib/mail/field.rb +119 -98
  31. data/lib/mail/field_list.rb +60 -7
  32. data/lib/mail/fields/bcc_field.rb +34 -52
  33. data/lib/mail/fields/cc_field.rb +28 -49
  34. data/lib/mail/fields/comments_field.rb +27 -37
  35. data/lib/mail/fields/common_address_field.rb +170 -0
  36. data/lib/mail/fields/common_date_field.rb +58 -0
  37. data/lib/mail/fields/common_field.rb +77 -0
  38. data/lib/mail/fields/common_message_id_field.rb +42 -0
  39. data/lib/mail/fields/content_description_field.rb +7 -14
  40. data/lib/mail/fields/content_disposition_field.rb +13 -38
  41. data/lib/mail/fields/content_id_field.rb +24 -51
  42. data/lib/mail/fields/content_location_field.rb +11 -25
  43. data/lib/mail/fields/content_transfer_encoding_field.rb +31 -31
  44. data/lib/mail/fields/content_type_field.rb +50 -80
  45. data/lib/mail/fields/date_field.rb +23 -52
  46. data/lib/mail/fields/from_field.rb +28 -49
  47. data/lib/mail/fields/in_reply_to_field.rb +38 -49
  48. data/lib/mail/fields/keywords_field.rb +18 -31
  49. data/lib/mail/fields/message_id_field.rb +25 -71
  50. data/lib/mail/fields/mime_version_field.rb +19 -30
  51. data/lib/mail/fields/named_structured_field.rb +11 -0
  52. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  53. data/lib/mail/fields/optional_field.rb +9 -7
  54. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +13 -11
  55. data/lib/mail/fields/received_field.rb +43 -57
  56. data/lib/mail/fields/references_field.rb +35 -49
  57. data/lib/mail/fields/reply_to_field.rb +28 -49
  58. data/lib/mail/fields/resent_bcc_field.rb +28 -49
  59. data/lib/mail/fields/resent_cc_field.rb +28 -49
  60. data/lib/mail/fields/resent_date_field.rb +5 -30
  61. data/lib/mail/fields/resent_from_field.rb +28 -49
  62. data/lib/mail/fields/resent_message_id_field.rb +5 -29
  63. data/lib/mail/fields/resent_sender_field.rb +27 -56
  64. data/lib/mail/fields/resent_to_field.rb +28 -49
  65. data/lib/mail/fields/return_path_field.rb +50 -54
  66. data/lib/mail/fields/sender_field.rb +34 -55
  67. data/lib/mail/fields/structured_field.rb +3 -30
  68. data/lib/mail/fields/subject_field.rb +9 -11
  69. data/lib/mail/fields/to_field.rb +28 -49
  70. data/lib/mail/fields/unstructured_field.rb +32 -47
  71. data/lib/mail/header.rb +71 -110
  72. data/lib/mail/mail.rb +2 -10
  73. data/lib/mail/matchers/attachment_matchers.rb +15 -0
  74. data/lib/mail/matchers/has_sent_mail.rb +21 -1
  75. data/lib/mail/message.rb +113 -117
  76. data/lib/mail/multibyte/chars.rb +23 -180
  77. data/lib/mail/multibyte/unicode.rb +10 -10
  78. data/lib/mail/multibyte/utils.rb +26 -43
  79. data/lib/mail/multibyte.rb +55 -16
  80. data/lib/mail/network/delivery_methods/exim.rb +8 -11
  81. data/lib/mail/network/delivery_methods/file_delivery.rb +13 -16
  82. data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  83. data/lib/mail/network/delivery_methods/sendmail.rb +32 -35
  84. data/lib/mail/network/delivery_methods/smtp.rb +76 -54
  85. data/lib/mail/network/delivery_methods/smtp_connection.rb +4 -9
  86. data/lib/mail/network/delivery_methods/test_mailer.rb +8 -9
  87. data/lib/mail/network/retriever_methods/base.rb +8 -8
  88. data/lib/mail/network/retriever_methods/imap.rb +20 -7
  89. data/lib/mail/network/retriever_methods/pop3.rb +5 -3
  90. data/lib/mail/network/retriever_methods/test_retriever.rb +3 -2
  91. data/lib/mail/network.rb +1 -0
  92. data/lib/mail/parser_tools.rb +15 -0
  93. data/lib/mail/parsers/address_lists_parser.rb +33225 -116
  94. data/lib/mail/parsers/address_lists_parser.rl +179 -0
  95. data/lib/mail/parsers/content_disposition_parser.rb +882 -49
  96. data/lib/mail/parsers/content_disposition_parser.rl +89 -0
  97. data/lib/mail/parsers/content_location_parser.rb +809 -23
  98. data/lib/mail/parsers/content_location_parser.rl +78 -0
  99. data/lib/mail/parsers/content_transfer_encoding_parser.rb +509 -21
  100. data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
  101. data/lib/mail/parsers/content_type_parser.rb +1037 -56
  102. data/lib/mail/parsers/content_type_parser.rl +90 -0
  103. data/lib/mail/parsers/date_time_parser.rb +877 -25
  104. data/lib/mail/parsers/date_time_parser.rl +69 -0
  105. data/lib/mail/parsers/envelope_from_parser.rb +3669 -40
  106. data/lib/mail/parsers/envelope_from_parser.rl +89 -0
  107. data/lib/mail/parsers/message_ids_parser.rb +5146 -25
  108. data/lib/mail/parsers/message_ids_parser.rl +93 -0
  109. data/lib/mail/parsers/mime_version_parser.rb +497 -26
  110. data/lib/mail/parsers/mime_version_parser.rl +68 -0
  111. data/lib/mail/parsers/phrase_lists_parser.rb +870 -22
  112. data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
  113. data/lib/mail/parsers/received_parser.rb +8776 -43
  114. data/lib/mail/parsers/received_parser.rl +91 -0
  115. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  116. data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  117. data/lib/mail/parsers/rfc2045_mime.rl +16 -0
  118. data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  119. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  120. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  121. data/lib/mail/parsers/rfc5322.rl +74 -0
  122. data/lib/mail/parsers/rfc5322_address.rl +72 -0
  123. data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
  124. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  125. data/lib/mail/parsers.rb +11 -25
  126. data/lib/mail/part.rb +6 -10
  127. data/lib/mail/parts_list.rb +62 -6
  128. data/lib/mail/smtp_envelope.rb +57 -0
  129. data/lib/mail/utilities.rb +357 -74
  130. data/lib/mail/version.rb +2 -2
  131. data/lib/mail/yaml.rb +30 -0
  132. data/lib/mail.rb +5 -35
  133. metadata +111 -66
  134. data/CHANGELOG.rdoc +0 -787
  135. data/CONTRIBUTING.md +0 -60
  136. data/Dependencies.txt +0 -2
  137. data/Gemfile +0 -11
  138. data/Rakefile +0 -29
  139. data/TODO.rdoc +0 -9
  140. data/lib/mail/core_extensions/smtp.rb +0 -25
  141. data/lib/mail/core_extensions/string/access.rb +0 -146
  142. data/lib/mail/core_extensions/string/multibyte.rb +0 -79
  143. data/lib/mail/core_extensions/string.rb +0 -21
  144. data/lib/mail/fields/common/address_container.rb +0 -17
  145. data/lib/mail/fields/common/common_address.rb +0 -136
  146. data/lib/mail/fields/common/common_date.rb +0 -36
  147. data/lib/mail/fields/common/common_field.rb +0 -61
  148. data/lib/mail/fields/common/common_message_id.rb +0 -49
  149. data/lib/mail/multibyte/exceptions.rb +0 -9
  150. data/lib/mail/parsers/ragel/common.rl +0 -185
  151. data/lib/mail/parsers/ragel/parser_info.rb +0 -61
  152. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
  153. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
  154. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
  155. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
  156. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
  157. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
  158. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
  159. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
  160. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
  161. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
  162. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
  163. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
  164. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
  165. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
  166. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
  167. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
  168. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
  169. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
  170. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
  171. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
  172. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
  173. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
  174. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
  175. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
  176. data/lib/mail/parsers/ragel/ruby.rb +0 -40
  177. data/lib/mail/parsers/ragel.rb +0 -18
  178. data/lib/mail/version_specific/ruby_1_8.rb +0 -126
  179. data/lib/mail/version_specific/ruby_1_9.rb +0 -223
@@ -0,0 +1,170 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+
5
+ module Mail
6
+ class AddressContainer < Array #:nodoc:
7
+ def initialize(field, list = nil)
8
+ @field = field
9
+ super list if list
10
+ end
11
+
12
+ def <<(address)
13
+ @field << address
14
+ end
15
+ end
16
+
17
+ class CommonAddressField < NamedStructuredField #:nodoc:
18
+ def self.singular?
19
+ true
20
+ end
21
+
22
+ def initialize(value = nil, charset = nil)
23
+ super encode_if_needed(value, charset), charset
24
+ end
25
+
26
+ def element # :nodoc:
27
+ @element ||= AddressList.new(value)
28
+ end
29
+
30
+ # Allows you to iterate through each address object in the address_list
31
+ def each
32
+ element.addresses.each do |address|
33
+ yield(address)
34
+ end
35
+ end
36
+
37
+ def default
38
+ addresses
39
+ end
40
+
41
+ def address
42
+ addresses.first
43
+ end
44
+
45
+ # Returns the address string of all the addresses in the address list
46
+ def addresses
47
+ list = element.addresses.map { |a| a.address }
48
+ Mail::AddressContainer.new(self, list)
49
+ end
50
+
51
+ # Returns the formatted string of all the addresses in the address list
52
+ def formatted
53
+ list = element.addresses.map { |a| a.format }
54
+ Mail::AddressContainer.new(self, list)
55
+ end
56
+
57
+ # Returns the display name of all the addresses in the address list
58
+ def display_names
59
+ list = element.addresses.map { |a| a.display_name }
60
+ Mail::AddressContainer.new(self, list)
61
+ end
62
+
63
+ # Returns the actual address objects in the address list
64
+ def addrs
65
+ list = element.addresses
66
+ Mail::AddressContainer.new(self, list)
67
+ end
68
+
69
+ # Returns a hash of group name => address strings for the address list
70
+ def groups
71
+ element.addresses_grouped_by_group
72
+ end
73
+
74
+ # Returns the addresses that are part of groups
75
+ def group_addresses
76
+ decoded_group_addresses
77
+ end
78
+
79
+ # Returns a list of decoded group addresses
80
+ def decoded_group_addresses
81
+ groups.map { |k,v| v.map { |a| a.decoded } }.flatten
82
+ end
83
+
84
+ # Returns a list of encoded group addresses
85
+ def encoded_group_addresses
86
+ groups.map { |k,v| v.map { |a| a.encoded } }.flatten
87
+ end
88
+
89
+ # Returns the name of all the groups in a string
90
+ def group_names # :nodoc:
91
+ element.group_names
92
+ end
93
+
94
+ def <<(val)
95
+ case
96
+ when val.nil?
97
+ raise ArgumentError, "Need to pass an address to <<"
98
+ when Utilities.blank?(val)
99
+ self
100
+ else
101
+ self.value = [self.value, encode_if_needed(val)].reject { |a| Utilities.blank?(a) }.join(", ")
102
+ end
103
+ end
104
+
105
+ def encode_if_needed(val, val_charset = charset) #:nodoc:
106
+ case val
107
+ when nil
108
+ val
109
+
110
+ # Need to join arrays of addresses into a single value
111
+ when Array
112
+ val.compact.map { |a| encode_if_needed a, val_charset }.join(', ')
113
+
114
+ # Pass through UTF-8; encode non-UTF-8.
115
+ else
116
+ utf8_if_needed(val, val_charset) || Encodings.encode_non_usascii(val, val_charset)
117
+ end
118
+ end
119
+
120
+ private
121
+ if 'string'.respond_to?(:encoding)
122
+ # Pass through UTF-8 addresses
123
+ def utf8_if_needed(val, val_charset)
124
+ if val_charset =~ /\AUTF-?8\z/i
125
+ val
126
+ elsif val.encoding == Encoding::UTF_8
127
+ val
128
+ elsif (utf8 = val.dup.force_encoding(Encoding::UTF_8)).valid_encoding?
129
+ utf8
130
+ end
131
+ end
132
+ else
133
+ def utf8_if_needed(val, val_charset)
134
+ if val_charset =~ /\AUTF-?8\z/i
135
+ val
136
+ end
137
+ end
138
+ end
139
+
140
+ def do_encode
141
+ return '' if Utilities.blank?(value)
142
+ address_array = element.addresses.reject { |a| encoded_group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
143
+ address_text = address_array.join(", \r\n\s")
144
+ group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.encoded }.join(", \r\n\s")};" }
145
+ group_text = group_array.join(" \r\n\s")
146
+ return_array = [address_text, group_text].reject { |a| Utilities.blank?(a) }
147
+ "#{name}: #{return_array.join(", \r\n\s")}\r\n"
148
+ end
149
+
150
+ def do_decode
151
+ return nil if Utilities.blank?(value)
152
+ address_array = element.addresses.reject { |a| decoded_group_addresses.include?(a.decoded) }.map { |a| a.decoded }
153
+ address_text = address_array.join(", ")
154
+ group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.decoded }.join(", ")};" }
155
+ group_text = group_array.join(" ")
156
+ return_array = [address_text, group_text].reject { |a| Utilities.blank?(a) }
157
+ return_array.join(", ")
158
+ end
159
+
160
+ def get_group_addresses(group_list)
161
+ if group_list.respond_to?(:addresses)
162
+ group_list.addresses.map do |address|
163
+ Mail::Address.new(address)
164
+ end
165
+ else
166
+ []
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,58 @@
1
+ require 'mail/fields/named_structured_field'
2
+ require 'mail/elements/date_time_element'
3
+ require 'mail/utilities'
4
+
5
+ module Mail
6
+ class CommonDateField < NamedStructuredField #:nodoc:
7
+ def self.singular?
8
+ true
9
+ end
10
+
11
+ def self.normalize_datetime(string)
12
+ if Utilities.blank?(string)
13
+ datetime = ::DateTime.now
14
+ else
15
+ stripped = string.to_s.gsub(/\(.*?\)/, '').squeeze(' ')
16
+ begin
17
+ datetime = ::DateTime.parse(stripped)
18
+ rescue ArgumentError => e
19
+ raise unless 'invalid date' == e.message
20
+ end
21
+ end
22
+
23
+ if datetime
24
+ datetime.strftime('%a, %d %b %Y %H:%M:%S %z')
25
+ else
26
+ string
27
+ end
28
+ end
29
+
30
+ def initialize(value = nil, charset = nil)
31
+ super self.class.normalize_datetime(value), charset
32
+ end
33
+
34
+ # Returns a date time object of the parsed date
35
+ def date_time
36
+ ::DateTime.parse("#{element.date_string} #{element.time_string}")
37
+ rescue ArgumentError => e
38
+ raise e unless e.message == 'invalid date'
39
+ end
40
+
41
+ def default
42
+ date_time
43
+ end
44
+
45
+ def element
46
+ @element ||= Mail::DateTimeElement.new(value)
47
+ end
48
+
49
+ private
50
+ def do_encode
51
+ "#{name}: #{value}\r\n"
52
+ end
53
+
54
+ def do_decode
55
+ value.to_s
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/constants'
4
+
5
+ module Mail
6
+ class CommonField #:nodoc:
7
+ def self.singular?
8
+ false
9
+ end
10
+
11
+ def self.parse(*args)
12
+ new(*args).tap(&:parse)
13
+ end
14
+
15
+ attr_accessor :name
16
+ attr_reader :value
17
+ attr_accessor :charset
18
+ attr_reader :errors
19
+
20
+ def initialize(name = nil, value = nil, charset = nil)
21
+ @errors = []
22
+
23
+ self.name = name
24
+ self.value = value
25
+ self.charset = charset || 'utf-8'
26
+ end
27
+
28
+ def singular?
29
+ self.class.singular?
30
+ end
31
+
32
+ def value=(value)
33
+ @element = nil
34
+ @value = value.is_a?(Array) ? value : value.to_s
35
+ parse
36
+ end
37
+
38
+ def parse
39
+ tap(&:element)
40
+ end
41
+
42
+ def element
43
+ nil
44
+ end
45
+
46
+ def to_s
47
+ decoded.to_s
48
+ end
49
+
50
+ def default
51
+ decoded
52
+ end
53
+
54
+ def decoded
55
+ do_decode
56
+ end
57
+
58
+ def encoded
59
+ do_encode
60
+ end
61
+
62
+ def responsible_for?(field_name)
63
+ name.to_s.casecmp(field_name.to_s) == 0
64
+ end
65
+
66
+ private
67
+
68
+ FILENAME_RE = /\b(filename|name)=([^;"\r\n]+\s[^;"\r\n]+)/
69
+ def ensure_filename_quoted(value)
70
+ if value.is_a?(String)
71
+ value.sub FILENAME_RE, '\1="\2"'
72
+ else
73
+ value
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/utilities'
5
+
6
+ module Mail
7
+ class CommonMessageIdField < NamedStructuredField #:nodoc:
8
+ def element
9
+ @element ||= Mail::MessageIdsElement.new(value)
10
+ end
11
+
12
+ def message_id
13
+ element.message_id
14
+ end
15
+
16
+ def message_ids
17
+ element.message_ids
18
+ end
19
+
20
+ def default
21
+ ids = message_ids
22
+ ids.one? ? ids.first : ids
23
+ end
24
+
25
+ def to_s
26
+ decoded.to_s
27
+ end
28
+
29
+ private
30
+ def do_encode
31
+ %Q{#{name}: #{formatted_message_ids("\r\n ")}\r\n}
32
+ end
33
+
34
+ def do_decode
35
+ formatted_message_ids
36
+ end
37
+
38
+ def formatted_message_ids(join = ' ')
39
+ message_ids.map { |m| "<#{m}>" }.join(join) if message_ids.any?
40
+ end
41
+ end
42
+ end
@@ -1,20 +1,13 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- #
5
- #
3
+ require 'mail/fields/named_unstructured_field'
4
+
6
5
  module Mail
7
- class ContentDescriptionField < UnstructuredField
8
-
9
- FIELD_NAME = 'content-description'
10
- CAPITALIZED_FIELD = 'Content-Description'
11
-
12
- def initialize(value = nil, charset = 'utf-8')
13
- self.charset = charset
14
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
15
- self.parse
16
- self
6
+ class ContentDescriptionField < NamedUnstructuredField #:nodoc:
7
+ NAME = 'Content-Description'
8
+
9
+ def self.singular?
10
+ true
17
11
  end
18
-
19
12
  end
20
13
  end
@@ -1,25 +1,18 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common/parameter_hash'
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/fields/parameter_hash'
4
5
 
5
6
  module Mail
6
- class ContentDispositionField < StructuredField
7
+ class ContentDispositionField < NamedStructuredField #:nodoc:
8
+ NAME = 'Content-Disposition'
7
9
 
8
- FIELD_NAME = 'content-disposition'
9
- CAPITALIZED_FIELD = 'Content-Disposition'
10
-
11
- def initialize(value = nil, charset = 'utf-8')
12
- self.charset = charset
13
- value = ensure_filename_quoted(value)
14
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
15
- self.parse
16
- self
10
+ def self.singular?
11
+ true
17
12
  end
18
13
 
19
- def parse(val = value)
20
- unless Utilities.blank?(val)
21
- @element = Mail::ContentDispositionElement.new(val)
22
- end
14
+ def initialize(value = nil, charset = nil)
15
+ super ensure_filename_quoted(value), charset
23
16
  end
24
17
 
25
18
  def element
@@ -37,35 +30,17 @@ module Mail
37
30
  end
38
31
 
39
32
  def filename
40
- case
41
- when !Utilities.blank?(parameters['filename'])
42
- @filename = parameters['filename']
43
- when !Utilities.blank?(parameters['name'])
44
- @filename = parameters['name']
45
- else
46
- @filename = nil
47
- end
48
- @filename
33
+ @filename ||= parameters['filename'] || parameters['name']
49
34
  end
50
35
 
51
- # TODO: Fix this up
52
36
  def encoded
53
- if parameters.length > 0
54
- p = ";\r\n\s#{parameters.encoded}\r\n"
55
- else
56
- p = "\r\n"
57
- end
58
- "#{CAPITALIZED_FIELD}: #{disposition_type}" + p
37
+ p = ";\r\n\s#{parameters.encoded}" if parameters.length > 0
38
+ "#{name}: #{disposition_type}#{p}\r\n"
59
39
  end
60
40
 
61
41
  def decoded
62
- if parameters.length > 0
63
- p = "; #{parameters.decoded}"
64
- else
65
- p = ""
66
- end
67
- "#{disposition_type}" + p
42
+ p = "; #{parameters.decoded}" if parameters.length > 0
43
+ "#{disposition_type}#{p}"
68
44
  end
69
-
70
45
  end
71
46
  end
@@ -1,63 +1,36 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- #
5
- #
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/utilities'
5
+
6
6
  module Mail
7
- class ContentIdField < StructuredField
8
-
9
- FIELD_NAME = 'content-id'
10
- CAPITALIZED_FIELD = "Content-ID"
11
-
12
- def initialize(value = nil, charset = 'utf-8')
13
- self.charset = charset
14
- @uniq = 1
15
- if Utilities.blank?(value)
16
- value = generate_content_id
17
- else
18
- value = strip_field(FIELD_NAME, value)
19
- end
20
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
21
- self.parse
22
- self
23
- end
24
-
25
- def parse(val = value)
26
- unless Utilities.blank?(val)
27
- @element = Mail::MessageIdsElement.new(val)
28
- end
29
- end
30
-
7
+ class ContentIdField < NamedStructuredField #:nodoc:
8
+ NAME = 'Content-ID'
9
+
10
+ def self.singular?
11
+ true
12
+ end
13
+
14
+ def initialize(value = nil, charset = nil)
15
+ value = Mail::Utilities.generate_message_id if Utilities.blank?(value)
16
+ super value, charset
17
+ end
18
+
31
19
  def element
32
20
  @element ||= Mail::MessageIdsElement.new(value)
33
21
  end
34
-
35
- def name
36
- 'Content-ID'
37
- end
38
-
22
+
39
23
  def content_id
40
24
  element.message_id
41
25
  end
42
-
43
- def to_s
44
- "<#{content_id}>"
45
- end
46
-
47
- # TODO: Fix this up
48
- def encoded
49
- "#{CAPITALIZED_FIELD}: #{to_s}\r\n"
50
- end
51
-
52
- def decoded
53
- "#{to_s}"
54
- end
55
-
26
+
56
27
  private
57
-
58
- def generate_content_id
59
- "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
60
- end
61
-
28
+ def do_decode
29
+ "<#{content_id}>"
30
+ end
31
+
32
+ def do_encode
33
+ "#{name}: #{do_decode}\r\n"
34
+ end
62
35
  end
63
36
  end
@@ -1,27 +1,15 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- #
5
- #
3
+ require 'mail/fields/named_structured_field'
4
+
6
5
  module Mail
7
- class ContentLocationField < StructuredField
8
-
9
- FIELD_NAME = 'content-location'
10
- CAPITALIZED_FIELD = 'Content-Location'
11
-
12
- def initialize(value = nil, charset = 'utf-8')
13
- self.charset = charset
14
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
15
- self.parse
16
- self
17
- end
18
-
19
- def parse(val = value)
20
- unless Utilities.blank?(val)
21
- @element = Mail::ContentLocationElement.new(val)
22
- end
6
+ class ContentLocationField < NamedStructuredField #:nodoc:
7
+ NAME = 'Content-Location'
8
+
9
+ def self.singular?
10
+ true
23
11
  end
24
-
12
+
25
13
  def element
26
14
  @element ||= Mail::ContentLocationElement.new(value)
27
15
  end
@@ -30,14 +18,12 @@ module Mail
30
18
  element.location
31
19
  end
32
20
 
33
- # TODO: Fix this up
34
21
  def encoded
35
- "#{CAPITALIZED_FIELD}: #{location}\r\n"
22
+ "#{name}: #{location}\r\n"
36
23
  end
37
-
24
+
38
25
  def decoded
39
- location
26
+ location
40
27
  end
41
-
42
28
  end
43
29
  end
@@ -1,45 +1,45 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- #
5
- #
3
+ require 'mail/fields/named_structured_field'
4
+
6
5
  module Mail
7
- class ContentTransferEncodingField < StructuredField
8
-
9
- FIELD_NAME = 'content-transfer-encoding'
10
- CAPITALIZED_FIELD = 'Content-Transfer-Encoding'
11
-
12
- def initialize(value = nil, charset = 'utf-8')
13
- self.charset = charset
14
- value = '7bit' if value.to_s =~ /7-?bits?/i
15
- value = '8bit' if value.to_s =~ /8-?bits?/i
16
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
17
- self.parse
18
- self
6
+ class ContentTransferEncodingField < NamedStructuredField #:nodoc:
7
+ NAME = 'Content-Transfer-Encoding'
8
+
9
+ def self.singular?
10
+ true
19
11
  end
20
-
21
- def parse(val = value)
22
- unless Utilities.blank?(val)
23
- @element = Mail::ContentTransferEncodingElement.new(val)
12
+
13
+ def self.normalize_content_transfer_encoding(value)
14
+ case value
15
+ when /7-?bits?/i
16
+ '7bit'
17
+ when /8-?bits?/i
18
+ '8bit'
19
+ else
20
+ value
24
21
  end
25
22
  end
26
-
23
+
24
+ def initialize(value = nil, charset = nil)
25
+ super self.class.normalize_content_transfer_encoding(value), charset
26
+ end
27
+
27
28
  def element
28
29
  @element ||= Mail::ContentTransferEncodingElement.new(value)
29
30
  end
30
-
31
+
31
32
  def encoding
32
33
  element.encoding
33
34
  end
34
-
35
- # TODO: Fix this up
36
- def encoded
37
- "#{CAPITALIZED_FIELD}: #{encoding}\r\n"
38
- end
39
-
40
- def decoded
41
- encoding
42
- end
43
-
35
+
36
+ private
37
+ def do_encode
38
+ "#{name}: #{encoding}\r\n"
39
+ end
40
+
41
+ def do_decode
42
+ encoding
43
+ end
44
44
  end
45
45
  end