mail 2.5.5 → 2.6.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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +8 -9
  3. data/CONTRIBUTING.md +13 -0
  4. data/Dependencies.txt +0 -1
  5. data/Gemfile +7 -24
  6. data/README.md +36 -15
  7. data/Rakefile +10 -2
  8. data/VERSION +4 -0
  9. data/lib/mail.rb +1 -1
  10. data/lib/mail/body.rb +2 -2
  11. data/lib/mail/check_delivery_params.rb +10 -47
  12. data/lib/mail/core_extensions/string.rb +12 -2
  13. data/lib/mail/elements/address.rb +38 -82
  14. data/lib/mail/elements/address_list.rb +19 -42
  15. data/lib/mail/elements/content_disposition_element.rb +3 -7
  16. data/lib/mail/elements/content_location_element.rb +2 -6
  17. data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
  18. data/lib/mail/elements/content_type_element.rb +4 -8
  19. data/lib/mail/elements/date_time_element.rb +3 -7
  20. data/lib/mail/elements/envelope_from_element.rb +3 -11
  21. data/lib/mail/elements/message_ids_element.rb +1 -6
  22. data/lib/mail/elements/mime_version_element.rb +3 -7
  23. data/lib/mail/elements/phrase_list.rb +2 -7
  24. data/lib/mail/elements/received_element.rb +3 -7
  25. data/lib/mail/encodings.rb +0 -1
  26. data/lib/mail/envelope.rb +0 -5
  27. data/lib/mail/field.rb +53 -17
  28. data/lib/mail/field_list.rb +18 -18
  29. data/lib/mail/fields/common/common_address.rb +15 -20
  30. data/lib/mail/fields/common/common_date.rb +0 -7
  31. data/lib/mail/fields/common/common_field.rb +1 -1
  32. data/lib/mail/fields/content_transfer_encoding_field.rb +0 -6
  33. data/lib/mail/fields/resent_sender_field.rb +1 -1
  34. data/lib/mail/fields/sender_field.rb +1 -1
  35. data/lib/mail/fields/unstructured_field.rb +7 -1
  36. data/lib/mail/header.rb +8 -22
  37. data/lib/mail/mail.rb +12 -0
  38. data/lib/mail/matchers/has_sent_mail.rb +34 -1
  39. data/lib/mail/message.rb +18 -11
  40. data/lib/mail/multibyte/unicode.rb +1 -1
  41. data/lib/mail/network/delivery_methods/exim.rb +10 -6
  42. data/lib/mail/network/delivery_methods/file_delivery.rb +8 -4
  43. data/lib/mail/network/delivery_methods/sendmail.rb +7 -9
  44. data/lib/mail/network/delivery_methods/smtp.rb +5 -2
  45. data/lib/mail/network/delivery_methods/smtp_connection.rb +6 -2
  46. data/lib/mail/network/delivery_methods/test_mailer.rb +8 -5
  47. data/lib/mail/network/retriever_methods/imap.rb +18 -13
  48. data/lib/mail/parsers.rb +26 -0
  49. data/lib/mail/parsers/address_lists_parser.rb +132 -0
  50. data/lib/mail/parsers/content_disposition_parser.rb +67 -0
  51. data/lib/mail/parsers/content_location_parser.rb +35 -0
  52. data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
  53. data/lib/mail/parsers/content_type_parser.rb +64 -0
  54. data/lib/mail/parsers/date_time_parser.rb +36 -0
  55. data/lib/mail/parsers/envelope_from_parser.rb +45 -0
  56. data/lib/mail/parsers/message_ids_parser.rb +39 -0
  57. data/lib/mail/parsers/mime_version_parser.rb +41 -0
  58. data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
  59. data/lib/mail/parsers/ragel.rb +17 -0
  60. data/lib/mail/parsers/ragel/common.rl +184 -0
  61. data/lib/mail/parsers/ragel/date_time.rl +30 -0
  62. data/lib/mail/parsers/ragel/parser_info.rb +61 -0
  63. data/lib/mail/parsers/ragel/ruby.rb +29 -0
  64. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
  65. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
  66. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
  67. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
  68. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
  69. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
  70. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
  71. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
  72. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
  73. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
  74. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
  75. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
  76. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
  77. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
  78. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
  79. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
  80. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
  81. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
  82. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
  83. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
  84. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
  85. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
  86. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
  87. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
  88. data/lib/mail/parsers/received_parser.rb +47 -0
  89. data/lib/mail/parts_list.rb +4 -2
  90. data/lib/mail/patterns.rb +3 -1
  91. data/lib/mail/utilities.rb +3 -1
  92. data/lib/mail/version.rb +1 -1
  93. data/lib/mail/version_specific/ruby_1_8.rb +1 -1
  94. data/lib/mail/version_specific/ruby_1_9.rb +13 -1
  95. metadata +55 -51
  96. data/lib/VERSION +0 -4
  97. data/lib/load_parsers.rb +0 -35
  98. data/lib/mail/parsers/address_lists.rb +0 -64
  99. data/lib/mail/parsers/address_lists.treetop +0 -19
  100. data/lib/mail/parsers/content_disposition.rb +0 -535
  101. data/lib/mail/parsers/content_disposition.treetop +0 -46
  102. data/lib/mail/parsers/content_location.rb +0 -139
  103. data/lib/mail/parsers/content_location.treetop +0 -20
  104. data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
  105. data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
  106. data/lib/mail/parsers/content_type.rb +0 -971
  107. data/lib/mail/parsers/content_type.treetop +0 -68
  108. data/lib/mail/parsers/date_time.rb +0 -114
  109. data/lib/mail/parsers/date_time.treetop +0 -11
  110. data/lib/mail/parsers/envelope_from.rb +0 -194
  111. data/lib/mail/parsers/envelope_from.treetop +0 -32
  112. data/lib/mail/parsers/message_ids.rb +0 -45
  113. data/lib/mail/parsers/message_ids.treetop +0 -15
  114. data/lib/mail/parsers/mime_version.rb +0 -144
  115. data/lib/mail/parsers/mime_version.treetop +0 -19
  116. data/lib/mail/parsers/phrase_lists.rb +0 -45
  117. data/lib/mail/parsers/phrase_lists.treetop +0 -15
  118. data/lib/mail/parsers/received.rb +0 -71
  119. data/lib/mail/parsers/received.treetop +0 -11
  120. data/lib/mail/parsers/rfc2045.rb +0 -421
  121. data/lib/mail/parsers/rfc2045.treetop +0 -35
  122. data/lib/mail/parsers/rfc2822.rb +0 -5397
  123. data/lib/mail/parsers/rfc2822.treetop +0 -408
  124. data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
  125. data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
  126. data/lib/tasks/corpus.rake +0 -125
  127. data/lib/tasks/treetop.rake +0 -10
@@ -1,241 +0,0 @@
1
- module Mail
2
- grammar RFC2822Obsolete
3
-
4
- rule obs_qp
5
- "\\" [\x00-\x7F]
6
- end
7
-
8
- rule obs_text
9
- LF* CR* (obs_char LF* CR*)*
10
- end
11
-
12
- rule obs_char
13
- [\x00-\x09] / # %d0-127 except CR and
14
- [\x0B-\x0C] / # LF
15
- [\x0E-\x7F]
16
- end
17
-
18
- rule obs_utext
19
- obs_text
20
- end
21
-
22
- rule obs_phrase
23
- (word / "." / "@")+
24
- end
25
-
26
- rule obs_phrase_list
27
- phrase / (phrase? CFWS? "," CFWS?)+ phrase?
28
- end
29
-
30
- rule obs_FWS
31
- WSP+ (CRLF WSP+)*
32
- end
33
-
34
- rule obs_day_of_week
35
- CFWS? day_name CFWS?
36
- end
37
-
38
- rule obs_year
39
- CFWS? (DIGIT DIGIT) CFWS?
40
- end
41
-
42
- rule obs_month
43
- CFWS month_name CFWS
44
- end
45
-
46
- rule obs_day
47
- CFWS? (DIGIT / (DIGIT DIGIT)) CFWS?
48
- end
49
-
50
- rule obs_hour
51
- CFWS? (DIGIT DIGIT) CFWS?
52
- end
53
-
54
- rule obs_minute
55
- CFWS? (DIGIT DIGIT) CFWS?
56
- end
57
-
58
- rule obs_second
59
- CFWS? (DIGIT DIGIT) CFWS?
60
- end
61
-
62
- rule obs_zone
63
- "UT" / "GMT" / # Universal Time
64
- # North American UT
65
- # offsets
66
- "EST" / "EDT" / # Eastern: - 5/ - 4
67
- "CST" / "CDT" / # Central: - 6/ - 5
68
- "MST" / "MDT" / # Mountain: - 7/ - 6
69
- "PST" / "PDT" / # Pacific: - 8/ - 7
70
- #
71
- [\x41-\x49] / # Military zones - "A"
72
- [\x4B-\x5A] / # through "I" and "K"
73
- [\x61-\x69] / # through "Z", both
74
- [\x6B-\x7A] # upper and lower case
75
- end
76
-
77
- rule obs_angle_addr
78
- CFWS? "<" obs_route? addr_spec ">" CFWS?
79
- end
80
-
81
- rule obs_route
82
- CFWS? obs_domain_list ":" CFWS?
83
- end
84
-
85
- rule obs_domain_list
86
- "@" domain (("," )* CFWS? "@" domain)*
87
- end
88
-
89
- rule obs_local_part
90
- word ("." word)*
91
- end
92
-
93
- rule obs_domain
94
- atom ("." atom)*
95
- end
96
-
97
- rule obs_mbox_list
98
- (mailbox? CFWS? "," CFWS?)+ mailbox?
99
- end
100
-
101
- rule obs_addr_list
102
- (address? CFWS? "," CFWS?)+ address?
103
- end
104
-
105
- rule obs_fields
106
- (obs_return /
107
- obs_received /
108
- obs_orig_date /
109
- obs_from /
110
- obs_sender /
111
- obs_reply_to /
112
- obs_to /
113
- obs_cc /
114
- obs_bcc /
115
- obs_message_id /
116
- obs_in_reply_to /
117
- obs_references /
118
- obs_subject /
119
- obs_comments /
120
- obs_keywords /
121
- obs_resent_date /
122
- obs_resent_from /
123
- obs_resent_send /
124
- obs_resent_rply /
125
- obs_resent_to /
126
- obs_resent_cc /
127
- obs_resent_bcc /
128
- obs_resent_mid /
129
- obs_optional)*
130
- end
131
-
132
- rule obs_orig_date
133
- "Date" WSP* ":" date_time CRLF
134
- end
135
-
136
- rule obs_from
137
- "From" WSP* ":" mailbox_list CRLF
138
- end
139
-
140
- rule obs_sender
141
- "Sender" WSP* ":" mailbox CRLF
142
- end
143
-
144
- rule obs_reply_to
145
- "Reply-To" WSP* ":" mailbox_list CRLF
146
- end
147
-
148
-
149
- rule obs_to
150
- "To" WSP* ":" address_list CRLF
151
- end
152
-
153
- rule obs_cc
154
- "Cc" WSP* ":" address_list CRLF
155
- end
156
-
157
- rule obs_bcc
158
- "Bcc" WSP* ":" (address_list / CFWS?) CRLF
159
- end
160
-
161
- rule obs_message_id
162
- "Message-ID" WSP* ":" msg_id CRLF
163
- end
164
-
165
- rule obs_in_reply_to
166
- "In-Reply-To" WSP* ":" (phrase / msg_id)* CRLF
167
- end
168
-
169
- rule obs_references
170
- "References" WSP* ":" (phrase / msg_id)* CRLF
171
- end
172
-
173
- rule obs_id_left
174
- local_part
175
- end
176
-
177
- rule obs_id_right
178
- domain
179
- end
180
-
181
- rule obs_subject
182
- "Subject" WSP* ":" unstructured CRLF
183
- end
184
-
185
- rule obs_comments
186
- "Comments" WSP* ":" unstructured CRLF
187
- end
188
-
189
- rule obs_keywords
190
- "Keywords" WSP* ":" obs_phrase_list CRLF
191
- end
192
-
193
- rule obs_resent_from
194
- "Resent-From" WSP* ":" mailbox_list CRLF
195
- end
196
-
197
- rule obs_resent_send
198
- "Resent-Sender" WSP* ":" mailbox CRLF
199
- end
200
-
201
- rule obs_resent_date
202
- "Resent-Date" WSP* ":" date_time CRLF
203
- end
204
-
205
- rule obs_resent_to
206
- "Resent-To" WSP* ":" address_list CRLF
207
- end
208
-
209
- rule obs_resent_cc
210
- "Resent-Cc" WSP* ":" address_list CRLF
211
- end
212
-
213
- rule obs_resent_bcc
214
- "Resent-Bcc" WSP* ":" (address_list / CFWS?) CRLF
215
- end
216
-
217
- rule obs_resent_mid
218
- "Resent-Message-ID" WSP* ":" msg_id CRLF
219
- end
220
-
221
- rule obs_resent_rply
222
- "Resent-Reply-To" WSP* ":" address_list CRLF
223
- end
224
-
225
- rule obs_return
226
- "Return-Path" WSP* ":" path CRLF
227
- end
228
-
229
- rule obs_received
230
- "Received" WSP* ":" name_val_list CRLF
231
- end
232
-
233
- rule obs_path
234
- obs_angle_addr
235
- end
236
-
237
- rule obs_optional
238
- field_name WSP* ":" unstructured CRLF
239
- end
240
- end
241
- end
@@ -1,125 +0,0 @@
1
- namespace :corpus do
2
-
3
- task :load_mail do
4
- require File.expand_path('../../../spec/environment')
5
- require 'mail'
6
- end
7
-
8
- # Used to run parsing against an arbitrary corpus of email.
9
- # For example: http://plg.uwaterloo.ca/~gvcormac/treccorpus/
10
- desc "Provide a LOCATION=/some/dir to verify parsing in bulk, otherwise defaults"
11
- task :verify_all => :load_mail do
12
-
13
- root_of_corpus = ENV['LOCATION'] || 'corpus/spam'
14
- @save_failures_to = ENV['SAVE_TO'] || 'spec/fixtures/emails/failed_emails'
15
- @failed_emails = []
16
- @checked_count = 0
17
-
18
- if root_of_corpus
19
- root_of_corpus = File.expand_path(root_of_corpus)
20
- if not File.directory?(root_of_corpus)
21
- raise "\n\tPath '#{root_of_corpus}' is not a directory.\n\n"
22
- end
23
- else
24
- raise "\n\tSupply path to corpus: LOCATION=/path/to/corpus\n\n"
25
- end
26
-
27
- if @save_failures_to
28
- if not File.directory?(@save_failures_to)
29
- raise "\n\tPath '#{@save_failures_to}' is not a directory.\n\n"
30
- end
31
- @save_failures_to = File.expand_path(@save_failures_to)
32
- puts "Mail which fails to parse will be saved in '#{@save_failures_to}'"
33
- end
34
-
35
- puts "Checking '#{root_of_corpus}' directory (recursively)"
36
-
37
- # we're tracking all the errors separately, don't clutter terminal
38
- $stderr_backup = $stderr.dup
39
- $stderr.reopen("/dev/null", "w")
40
- STDERR = $stderr
41
-
42
- dir_node(root_of_corpus)
43
-
44
- # put our toys back now that we're done with them
45
- $stderr = $stderr_backup.dup
46
- STDERR = $stderr
47
-
48
- puts "\n\n"
49
-
50
- if @failed_emails.any?
51
- report_failures_to_stdout
52
- end
53
- puts "Out of Total: #{@checked_count}"
54
-
55
- if @save_failures_to
56
- puts "Add SAVE_TO=/some/dir to save failed emails to for review.,"
57
- puts "May result in a lot of saved files. Do a dry run first!\n\n"
58
- else
59
- puts "There are no errors"
60
- end
61
- end
62
-
63
- def dir_node(path)
64
- puts "\n\n"
65
- puts "Checking emails in '#{path}':"
66
-
67
- entries = Dir.entries(path)
68
-
69
- entries.each do |entry|
70
- next if ['.', '..'].include?(entry)
71
- full_path = File.join(path, entry)
72
-
73
- if File.file?(full_path)
74
- file_node(full_path)
75
- elsif File.directory?(full_path)
76
- dir_node(full_path)
77
- end
78
- end
79
- end
80
-
81
- def file_node(path)
82
- verify(path)
83
- end
84
-
85
- def verify(path)
86
- result, message = parse_as_mail(path)
87
- if result
88
- print '.'
89
- $stdout.flush
90
- else
91
- save_failure(path, message)
92
- print 'x'
93
- end
94
- end
95
-
96
- def save_failure(path, message)
97
- @failed_emails << [path, message]
98
- if @save_failures_to
99
- email_basename = File.basename(path)
100
- failure_as_filename = message.gsub(/\W/, '_')
101
- new_email_name = [failure_as_filename, email_basename].join("_")
102
- File.open(File.join(@save_failures_to, new_email_name), 'w+') do |fh|
103
- fh << File.read(path)
104
- end
105
- end
106
- end
107
-
108
- def parse_as_mail(path)
109
- @checked_count += 1
110
- begin
111
- parsed_mail = Mail.read(path)
112
- [true, nil]
113
- rescue => e
114
- [false, e.message]
115
- end
116
- end
117
-
118
- def report_failures_to_stdout
119
- @failed_emails.each do |failed|
120
- puts "#{failed[0]} : #{failed[1]}"
121
- end
122
- puts "Failed: #{@failed_emails.size}"
123
- end
124
-
125
- end
@@ -1,10 +0,0 @@
1
- namespace :treetop do
2
-
3
- desc "Pre-generate all the .treetop files into .rb files"
4
- task :generate do
5
- Dir.glob(File.expand_path('../../mail/parsers/*.treetop', __FILE__)).each do |filename|
6
- `bundle exec tt #{filename}`
7
- end
8
- end
9
-
10
- end