mail 2.6.4 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,27 +1,20 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/content_disposition_parser'
4
+
3
5
  module Mail
4
- class ContentDispositionElement # :nodoc:
5
-
6
- include Mail::Utilities
7
-
8
- def initialize( string )
9
- content_disposition = Mail::Parsers::ContentDispositionParser.new.parse(cleaned(string))
6
+ class ContentDispositionElement #:nodoc:
7
+ attr_reader :disposition_type, :parameters
8
+
9
+ def initialize(string)
10
+ content_disposition = Mail::Parsers::ContentDispositionParser.parse(cleaned(string))
10
11
  @disposition_type = content_disposition.disposition_type
11
12
  @parameters = content_disposition.parameters
12
13
  end
13
-
14
- def disposition_type
15
- @disposition_type
16
- end
17
-
18
- def parameters
19
- @parameters
20
- end
21
-
14
+
15
+ private
22
16
  def cleaned(string)
23
17
  string =~ /(.+);\s*$/ ? $1 : string
24
18
  end
25
-
26
19
  end
27
20
  end
@@ -1,22 +1,17 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- module Mail
4
- class ContentLocationElement # :nodoc:
5
-
6
- include Mail::Utilities
3
+ require 'mail/parsers/content_location_parser'
7
4
 
8
- def initialize( string )
9
- content_location = Mail::Parsers::ContentLocationParser.new.parse(string)
10
- @location = content_location.location
11
- end
5
+ module Mail
6
+ class ContentLocationElement #:nodoc:
7
+ attr_reader :location
12
8
 
13
- def location
14
- @location
9
+ def initialize(string)
10
+ @location = Mail::Parsers::ContentLocationParser.parse(string).location
15
11
  end
16
12
 
17
13
  def to_s(*args)
18
14
  location.to_s
19
15
  end
20
-
21
16
  end
22
17
  end
@@ -1,18 +1,13 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/content_transfer_encoding_parser'
4
+
3
5
  module Mail
4
- class ContentTransferEncodingElement
5
-
6
- include Mail::Utilities
7
-
6
+ class ContentTransferEncodingElement #:nodoc:
7
+ attr_reader :encoding
8
+
8
9
  def initialize(string)
9
- content_transfer_encoding = Mail::Parsers::ContentTransferEncodingParser.new.parse(string)
10
- @encoding = content_transfer_encoding.encoding
10
+ @encoding = Mail::Parsers::ContentTransferEncodingParser.parse(string).encoding
11
11
  end
12
-
13
- def encoding
14
- @encoding
15
- end
16
-
17
12
  end
18
13
  end
@@ -1,32 +1,25 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/content_type_parser'
4
+
3
5
  module Mail
4
- class ContentTypeElement # :nodoc:
5
-
6
- include Mail::Utilities
7
-
8
- def initialize( string )
9
- content_type = Mail::Parsers::ContentTypeParser.new.parse(cleaned(string))
6
+ class ContentTypeElement #:nodoc:
7
+ attr_reader :main_type, :sub_type, :parameters
8
+
9
+ def initialize(string)
10
+ content_type = Mail::Parsers::ContentTypeParser.parse(cleaned(string))
10
11
  @main_type = content_type.main_type
11
12
  @sub_type = content_type.sub_type
12
13
  @parameters = content_type.parameters
13
14
  end
14
-
15
- def main_type
16
- @main_type
17
- end
18
-
19
- def sub_type
20
- @sub_type
21
- end
22
-
23
- def parameters
24
- @parameters
25
- end
26
-
27
- def cleaned(string)
28
- string =~ /(.+);\s*$/ ? $1 : string
29
- end
30
-
15
+
16
+ private
17
+ def cleaned(string)
18
+ if string =~ /;\s*$/
19
+ $`
20
+ else
21
+ string
22
+ end
23
+ end
31
24
  end
32
25
  end
@@ -1,23 +1,15 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/date_time_parser'
4
+
3
5
  module Mail
4
- class DateTimeElement # :nodoc:
5
-
6
- include Mail::Utilities
7
-
8
- def initialize( string )
9
- date_time = Mail::Parsers::DateTimeParser.new.parse(string)
6
+ class DateTimeElement #:nodoc:
7
+ attr_reader :date_string, :time_string
8
+
9
+ def initialize(string)
10
+ date_time = Mail::Parsers::DateTimeParser.parse(string)
10
11
  @date_string = date_time.date_string
11
12
  @time_string = date_time.time_string
12
13
  end
13
-
14
- def date_string
15
- @date_string
16
- end
17
-
18
- def time_string
19
- @time_string
20
- end
21
-
22
14
  end
23
15
  end
@@ -1,40 +1,39 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/envelope_from_parser'
4
+ require 'date'
5
+
3
6
  module Mail
4
- class EnvelopeFromElement
5
-
6
- include Mail::Utilities
7
-
8
- def initialize( string )
9
- @envelope_from = Mail::Parsers::EnvelopeFromParser.new.parse(string)
10
- @address = @envelope_from.address
11
- @date_time = ::DateTime.parse(@envelope_from.ctime_date)
12
- end
13
-
14
- def date_time
15
- @date_time
16
- end
17
-
18
- def address
19
- @address
7
+ class EnvelopeFromElement #:nodoc:
8
+ attr_reader :date_time, :address
9
+
10
+ def initialize(string)
11
+ envelope_from = Mail::Parsers::EnvelopeFromParser.parse(string)
12
+ @address = envelope_from.address
13
+ @date_time = ::DateTime.parse(envelope_from.ctime_date) if envelope_from.ctime_date
20
14
  end
21
-
15
+
22
16
  # RFC 4155:
23
17
  # a timestamp indicating the UTC date and time when the message
24
18
  # was originally received, conformant with the syntax of the
25
19
  # traditional UNIX 'ctime' output sans timezone (note that the
26
20
  # use of UTC precludes the need for a timezone indicator);
27
21
  def formatted_date_time
28
- if @date_time.respond_to?(:ctime)
29
- @date_time.ctime
30
- else
31
- @date_time.strftime '%a %b %e %T %Y'
22
+ if date_time
23
+ if date_time.respond_to?(:ctime)
24
+ date_time.ctime
25
+ else
26
+ date_time.strftime '%a %b %e %T %Y'
27
+ end
32
28
  end
33
29
  end
34
30
 
35
31
  def to_s
36
- "#{@address} #{formatted_date_time}"
32
+ if date_time
33
+ "#{address} #{formatted_date_time}"
34
+ else
35
+ address
36
+ end
37
37
  end
38
-
39
38
  end
40
39
  end
@@ -1,26 +1,31 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/message_ids_parser'
4
+ require 'mail/utilities'
5
+
3
6
  module Mail
4
- class MessageIdsElement
7
+ class MessageIdsElement #:nodoc:
8
+ def self.parse(string)
9
+ new(string).tap(&:message_ids)
10
+ end
5
11
 
6
- include Mail::Utilities
12
+ attr_reader :message_ids
7
13
 
8
14
  def initialize(string)
9
- raise Mail::Field::ParseError.new(Mail::MessageIdsElement, string, 'nil is invalid') if string.nil?
10
- @message_ids = Mail::Parsers::MessageIdsParser.new.parse(string).message_ids.map { |msg_id| clean_msg_id(msg_id) }
11
- end
12
-
13
- def message_ids
14
- @message_ids
15
+ @message_ids = parse(string)
15
16
  end
16
17
 
17
18
  def message_id
18
- @message_ids.first
19
- end
20
-
21
- def clean_msg_id( val )
22
- val =~ /.*<(.*)>.*/ ; $1
19
+ message_ids.first
23
20
  end
24
21
 
22
+ private
23
+ def parse(string)
24
+ if Utilities.blank? string
25
+ []
26
+ else
27
+ Mail::Parsers::MessageIdsParser.parse(string).message_ids
28
+ end
29
+ end
25
30
  end
26
31
  end
@@ -1,23 +1,15 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/mime_version_parser'
4
+
3
5
  module Mail
4
- class MimeVersionElement
5
-
6
- include Mail::Utilities
7
-
8
- def initialize( string )
9
- mime_version = Mail::Parsers::MimeVersionParser.new.parse(string)
6
+ class MimeVersionElement #:nodoc:
7
+ attr_reader :major, :minor
8
+
9
+ def initialize(string)
10
+ mime_version = Mail::Parsers::MimeVersionParser.parse(string)
10
11
  @major = mime_version.major
11
12
  @minor = mime_version.minor
12
13
  end
13
-
14
- def major
15
- @major
16
- end
17
-
18
- def minor
19
- @minor
20
- end
21
-
22
14
  end
23
15
  end
@@ -1,17 +1,19 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/phrase_lists_parser'
4
+ require 'mail/utilities'
5
+
3
6
  module Mail
4
- class PhraseList
5
-
6
- include Mail::Utilities
7
-
7
+ class PhraseList #:nodoc:
8
+ attr_reader :phrases
9
+
8
10
  def initialize(string)
9
- @phrase_lists = Mail::Parsers::PhraseListsParser.new.parse(string)
11
+ @phrases =
12
+ if Utilities.blank? string
13
+ []
14
+ else
15
+ Mail::Parsers::PhraseListsParser.parse(string).phrases.map { |p| Mail::Utilities.unquote(p) }
16
+ end
10
17
  end
11
-
12
- def phrases
13
- @phrase_lists.phrases.map { |p| unquote(p) }
14
- end
15
-
16
18
  end
17
19
  end
@@ -1,27 +1,35 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+ require 'mail/parsers/received_parser'
4
+ require 'mail/utilities'
5
+ require 'date'
6
+
3
7
  module Mail
4
- class ReceivedElement
5
-
6
- include Mail::Utilities
7
-
8
- def initialize( string )
9
- received = Mail::Parsers::ReceivedParser.new.parse(string)
10
- @date_time = ::DateTime.parse("#{received.date} #{received.time}")
11
- @info = received.info
8
+ class ReceivedElement #:nodoc:
9
+ attr_reader :info, :date_time
10
+
11
+ def initialize(string)
12
+ if Utilities.blank? string
13
+ @date_time = nil
14
+ @info = nil
15
+ else
16
+ received = Mail::Parsers::ReceivedParser.parse(string)
17
+ @date_time = datetime_for(received)
18
+ @info = received.info
19
+ end
12
20
  end
13
-
14
- def date_time
15
- @date_time
16
- end
17
-
18
- def info
19
- @info
20
- end
21
-
21
+
22
22
  def to_s(*args)
23
- "#{@info}; #{@date_time.to_s(*args)}"
23
+ "#{info}; #{date_time.to_s(*args)}"
24
24
  end
25
-
25
+
26
+ private
27
+ def datetime_for(received)
28
+ ::DateTime.parse("#{received.date} #{received.time}")
29
+ rescue ArgumentError => e
30
+ raise e unless e.message == 'invalid date'
31
+ warn "WARNING: Invalid date field for received element (#{received.date} #{received.time}): #{e.class}: #{e.message}"
32
+ nil
33
+ end
26
34
  end
27
35
  end
@@ -4,29 +4,24 @@ require 'mail/encodings/8bit'
4
4
 
5
5
  module Mail
6
6
  module Encodings
7
+ # 7bit and 8bit are equivalent. 7bit encoding is for text only.
7
8
  class SevenBit < EightBit
8
9
  NAME = '7bit'
9
-
10
10
  PRIORITY = 1
11
+ Encodings.register(NAME, self)
11
12
 
12
- # 7bit and 8bit operate the same
13
-
14
- # Decode the string
15
13
  def self.decode(str)
16
- super
14
+ ::Mail::Utilities.binary_unsafe_to_lf str
17
15
  end
18
-
19
- # Encode the string
16
+
20
17
  def self.encode(str)
21
- super
22
- end
23
-
24
- # Idenity encodings have a fixed cost, 1 byte out per 1 byte in
25
- def self.cost(str)
26
- super
18
+ ::Mail::Utilities.binary_unsafe_to_crlf str
27
19
  end
28
20
 
29
- Encodings.register(NAME, self)
21
+ # Per RFC 2045 2.7. 7bit Data, No octets with decimal values greater than 127 are allowed.
22
+ def self.compatible_input?(str)
23
+ str.ascii_only? && super
24
+ end
30
25
  end
31
26
  end
32
27
  end
@@ -6,32 +6,13 @@ module Mail
6
6
  module Encodings
7
7
  class EightBit < Binary
8
8
  NAME = '8bit'
9
-
10
9
  PRIORITY = 4
11
-
12
- # 8bit is an identiy encoding, meaning nothing to do
13
-
14
- # Decode the string
15
- def self.decode(str)
16
- ::Mail::Utilities.to_lf str
17
- end
18
-
19
- # Encode the string
20
- def self.encode(str)
21
- ::Mail::Utilities.to_crlf str
22
- end
23
-
24
- # Idenity encodings have a fixed cost, 1 byte out per 1 byte in
25
- def self.cost(str)
26
- 1.0
27
- end
10
+ Encodings.register(NAME, self)
28
11
 
29
12
  # Per RFC 2821 4.5.3.1, SMTP lines may not be longer than 1000 octets including the <CRLF>.
30
13
  def self.compatible_input?(str)
31
- !str.lines.find { |line| line.length > 998 }
14
+ !str.lines.find { |line| line.bytesize > 998 }
32
15
  end
33
-
34
- Encodings.register(NAME, self)
35
16
  end
36
17
  end
37
18
  end
@@ -4,36 +4,35 @@ require 'mail/encodings/7bit'
4
4
 
5
5
  module Mail
6
6
  module Encodings
7
+ # Base64 encoding handles binary content at the cost of 4 output bytes
8
+ # per input byte.
7
9
  class Base64 < SevenBit
8
10
  NAME = 'base64'
9
-
10
11
  PRIORITY = 3
11
-
12
+ Encodings.register(NAME, self)
13
+
12
14
  def self.can_encode?(enc)
13
15
  true
14
16
  end
15
17
 
16
- # Decode the string from Base64
17
18
  def self.decode(str)
18
- RubyVer.decode_base64( str )
19
+ Utilities.decode_base64(str)
19
20
  end
20
-
21
- # Encode the string to Base64
21
+
22
22
  def self.encode(str)
23
- ::Mail::Utilities.to_crlf(RubyVer.encode_base64( str ))
23
+ ::Mail::Utilities.binary_unsafe_to_crlf(Utilities.encode_base64(str))
24
24
  end
25
25
 
26
- # Base64 has a fixed cost, 4 bytes out per 3 bytes in
26
+ # 3 bytes in -> 4 bytes out
27
27
  def self.cost(str)
28
- 4.0/3
28
+ 4.0 / 3
29
29
  end
30
30
 
31
- # Base64 inserts newlines automatically and cannot violate the SMTP spec.
31
+ # Ruby Base64 inserts newlines automatically, so it doesn't exceed
32
+ # SMTP line length limits.
32
33
  def self.compatible_input?(str)
33
34
  true
34
35
  end
35
-
36
- Encodings.register(NAME, self)
37
36
  end
38
37
  end
39
38
  end
@@ -1,32 +1,13 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/encodings/transfer_encoding'
3
+ require 'mail/encodings/identity'
4
4
 
5
5
  module Mail
6
6
  module Encodings
7
- class Binary < TransferEncoding
7
+ class Binary < Identity
8
8
  NAME = 'binary'
9
-
10
9
  PRIORITY = 5
11
-
12
- # Binary is an identiy encoding, meaning nothing to do
13
-
14
- # Decode the string
15
- def self.decode(str)
16
- str
17
- end
18
-
19
- # Encode the string
20
- def self.encode(str)
21
- str
22
- end
23
-
24
- # Idenity encodings have a fixed cost, 1 byte out per 1 byte in
25
- def self.cost(str)
26
- 1.0
27
- end
28
-
29
- Encodings.register(NAME, self)
10
+ Encodings.register(NAME, self)
30
11
  end
31
12
  end
32
13
  end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/encodings/transfer_encoding'
4
+
5
+ module Mail
6
+ module Encodings
7
+ # Identity encodings do no encoding/decoding and have a fixed cost:
8
+ # 1 byte in -> 1 byte out.
9
+ class Identity < TransferEncoding #:nodoc:
10
+ def self.decode(str)
11
+ str
12
+ end
13
+
14
+ def self.encode(str)
15
+ str
16
+ end
17
+
18
+ # 1 output byte per input byte.
19
+ def self.cost(str)
20
+ 1.0
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,27 +6,27 @@ module Mail
6
6
  module Encodings
7
7
  class QuotedPrintable < SevenBit
8
8
  NAME='quoted-printable'
9
-
9
+
10
10
  PRIORITY = 2
11
11
 
12
- def self.can_encode?(str)
13
- EightBit.can_encode? str
12
+ def self.can_encode?(enc)
13
+ EightBit.can_encode? enc
14
14
  end
15
15
 
16
16
  # Decode the string from Quoted-Printable. Cope with hard line breaks
17
17
  # that were incorrectly encoded as hex instead of literal CRLF.
18
18
  def self.decode(str)
19
- ::Mail::Utilities.to_lf str.gsub(/(?:=0D=0A|=0D|=0A)\r\n/, "\r\n").unpack("M*").first
19
+ ::Mail::Utilities.to_lf ::Mail::Utilities.to_crlf(str).gsub(/(?:=0D=0A|=0D|=0A)\r\n/, "\r\n").unpack("M*").first
20
20
  end
21
21
 
22
22
  def self.encode(str)
23
- ::Mail::Utilities.to_crlf([::Mail::Utilities.to_lf(str)].pack("M"))
23
+ ::Mail::Utilities.to_crlf [::Mail::Utilities.to_lf(str)].pack("M")
24
24
  end
25
25
 
26
26
  def self.cost(str)
27
27
  # These bytes probably do not need encoding
28
28
  c = str.count("\x9\xA\xD\x20-\x3C\x3E-\x7E")
29
- # Everything else turns into =XX where XX is a
29
+ # Everything else turns into =XX where XX is a
30
30
  # two digit hex number (taking 3 bytes)
31
31
  total = (str.bytesize - c)*3 + c
32
32
  total.to_f/str.bytesize