kbaum-mail 2.1.2.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 (114) hide show
  1. data/CHANGELOG.rdoc +289 -0
  2. data/README.rdoc +575 -0
  3. data/Rakefile +72 -0
  4. data/TODO.rdoc +19 -0
  5. data/lib/mail.rb +113 -0
  6. data/lib/mail/attachments_list.rb +76 -0
  7. data/lib/mail/body.rb +243 -0
  8. data/lib/mail/configuration.rb +69 -0
  9. data/lib/mail/core_extensions/nil.rb +11 -0
  10. data/lib/mail/core_extensions/string.rb +19 -0
  11. data/lib/mail/elements/address.rb +306 -0
  12. data/lib/mail/elements/address_list.rb +74 -0
  13. data/lib/mail/elements/content_disposition_element.rb +30 -0
  14. data/lib/mail/elements/content_location_element.rb +25 -0
  15. data/lib/mail/elements/content_transfer_encoding_element.rb +21 -0
  16. data/lib/mail/elements/content_type_element.rb +35 -0
  17. data/lib/mail/elements/date_time_element.rb +26 -0
  18. data/lib/mail/elements/envelope_from_element.rb +34 -0
  19. data/lib/mail/elements/message_ids_element.rb +29 -0
  20. data/lib/mail/elements/mime_version_element.rb +26 -0
  21. data/lib/mail/elements/phrase_list.rb +21 -0
  22. data/lib/mail/elements/received_element.rb +30 -0
  23. data/lib/mail/encodings/base64.rb +18 -0
  24. data/lib/mail/encodings/encodings.rb +201 -0
  25. data/lib/mail/encodings/quoted_printable.rb +26 -0
  26. data/lib/mail/envelope.rb +35 -0
  27. data/lib/mail/field.rb +219 -0
  28. data/lib/mail/field_list.rb +33 -0
  29. data/lib/mail/fields/bcc_field.rb +53 -0
  30. data/lib/mail/fields/cc_field.rb +52 -0
  31. data/lib/mail/fields/comments_field.rb +41 -0
  32. data/lib/mail/fields/common/address_container.rb +16 -0
  33. data/lib/mail/fields/common/common_address.rb +128 -0
  34. data/lib/mail/fields/common/common_date.rb +51 -0
  35. data/lib/mail/fields/common/common_field.rb +64 -0
  36. data/lib/mail/fields/common/common_message_id.rb +57 -0
  37. data/lib/mail/fields/common/parameter_hash.rb +39 -0
  38. data/lib/mail/fields/content_description_field.rb +19 -0
  39. data/lib/mail/fields/content_disposition_field.rb +60 -0
  40. data/lib/mail/fields/content_id_field.rb +63 -0
  41. data/lib/mail/fields/content_location_field.rb +42 -0
  42. data/lib/mail/fields/content_transfer_encoding_field.rb +45 -0
  43. data/lib/mail/fields/content_type_field.rb +175 -0
  44. data/lib/mail/fields/date_field.rb +53 -0
  45. data/lib/mail/fields/from_field.rb +53 -0
  46. data/lib/mail/fields/in_reply_to_field.rb +52 -0
  47. data/lib/mail/fields/keywords_field.rb +43 -0
  48. data/lib/mail/fields/message_id_field.rb +80 -0
  49. data/lib/mail/fields/mime_version_field.rb +54 -0
  50. data/lib/mail/fields/optional_field.rb +11 -0
  51. data/lib/mail/fields/received_field.rb +62 -0
  52. data/lib/mail/fields/references_field.rb +53 -0
  53. data/lib/mail/fields/reply_to_field.rb +53 -0
  54. data/lib/mail/fields/resent_bcc_field.rb +53 -0
  55. data/lib/mail/fields/resent_cc_field.rb +53 -0
  56. data/lib/mail/fields/resent_date_field.rb +33 -0
  57. data/lib/mail/fields/resent_from_field.rb +53 -0
  58. data/lib/mail/fields/resent_message_id_field.rb +32 -0
  59. data/lib/mail/fields/resent_sender_field.rb +60 -0
  60. data/lib/mail/fields/resent_to_field.rb +53 -0
  61. data/lib/mail/fields/return_path_field.rb +62 -0
  62. data/lib/mail/fields/sender_field.rb +65 -0
  63. data/lib/mail/fields/structured_field.rb +36 -0
  64. data/lib/mail/fields/subject_field.rb +15 -0
  65. data/lib/mail/fields/to_field.rb +53 -0
  66. data/lib/mail/fields/unstructured_field.rb +117 -0
  67. data/lib/mail/header.rb +235 -0
  68. data/lib/mail/mail.rb +194 -0
  69. data/lib/mail/message.rb +1780 -0
  70. data/lib/mail/network/delivery_methods/file_delivery.rb +40 -0
  71. data/lib/mail/network/delivery_methods/sendmail.rb +62 -0
  72. data/lib/mail/network/delivery_methods/smtp.rb +110 -0
  73. data/lib/mail/network/delivery_methods/test_mailer.rb +40 -0
  74. data/lib/mail/network/retriever_methods/imap.rb +31 -0
  75. data/lib/mail/network/retriever_methods/pop3.rb +149 -0
  76. data/lib/mail/parsers/address_lists.rb +61 -0
  77. data/lib/mail/parsers/address_lists.treetop +19 -0
  78. data/lib/mail/parsers/content_disposition.rb +369 -0
  79. data/lib/mail/parsers/content_disposition.treetop +46 -0
  80. data/lib/mail/parsers/content_location.rb +133 -0
  81. data/lib/mail/parsers/content_location.treetop +20 -0
  82. data/lib/mail/parsers/content_transfer_encoding.rb +179 -0
  83. data/lib/mail/parsers/content_transfer_encoding.treetop +25 -0
  84. data/lib/mail/parsers/content_type.rb +512 -0
  85. data/lib/mail/parsers/content_type.treetop +58 -0
  86. data/lib/mail/parsers/date_time.rb +111 -0
  87. data/lib/mail/parsers/date_time.treetop +11 -0
  88. data/lib/mail/parsers/envelope_from.rb +188 -0
  89. data/lib/mail/parsers/envelope_from.treetop +32 -0
  90. data/lib/mail/parsers/message_ids.rb +42 -0
  91. data/lib/mail/parsers/message_ids.treetop +15 -0
  92. data/lib/mail/parsers/mime_version.rb +141 -0
  93. data/lib/mail/parsers/mime_version.treetop +19 -0
  94. data/lib/mail/parsers/phrase_lists.rb +42 -0
  95. data/lib/mail/parsers/phrase_lists.treetop +15 -0
  96. data/lib/mail/parsers/received.rb +68 -0
  97. data/lib/mail/parsers/received.treetop +11 -0
  98. data/lib/mail/parsers/rfc2045.rb +406 -0
  99. data/lib/mail/parsers/rfc2045.treetop +35 -0
  100. data/lib/mail/parsers/rfc2822.rb +5081 -0
  101. data/lib/mail/parsers/rfc2822.treetop +410 -0
  102. data/lib/mail/parsers/rfc2822_obsolete.rb +3607 -0
  103. data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
  104. data/lib/mail/part.rb +82 -0
  105. data/lib/mail/parts_list.rb +34 -0
  106. data/lib/mail/patterns.rb +43 -0
  107. data/lib/mail/utilities.rb +163 -0
  108. data/lib/mail/vendor/treetop.rb +4 -0
  109. data/lib/mail/version.rb +10 -0
  110. data/lib/mail/version_specific/ruby_1_8.rb +84 -0
  111. data/lib/mail/version_specific/ruby_1_9.rb +77 -0
  112. data/lib/tasks/corpus.rake +125 -0
  113. data/lib/tasks/treetop.rake +10 -0
  114. metadata +188 -0
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ #
3
+ # = Resent-From Field
4
+ #
5
+ # The Resent-From field inherits resent-from StructuredField and handles the Resent-From: header
6
+ # field in the email.
7
+ #
8
+ # Sending resent_from to a mail message will instantiate a Mail::Field object that
9
+ # has a ResentFromField as it's field type. This includes all Mail::CommonAddress
10
+ # module instance metods.
11
+ #
12
+ # Only one Resent-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.resent_from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
+ # mail.resent_from #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
20
+ # mail[:resent_from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
21
+ # mail['resent-from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
22
+ # mail['Resent-From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentFromField:0x180e1c4
23
+ #
24
+ # mail[:resent_from].encoded #=> 'Resent-From: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
+ # mail[:resent_from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
+ # mail[:resent_from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
+ # mail[:resent_from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
28
+ #
29
+ module Mail
30
+ class ResentFromField < StructuredField
31
+
32
+ include Mail::CommonAddress
33
+
34
+ FIELD_NAME = 'resent-from'
35
+ CAPITALIZED_FIELD = 'Resent-From'
36
+
37
+ def initialize(*args)
38
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ self.parse
40
+ self
41
+
42
+ end
43
+
44
+ def encoded
45
+ do_encode(CAPITALIZED_FIELD)
46
+ end
47
+
48
+ def decoded
49
+ do_decode
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ #
3
+ # resent-msg-id = "Resent-Message-ID:" msg-id CRLF
4
+ module Mail
5
+ class ResentMessageIdField < StructuredField
6
+
7
+ include CommonMessageId
8
+
9
+ FIELD_NAME = 'resent-message-id'
10
+ CAPITALIZED_FIELD = 'Resent-Message-ID'
11
+
12
+ def initialize(*args)
13
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
14
+ self.parse
15
+ self
16
+
17
+ end
18
+
19
+ def name
20
+ 'Resent-Message-ID'
21
+ end
22
+
23
+ def encoded
24
+ do_encode(CAPITALIZED_FIELD)
25
+ end
26
+
27
+ def decoded
28
+ do_decode
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ #
3
+ # = Resent-Sender Field
4
+ #
5
+ # The Resent-Sender field inherits resent-sender StructuredField and handles the Resent-Sender: header
6
+ # field in the email.
7
+ #
8
+ # Sending resent_sender to a mail message will instantiate a Mail::Field object that
9
+ # has a ResentSenderField as it's field type. This includes all Mail::CommonAddress
10
+ # module instance metods.
11
+ #
12
+ # Only one Resent-Sender 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.resent_sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
+ # mail.resent_sender #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
20
+ # mail[:resent_sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
21
+ # mail['resent-sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
22
+ # mail['Resent-Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentSenderField:0x180e1c4
23
+ #
24
+ # mail.resent_sender.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
25
+ # mail.resent_sender.addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
26
+ # mail.resent_sender.formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
27
+ #
28
+ module Mail
29
+ class ResentSenderField < StructuredField
30
+
31
+ include Mail::CommonAddress
32
+
33
+ FIELD_NAME = 'resent-sender'
34
+ CAPITALIZED_FIELD = 'Resent-Sender'
35
+
36
+ def initialize(*args)
37
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
38
+ self.parse
39
+ self
40
+
41
+ end
42
+
43
+ def addresses
44
+ [address.address]
45
+ end
46
+
47
+ def address
48
+ result = tree.addresses.first
49
+ end
50
+
51
+ def encoded
52
+ do_encode(CAPITALIZED_FIELD)
53
+ end
54
+
55
+ def decoded
56
+ do_decode
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ #
3
+ # = Resent-To Field
4
+ #
5
+ # The Resent-To field inherits resent-to StructuredField and handles the Resent-To: header
6
+ # field in the email.
7
+ #
8
+ # Sending resent_to to a mail message will instantiate a Mail::Field object that
9
+ # has a ResentToField as it's field type. This includes all Mail::CommonAddress
10
+ # module instance metods.
11
+ #
12
+ # Only one Resent-To 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.resent_to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
+ # mail.resent_to #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
20
+ # mail[:resent_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
21
+ # mail['resent-to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
22
+ # mail['Resent-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ResentToField:0x180e1c4
23
+ #
24
+ # mail[:resent_to].encoded #=> 'Resent-To: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
+ # mail[:resent_to].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
+ # mail[:resent_to].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
+ # mail[:resent_to].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
28
+ #
29
+ module Mail
30
+ class ResentToField < StructuredField
31
+
32
+ include Mail::CommonAddress
33
+
34
+ FIELD_NAME = 'resent-to'
35
+ CAPITALIZED_FIELD = 'Resent-To'
36
+
37
+ def initialize(*args)
38
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ self.parse
40
+ self
41
+
42
+ end
43
+
44
+ def encoded
45
+ do_encode(CAPITALIZED_FIELD)
46
+ end
47
+
48
+ def decoded
49
+ do_decode
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ #
3
+ # 4.4.3. REPLY-TO / RESENT-REPLY-TO
4
+ #
5
+ # Note: The "Return-Path" field is added by the mail transport
6
+ # service, at the time of final deliver. It is intended
7
+ # to identify a path back to the orginator of the mes-
8
+ # sage. The "Reply-To" field is added by the message
9
+ # originator and is intended to direct replies.
10
+ #
11
+ # trace = [return]
12
+ # 1*received
13
+ #
14
+ # return = "Return-Path:" path CRLF
15
+ #
16
+ # path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
17
+ # obs-path
18
+ #
19
+ # received = "Received:" name-val-list ";" date-time CRLF
20
+ #
21
+ # name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
22
+ #
23
+ # name-val-pair = item-name CFWS item-value
24
+ #
25
+ # item-name = ALPHA *(["-"] (ALPHA / DIGIT))
26
+ #
27
+ # item-value = 1*angle-addr / addr-spec /
28
+ # atom / domain / msg-id
29
+ #
30
+ module Mail
31
+ class ReturnPathField < StructuredField
32
+
33
+ include Mail::CommonAddress
34
+
35
+ FIELD_NAME = 'return-path'
36
+ CAPITALIZED_FIELD = 'Return-Path'
37
+
38
+ def initialize(*args)
39
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
40
+ self.parse
41
+ self
42
+
43
+ end
44
+
45
+ def encoded
46
+ "#{CAPITALIZED_FIELD}: <#{address}>\r\n"
47
+ end
48
+
49
+ def decoded
50
+ do_decode
51
+ end
52
+
53
+ def address
54
+ addresses.first
55
+ end
56
+
57
+ def default
58
+ address
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ #
3
+ # = Sender Field
4
+ #
5
+ # The Sender field inherits sender StructuredField and handles the Sender: header
6
+ # field in the email.
7
+ #
8
+ # Sending sender to a mail message will instantiate a Mail::Field object that
9
+ # has a SenderField as it's field type. This includes all Mail::CommonAddress
10
+ # module instance metods.
11
+ #
12
+ # Only one Sender 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.sender = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
+ # mail.sender #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
20
+ # mail[:sender] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
21
+ # mail['sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
22
+ # mail['Sender'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::SenderField:0x180e1c4
23
+ #
24
+ # mail[:sender].encoded #=> 'Sender: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
+ # mail[:sender].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
+ # mail[:sender].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
+ # mail[:sender].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
28
+ #
29
+ module Mail
30
+ class SenderField < StructuredField
31
+
32
+ include Mail::CommonAddress
33
+
34
+ FIELD_NAME = 'sender'
35
+ CAPITALIZED_FIELD = 'Sender'
36
+
37
+ def initialize(*args)
38
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ self.parse
40
+ self
41
+
42
+ end
43
+
44
+ def addresses
45
+ [address.address]
46
+ end
47
+
48
+ def address
49
+ result = tree.addresses.first
50
+ end
51
+
52
+ def encoded
53
+ do_encode(CAPITALIZED_FIELD)
54
+ end
55
+
56
+ def decoded
57
+ do_decode
58
+ end
59
+
60
+ def default
61
+ address.address
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+ # Provides access to a structured header field
4
+ #
5
+ # ===Per RFC 2822:
6
+ # 2.2.2. Structured Header Field Bodies
7
+ #
8
+ # Some field bodies in this standard have specific syntactical
9
+ # structure more restrictive than the unstructured field bodies
10
+ # described above. These are referred to as "structured" field bodies.
11
+ # Structured field bodies are sequences of specific lexical tokens as
12
+ # described in sections 3 and 4 of this standard. Many of these tokens
13
+ # are allowed (according to their syntax) to be introduced or end with
14
+ # comments (as described in section 3.2.3) as well as the space (SP,
15
+ # ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters
16
+ # (together known as the white space characters, WSP), and those WSP
17
+ # characters are subject to header "folding" and "unfolding" as
18
+ # described in section 2.2.3. Semantic analysis of structured field
19
+ # bodies is given along with their syntax.
20
+ class StructuredField
21
+
22
+ include Mail::CommonField
23
+ include Mail::Utilities
24
+
25
+ def initialize(*args)
26
+ self.name = args.first
27
+ self.value = args.last
28
+ self
29
+ end
30
+
31
+ def default
32
+ decoded
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ #
3
+ # subject = "Subject:" unstructured CRLF
4
+ module Mail
5
+ class SubjectField < UnstructuredField
6
+
7
+ FIELD_NAME = 'subject'
8
+ CAPITALIZED_FIELD = "Subject"
9
+
10
+ def initialize(*args)
11
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ #
3
+ # = To Field
4
+ #
5
+ # The To field inherits to StructuredField and handles the To: header
6
+ # field in the email.
7
+ #
8
+ # Sending to to a mail message will instantiate a Mail::Field object that
9
+ # has a ToField as it's field type. This includes all Mail::CommonAddress
10
+ # module instance metods.
11
+ #
12
+ # Only one To 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.to = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
+ # mail.to #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
20
+ # mail[:to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
21
+ # mail['to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
22
+ # mail['To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
23
+ #
24
+ # mail[:to].encoded #=> 'To: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
+ # mail[:to].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
+ # mail[:to].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
+ # mail[:to].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
28
+ #
29
+ module Mail
30
+ class ToField < StructuredField
31
+
32
+ include Mail::CommonAddress
33
+
34
+ FIELD_NAME = 'to'
35
+ CAPITALIZED_FIELD = 'To'
36
+
37
+ def initialize(*args)
38
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ self.parse
40
+ self
41
+
42
+ end
43
+
44
+ def encoded
45
+ do_encode(CAPITALIZED_FIELD)
46
+ end
47
+
48
+ def decoded
49
+ do_decode
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,117 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+ # Provides access to an unstructured header field
4
+ #
5
+ # ===Per RFC 2822:
6
+ # 2.2.1. Unstructured Header Field Bodies
7
+ #
8
+ # Some field bodies in this standard are defined simply as
9
+ # "unstructured" (which is specified below as any US-ASCII characters,
10
+ # except for CR and LF) with no further restrictions. These are
11
+ # referred to as unstructured field bodies. Semantically, unstructured
12
+ # field bodies are simply to be treated as a single line of characters
13
+ # with no further processing (except for header "folding" and
14
+ # "unfolding" as described in section 2.2.3).
15
+ class UnstructuredField
16
+
17
+ include Mail::CommonField
18
+ include Mail::Utilities
19
+
20
+ def initialize(*args)
21
+ self.name = args.first
22
+ self.value = args.last
23
+ self
24
+ end
25
+
26
+ def encoded
27
+ do_encode(self.name)
28
+ end
29
+
30
+ def decoded
31
+ do_decode
32
+ end
33
+
34
+ def default
35
+ decoded
36
+ end
37
+
38
+ def parse # An unstructured field does not parse
39
+ self
40
+ end
41
+
42
+ private
43
+
44
+ def do_encode(name)
45
+ value.nil? ? '' : "#{wrapped_value}\r\n"
46
+ end
47
+
48
+ def do_decode
49
+ value.blank? ? nil : Encodings.decode_encode(value, :decode)
50
+ end
51
+
52
+ # 2.2.3. Long Header Fields
53
+ #
54
+ # Each header field is logically a single line of characters comprising
55
+ # the field name, the colon, and the field body. For convenience
56
+ # however, and to deal with the 998/78 character limitations per line,
57
+ # the field body portion of a header field can be split into a multiple
58
+ # line representation; this is called "folding". The general rule is
59
+ # that wherever this standard allows for folding white space (not
60
+ # simply WSP characters), a CRLF may be inserted before any WSP. For
61
+ # example, the header field:
62
+ #
63
+ # Subject: This is a test
64
+ #
65
+ # can be represented as:
66
+ #
67
+ # Subject: This
68
+ # is a test
69
+ #
70
+ # Note: Though structured field bodies are defined in such a way that
71
+ # folding can take place between many of the lexical tokens (and even
72
+ # within some of the lexical tokens), folding SHOULD be limited to
73
+ # placing the CRLF at higher-level syntactic breaks. For instance, if
74
+ # a field body is defined as comma-separated values, it is recommended
75
+ # that folding occur after the comma separating the structured items in
76
+ # preference to other places where the field could be folded, even if
77
+ # it is allowed elsewhere.
78
+ def wrapped_value # :nodoc:
79
+ case
80
+ when decoded.to_s.ascii_only? && field_length <= 78
81
+ "#{name}: #{value}"
82
+ when field_length <= 40 # Allow for =?ISO-8859-1?B?=...=
83
+ "#{name}: #{encode(value)}"
84
+ else
85
+ @folded_line = []
86
+ @unfolded_line = value.clone
87
+ fold("#{name}: ".length)
88
+ folded = @folded_line.map { |l| l unless l.blank? }.compact.join("\r\n\t")
89
+ "#{name}: #{folded}"
90
+ end
91
+ end
92
+
93
+ def fold(prepend = 0) # :nodoc:
94
+ # Get the last whitespace character, OR we'll just choose
95
+ # 78 if there is no whitespace
96
+ @unfolded_line.ascii_only? ? (limit = 78 - prepend) : (limit = 40 - prepend)
97
+ wspp = @unfolded_line.slice(0..limit) =~ /[ \t][^ \T]*$/ || limit
98
+ wspp = limit if wspp == 0
99
+ @folded_line << encode(@unfolded_line.slice!(0...wspp))
100
+ if @unfolded_line.length > limit
101
+ fold
102
+ else
103
+ @folded_line << encode(@unfolded_line)
104
+ end
105
+ end
106
+
107
+ def encode(value)
108
+ if value.ascii_only?
109
+ value
110
+ else
111
+ RUBY_VERSION < '1.9' ? encoding = $KCODE : encoding = @value.encoding
112
+ Encodings.b_value_encode(value, encoding)
113
+ end
114
+ end
115
+
116
+ end
117
+ end