mail 2.7.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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +59 -28
  3. data/lib/mail/attachments_list.rb +2 -5
  4. data/lib/mail/body.rb +24 -47
  5. data/lib/mail/check_delivery_params.rb +21 -16
  6. data/lib/mail/constants.rb +27 -5
  7. data/lib/mail/elements/address.rb +27 -27
  8. data/lib/mail/elements/address_list.rb +1 -1
  9. data/lib/mail/elements/content_disposition_element.rb +1 -1
  10. data/lib/mail/elements/content_location_element.rb +1 -1
  11. data/lib/mail/elements/content_transfer_encoding_element.rb +1 -1
  12. data/lib/mail/elements/content_type_element.rb +8 -4
  13. data/lib/mail/elements/date_time_element.rb +1 -1
  14. data/lib/mail/elements/envelope_from_element.rb +13 -7
  15. data/lib/mail/elements/message_ids_element.rb +14 -5
  16. data/lib/mail/elements/mime_version_element.rb +1 -1
  17. data/lib/mail/elements/phrase_list.rb +7 -2
  18. data/lib/mail/elements/received_element.rb +20 -6
  19. data/lib/mail/encodings/7bit.rb +5 -0
  20. data/lib/mail/encodings/base64.rb +2 -2
  21. data/lib/mail/encodings/quoted_printable.rb +2 -2
  22. data/lib/mail/encodings.rb +30 -59
  23. data/lib/mail/envelope.rb +11 -14
  24. data/lib/mail/field.rb +37 -53
  25. data/lib/mail/field_list.rb +60 -7
  26. data/lib/mail/fields/bcc_field.rb +34 -52
  27. data/lib/mail/fields/cc_field.rb +28 -49
  28. data/lib/mail/fields/comments_field.rb +27 -37
  29. data/lib/mail/fields/common_address_field.rb +170 -0
  30. data/lib/mail/fields/common_date_field.rb +58 -0
  31. data/lib/mail/fields/common_field.rb +77 -0
  32. data/lib/mail/fields/common_message_id_field.rb +42 -0
  33. data/lib/mail/fields/content_description_field.rb +7 -14
  34. data/lib/mail/fields/content_disposition_field.rb +13 -38
  35. data/lib/mail/fields/content_id_field.rb +24 -51
  36. data/lib/mail/fields/content_location_field.rb +11 -25
  37. data/lib/mail/fields/content_transfer_encoding_field.rb +31 -31
  38. data/lib/mail/fields/content_type_field.rb +46 -71
  39. data/lib/mail/fields/date_field.rb +23 -51
  40. data/lib/mail/fields/from_field.rb +28 -49
  41. data/lib/mail/fields/in_reply_to_field.rb +38 -49
  42. data/lib/mail/fields/keywords_field.rb +18 -31
  43. data/lib/mail/fields/message_id_field.rb +25 -71
  44. data/lib/mail/fields/mime_version_field.rb +19 -30
  45. data/lib/mail/fields/named_structured_field.rb +11 -0
  46. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  47. data/lib/mail/fields/optional_field.rb +5 -6
  48. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +12 -10
  49. data/lib/mail/fields/received_field.rb +43 -57
  50. data/lib/mail/fields/references_field.rb +35 -49
  51. data/lib/mail/fields/reply_to_field.rb +28 -49
  52. data/lib/mail/fields/resent_bcc_field.rb +28 -49
  53. data/lib/mail/fields/resent_cc_field.rb +28 -49
  54. data/lib/mail/fields/resent_date_field.rb +5 -29
  55. data/lib/mail/fields/resent_from_field.rb +28 -49
  56. data/lib/mail/fields/resent_message_id_field.rb +5 -29
  57. data/lib/mail/fields/resent_sender_field.rb +27 -56
  58. data/lib/mail/fields/resent_to_field.rb +28 -49
  59. data/lib/mail/fields/return_path_field.rb +50 -54
  60. data/lib/mail/fields/sender_field.rb +34 -55
  61. data/lib/mail/fields/structured_field.rb +3 -30
  62. data/lib/mail/fields/subject_field.rb +9 -11
  63. data/lib/mail/fields/to_field.rb +28 -49
  64. data/lib/mail/fields/unstructured_field.rb +16 -48
  65. data/lib/mail/header.rb +69 -110
  66. data/lib/mail/matchers/attachment_matchers.rb +15 -0
  67. data/lib/mail/message.rb +52 -66
  68. data/lib/mail/multibyte/chars.rb +8 -166
  69. data/lib/mail/multibyte/utils.rb +26 -43
  70. data/lib/mail/multibyte.rb +1 -11
  71. data/lib/mail/network/delivery_methods/exim.rb +5 -4
  72. data/lib/mail/network/delivery_methods/file_delivery.rb +11 -10
  73. data/lib/mail/network/delivery_methods/logger_delivery.rb +2 -5
  74. data/lib/mail/network/delivery_methods/sendmail.rb +56 -18
  75. data/lib/mail/network/delivery_methods/smtp.rb +25 -9
  76. data/lib/mail/network/delivery_methods/smtp_connection.rb +3 -12
  77. data/lib/mail/network/delivery_methods/test_mailer.rb +4 -2
  78. data/lib/mail/network/retriever_methods/base.rb +8 -8
  79. data/lib/mail/network/retriever_methods/imap.rb +2 -2
  80. data/lib/mail/network/retriever_methods/pop3.rb +2 -2
  81. data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
  82. data/lib/mail/parsers/address_lists_parser.rb +33070 -33064
  83. data/lib/mail/parsers/address_lists_parser.rl +7 -0
  84. data/lib/mail/parsers/content_disposition_parser.rb +833 -827
  85. data/lib/mail/parsers/content_disposition_parser.rl +7 -0
  86. data/lib/mail/parsers/content_location_parser.rb +770 -764
  87. data/lib/mail/parsers/content_location_parser.rl +7 -0
  88. data/lib/mail/parsers/content_transfer_encoding_parser.rb +474 -468
  89. data/lib/mail/parsers/content_transfer_encoding_parser.rl +7 -0
  90. data/lib/mail/parsers/content_type_parser.rb +971 -965
  91. data/lib/mail/parsers/content_type_parser.rl +7 -0
  92. data/lib/mail/parsers/date_time_parser.rb +838 -832
  93. data/lib/mail/parsers/date_time_parser.rl +7 -0
  94. data/lib/mail/parsers/envelope_from_parser.rb +3623 -3529
  95. data/lib/mail/parsers/envelope_from_parser.rl +7 -0
  96. data/lib/mail/parsers/message_ids_parser.rb +5107 -2800
  97. data/lib/mail/parsers/message_ids_parser.rl +12 -1
  98. data/lib/mail/parsers/mime_version_parser.rb +463 -457
  99. data/lib/mail/parsers/mime_version_parser.rl +7 -0
  100. data/lib/mail/parsers/phrase_lists_parser.rb +836 -830
  101. data/lib/mail/parsers/phrase_lists_parser.rl +8 -1
  102. data/lib/mail/parsers/received_parser.rb +8688 -8682
  103. data/lib/mail/parsers/received_parser.rl +7 -0
  104. data/lib/mail/parsers/rfc5322.rl +28 -13
  105. data/lib/mail/parsers.rb +11 -17
  106. data/lib/mail/part.rb +5 -9
  107. data/lib/mail/parts_list.rb +57 -0
  108. data/lib/mail/smtp_envelope.rb +57 -0
  109. data/lib/mail/utilities.rb +307 -69
  110. data/lib/mail/version.rb +1 -1
  111. data/lib/mail/yaml.rb +30 -0
  112. data/lib/mail.rb +3 -20
  113. metadata +72 -18
  114. data/lib/mail/core_extensions/smtp.rb +0 -28
  115. data/lib/mail/core_extensions/string.rb +0 -17
  116. data/lib/mail/fields/common/address_container.rb +0 -17
  117. data/lib/mail/fields/common/common_address.rb +0 -161
  118. data/lib/mail/fields/common/common_date.rb +0 -36
  119. data/lib/mail/fields/common/common_field.rb +0 -52
  120. data/lib/mail/fields/common/common_message_id.rb +0 -49
  121. data/lib/mail/version_specific/ruby_1_8.rb +0 -163
  122. data/lib/mail/version_specific/ruby_1_9.rb +0 -278
@@ -1,55 +1,34 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # = From Field
5
- #
6
- # The From field inherits from StructuredField and handles the From: header
7
- # field in the email.
8
- #
9
- # Sending from to a mail message will instantiate a Mail::Field object that
10
- # has a FromField as its field type. This includes all Mail::CommonAddress
11
- # module instance metods.
12
- #
13
- # Only one From field can appear in a header, though it can have multiple
14
- # addresses and groups of addresses.
15
- #
16
- # == Examples:
17
- #
18
- # mail = Mail.new
19
- # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
20
- # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
21
- # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
22
- # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
23
- # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
24
- #
25
- # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
26
- # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
27
- # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
28
- # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
29
- #
30
- require 'mail/fields/common/common_address'
3
+ require 'mail/fields/common_address_field'
31
4
 
32
5
  module Mail
33
- class FromField < StructuredField
34
-
35
- include Mail::CommonAddress
36
-
37
- FIELD_NAME = 'from'
38
- CAPITALIZED_FIELD = 'From'
39
-
40
- def initialize(value = nil, charset = 'utf-8')
41
- self.charset = charset
42
- super(CAPITALIZED_FIELD, value, charset)
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,57 +1,46 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # = In-Reply-To Field
5
- #
6
- # The In-Reply-To field inherits from StructuredField and handles the
7
- # In-Reply-To: header field in the email.
8
- #
9
- # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
10
- # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
11
- # module instance metods.
12
- #
13
- # Note that, the #message_ids method will return an array of message IDs without the
14
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
15
- #
16
- # Only one InReplyTo field can appear in a header, though it can have multiple
17
- # Message IDs.
18
- #
19
- # == Examples:
20
- #
21
- # mail = Mail.new
22
- # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
23
- # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
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
- # mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
27
- #
28
- # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
29
- #
30
- require 'mail/fields/common/common_message_id'
3
+ require 'mail/fields/common_message_id_field'
31
4
 
32
5
  module Mail
33
- class InReplyToField < StructuredField
34
-
35
- include Mail::CommonMessageId
36
-
37
- FIELD_NAME = 'in-reply-to'
38
- CAPITALIZED_FIELD = 'In-Reply-To'
39
-
40
- def initialize(value = nil, charset = 'utf-8')
41
- self.charset = charset
42
- value = value.join("\r\n\s") if value.is_a?(Array)
43
- super(CAPITALIZED_FIELD, value, charset)
44
- self.parse
45
- self
46
- end
47
-
48
- def encoded
49
- 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
50
36
  end
51
-
52
- def decoded
53
- 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
54
44
  end
55
-
56
45
  end
57
46
  end
@@ -1,44 +1,31 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # keywords = "Keywords:" phrase *("," phrase) CRLF
3
+ require 'mail/fields/named_structured_field'
4
+
5
5
  module Mail
6
- class KeywordsField < StructuredField
7
-
8
- FIELD_NAME = 'keywords'
9
- CAPITALIZED_FIELD = 'Keywords'
10
-
11
- def initialize(value = nil, charset = 'utf-8')
12
- self.charset = charset
13
- super(CAPITALIZED_FIELD, value, charset)
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 Utilities.blank?(val)
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,83 +1,37 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # = Message-ID Field
5
- #
6
- # The Message-ID field inherits from StructuredField and handles the
7
- # Message-ID: header field in the email.
8
- #
9
- # Sending message_id to a mail message will instantiate a Mail::Field object that
10
- # has a MessageIdField as its field type. This includes all Mail::CommonMessageId
11
- # module instance metods.
12
- #
13
- # Only one MessageId field can appear in a header, and syntactically it can only have
14
- # one Message ID. The message_ids method call has been left in however as it will only
15
- # return the one message id, ie, an array of length 1.
16
- #
17
- # Note that, the #message_ids method will return an array of message IDs without the
18
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
19
- #
20
- # == Examples:
21
- #
22
- # mail = Mail.new
23
- # mail.message_id = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
24
- # mail.message_id #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
25
- # mail[:message_id] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
26
- # mail['message_id'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
27
- # mail['Message-ID'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
28
- #
29
- # mail[:message_id].message_id #=> 'F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom'
30
- # mail[:message_id].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
31
- #
32
- require 'mail/fields/common/common_message_id'
3
+ require 'mail/fields/common_message_id_field'
4
+ require 'mail/utilities'
33
5
 
34
6
  module Mail
35
- class MessageIdField < StructuredField
36
-
37
- include Mail::CommonMessageId
38
-
39
- FIELD_NAME = 'message-id'
40
- CAPITALIZED_FIELD = 'Message-ID'
41
-
42
- def initialize(value = nil, charset = 'utf-8')
43
- self.charset = charset
44
- @uniq = 1
45
- if Utilities.blank?(value)
46
- self.name = CAPITALIZED_FIELD
47
- self.value = generate_message_id
48
- else
49
- super(CAPITALIZED_FIELD, value, charset)
50
- end
51
- self.parse
52
- 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'
53
23
 
24
+ def self.singular?
25
+ true
54
26
  end
55
-
56
- def name
57
- '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
58
31
  end
59
-
32
+
60
33
  def message_ids
61
34
  [message_id]
62
35
  end
63
-
64
- def to_s
65
- "<#{message_id}>"
66
- end
67
-
68
- def encoded
69
- do_encode(CAPITALIZED_FIELD)
70
- end
71
-
72
- def decoded
73
- do_decode
74
- end
75
-
76
- private
77
-
78
- def generate_message_id
79
- "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
80
- end
81
-
82
36
  end
83
37
  end
@@ -1,35 +1,25 @@
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 MimeVersionField < StructuredField
8
-
9
- FIELD_NAME = 'mime-version'
10
- CAPITALIZED_FIELD = 'Mime-Version'
11
-
12
- def initialize(value = nil, charset = 'utf-8')
13
- self.charset = charset
14
- if Utilities.blank?(value)
15
- value = '1.0'
16
- end
17
- super(CAPITALIZED_FIELD, value, charset)
18
- self.parse
19
- self
20
-
21
- end
22
-
23
- def parse(val = value)
24
- unless Utilities.blank?(val)
25
- @element = Mail::MimeVersionElement.new(val)
26
- end
27
- end
28
-
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
+
29
19
  def element
30
20
  @element ||= Mail::MimeVersionElement.new(value)
31
21
  end
32
-
22
+
33
23
  def version
34
24
  "#{element.major}.#{element.minor}"
35
25
  end
@@ -41,14 +31,13 @@ module Mail
41
31
  def minor
42
32
  element.minor.to_i
43
33
  end
44
-
34
+
45
35
  def encoded
46
- "#{CAPITALIZED_FIELD}: #{version}\r\n"
36
+ "#{name}: #{version}\r\n"
47
37
  end
48
-
38
+
49
39
  def decoded
50
40
  version
51
41
  end
52
-
53
42
  end
54
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,14 +1,13 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # The field names of any optional-field MUST NOT be identical to any
5
- # field name specified elsewhere in this standard.
6
- #
7
- # optional-field = field-name ":" unstructured CRLF
8
3
  require 'mail/fields/unstructured_field'
9
4
 
10
5
  module Mail
11
- class OptionalField < UnstructuredField
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:
12
11
  private
13
12
  def do_encode
14
13
  "#{wrapped_value}\r\n"
@@ -1,31 +1,33 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- module Mail
3
+ require 'mail/constants'
4
+ require 'mail/indifferent_hash'
5
+ require 'mail/encodings'
4
6
 
7
+ module Mail
5
8
  # ParameterHash is an intelligent Hash that allows you to add
6
9
  # parameter values including the MIME extension paramaters that
7
10
  # have the name*0="blah", name*1="bleh" keys, and will just return
8
11
  # a single key called name="blahbleh" and do any required un-encoding
9
12
  # to make that happen
10
- # Parameters are defined in RFC2045, split keys are in RFC2231
11
-
12
- class ParameterHash < IndifferentHash
13
-
14
- include Mail::Utilities
15
-
13
+ #
14
+ # Parameters are defined in RFC2045. Split keys are in RFC2231.
15
+ class ParameterHash < IndifferentHash #:nodoc:
16
16
  def [](key_name)
17
17
  key_pattern = Regexp.escape(key_name.to_s)
18
18
  pairs = []
19
19
  exact = nil
20
+
20
21
  each do |k,v|
21
22
  if k =~ /^#{key_pattern}(\*|$)/i
22
- if $1 == ASTERISK
23
+ if $1 == Constants::ASTERISK
23
24
  pairs << [k, v]
24
25
  else
25
26
  exact = k
26
27
  end
27
28
  end
28
29
  end
30
+
29
31
  if pairs.empty? # Just dealing with a single value pair
30
32
  super(exact || key_name)
31
33
  else # Dealing with a multiple value pair or a single encoded value pair
@@ -46,13 +48,13 @@ module Mail
46
48
  value = Mail::Encodings.param_encode(value)
47
49
  key_name = "#{key_name}*"
48
50
  end
49
- %Q{#{key_name}=#{quote_token(value)}}
51
+ %Q{#{key_name}=#{Utilities.quote_token(value)}}
50
52
  end.join(";\r\n\s")
51
53
  end
52
54
 
53
55
  def decoded
54
56
  map.sort_by { |a| a.first.to_s }.map! do |key_name, value|
55
- %Q{#{key_name}=#{quote_token(value)}}
57
+ %Q{#{key_name}=#{Utilities.quote_token(value)}}
56
58
  end.join("; ")
57
59
  end
58
60
  end
@@ -1,76 +1,62 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # trace = [return]
5
- # 1*received
6
- #
7
- # return = "Return-Path:" path CRLF
8
- #
9
- # path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
10
- # obs-path
11
- #
12
- # received = "Received:" name-val-list ";" date-time CRLF
13
- #
14
- # name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
15
- #
16
- # name-val-pair = item-name CFWS item-value
17
- #
18
- # item-name = ALPHA *(["-"] (ALPHA / DIGIT))
19
- #
20
- # item-value = 1*angle-addr / addr-spec /
21
- # atom / domain / msg-id
22
- #
3
+ require 'mail/fields/named_structured_field'
4
+
23
5
  module Mail
24
- class ReceivedField < StructuredField
25
-
26
- FIELD_NAME = 'received'
27
- CAPITALIZED_FIELD = 'Received'
28
-
29
- def initialize(value = nil, charset = 'utf-8')
30
- self.charset = charset
31
- super(CAPITALIZED_FIELD, value, charset)
32
- self.parse
33
- self
6
+ # trace = [return]
7
+ # 1*received
8
+ #
9
+ # return = "Return-Path:" path CRLF
10
+ #
11
+ # path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
12
+ # obs-path
13
+ #
14
+ # received = "Received:" name-val-list ";" date-time CRLF
15
+ #
16
+ # name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
17
+ #
18
+ # name-val-pair = item-name CFWS item-value
19
+ #
20
+ # item-name = ALPHA *(["-"] (ALPHA / DIGIT))
21
+ #
22
+ # item-value = 1*angle-addr / addr-spec /
23
+ # atom / domain / msg-id
24
+ class ReceivedField < NamedStructuredField #:nodoc:
25
+ NAME = 'Received'
34
26
 
35
- end
36
-
37
- def parse(val = value)
38
- unless Utilities.blank?(val)
39
- @element = Mail::ReceivedElement.new(val)
40
- end
41
- end
42
-
43
27
  def element
44
28
  @element ||= Mail::ReceivedElement.new(value)
45
29
  end
46
-
30
+
47
31
  def date_time
48
- @datetime ||= ::DateTime.parse("#{element.date_time}")
32
+ @datetime ||= element.date_time
49
33
  end
50
34
 
51
35
  def info
52
36
  element.info
53
37
  end
54
-
38
+
55
39
  def formatted_date
56
- date_time.strftime("%a, %d %b %Y %H:%M:%S ") + date_time.zone.delete(':')
57
- end
58
-
59
- def encoded
60
- if Utilities.blank?(value)
61
- "#{CAPITALIZED_FIELD}: \r\n"
62
- else
63
- "#{CAPITALIZED_FIELD}: #{info}; #{formatted_date}\r\n"
40
+ if date_time.respond_to? :strftime and date_time.respond_to? :zone
41
+ date_time.strftime("%a, %d %b %Y %H:%M:%S ") + date_time.zone.delete(':')
64
42
  end
65
43
  end
66
-
67
- def decoded
68
- if Utilities.blank?(value)
69
- ""
70
- else
71
- "#{info}; #{formatted_date}"
44
+
45
+ private
46
+ def do_encode
47
+ if Utilities.blank?(value)
48
+ "#{name}: \r\n"
49
+ else
50
+ "#{name}: #{info}; #{formatted_date}\r\n"
51
+ end
52
+ end
53
+
54
+ def do_decode
55
+ if Utilities.blank?(value)
56
+ ""
57
+ else
58
+ "#{info}; #{formatted_date}"
59
+ end
72
60
  end
73
- end
74
-
75
61
  end
76
62
  end