mail 1.5.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mail might be problematic. Click here for more details.
- data/CHANGELOG.rdoc +25 -0
- data/README.rdoc +16 -0
- data/Rakefile +1 -2
- data/lib/mail.rb +8 -1
- data/lib/mail/fields/content_type_field.rb +52 -6
- data/lib/mail/fields/return_path_field.rb +9 -1
- data/lib/mail/message.rb +2 -2
- data/lib/mail/network/delivery_methods/sendmail.rb +3 -1
- data/lib/mail/network/delivery_methods/smtp.rb +9 -8
- data/lib/mail/network/retriever_methods/pop3.rb +1 -0
- data/lib/mail/version.rb +1 -1
- data/lib/tasks/corpus.rake +1 -1
- metadata +2 -2
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
== Fri 8 Jan 2010 00:00:08 UTC Mikel Lindsaar <raasdnil@gmail.com>
|
2
|
+
|
3
|
+
* Version bump to 1.5.2
|
4
|
+
|
5
|
+
== Fri 8 Jan 8:55:49 2010 +1100 Mikel Lindsaar <raasdnil@gmail.com>
|
6
|
+
|
7
|
+
* Updated Sendmail and SMTP delivery methods to use return-path if present
|
8
|
+
* Fix up a lot of content-type parsing problems
|
9
|
+
* Updating compat listing
|
10
|
+
* Moving error emails into one directory
|
11
|
+
* Moving error emails into one directory
|
12
|
+
* Initializing @tls variable to remove warnings
|
13
|
+
* Moved default corpus directory
|
14
|
+
* Fixed up git ignore file
|
15
|
+
|
16
|
+
== Thu 6 Jan 2010 23:59:29 UTC Mikel Lindsaar <raasdnil@gmail.com>
|
17
|
+
|
18
|
+
* Added compatibility list to Readme.rdoc
|
19
|
+
* Fixing encoding of return path to be per RFC 2822, adding angle brackets around the addr_spec
|
20
|
+
* Specs covering return path setting and preserving
|
21
|
+
|
22
|
+
== Thu 5 Jan 2010 23:59:48 UTC Mikel Lindsaar <raasdnil@gmail.com>
|
23
|
+
|
24
|
+
* Moving the require for tlsmail for Ruby 1.8.6 into mail.rb
|
25
|
+
|
1
26
|
== Sun Jan 3 00:08:06 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
2
27
|
|
3
28
|
* Version bump to 1.5.0
|
data/README.rdoc
CHANGED
@@ -23,6 +23,22 @@ Finally, Mail has been designed with a very simple object oriented system
|
|
23
23
|
that really opens up the email messages you are parsing, if you know what
|
24
24
|
you are doing, you can fiddle with every last bit of your email directly.
|
25
25
|
|
26
|
+
== Compatibility
|
27
|
+
|
28
|
+
Mail is tested and works on the following platforms:
|
29
|
+
|
30
|
+
* ree-1.8.7-2009.10 [ x86_64 ]
|
31
|
+
* ruby-1.8.6-p383 [ x86_64 ]
|
32
|
+
* ruby-1.8.7-p248 [ x86_64 ]
|
33
|
+
* ruby-1.9.1-head [ x86_64 ]
|
34
|
+
* ruby-1.9.1-p376 [ x86_64 ]
|
35
|
+
|
36
|
+
Mail seems to work fine on JRuby as well, however, the Base64 and Quoted-Printable
|
37
|
+
encoding methods are implemented differently and return different values so 6
|
38
|
+
specs fail. This needs to be triple checked if all OK.
|
39
|
+
|
40
|
+
* jruby-1.4.0 [x86_64-java]
|
41
|
+
|
26
42
|
== Discussion
|
27
43
|
|
28
44
|
If you want to discuss mail with like minded individuals, please subscribe to
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ require 'bundler'
|
|
12
12
|
|
13
13
|
spec = Gem::Specification.new do |s|
|
14
14
|
s.name = "mail"
|
15
|
-
s.version = "1.5.
|
15
|
+
s.version = "1.5.2"
|
16
16
|
s.author = "Mike Lindsaar"
|
17
17
|
s.email = "raasdnil@gmail.com"
|
18
18
|
s.homepage = "http://github.com/mikel/mail"
|
@@ -23,7 +23,6 @@ spec = Gem::Specification.new do |s|
|
|
23
23
|
s.has_rdoc = true
|
24
24
|
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "TODO.rdoc"]
|
25
25
|
|
26
|
-
s.add_dependency('tlsmail') if RUBY_VERSION <= '1.8.6'
|
27
26
|
s.add_dependency('activesupport', ">= 2.3.4")
|
28
27
|
s.add_dependency('mime-types')
|
29
28
|
|
data/lib/mail.rb
CHANGED
@@ -15,7 +15,14 @@ module Mail # :doc:
|
|
15
15
|
require 'uri'
|
16
16
|
require 'net/smtp'
|
17
17
|
require 'mime/types'
|
18
|
-
|
18
|
+
|
19
|
+
if RUBY_VERSION <= '1.8.6'
|
20
|
+
begin
|
21
|
+
require 'tlsmail'
|
22
|
+
rescue LoadError
|
23
|
+
raise "You need to install tlsmail if you are using ruby <= 1.8.6"
|
24
|
+
end
|
25
|
+
end
|
19
26
|
|
20
27
|
if RUBY_VERSION >= "1.9.1"
|
21
28
|
require 'mail/version_specific/ruby_1_9.rb'
|
@@ -28,9 +28,19 @@ module Mail
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def element
|
31
|
-
|
32
|
-
|
31
|
+
begin
|
32
|
+
@element ||= Mail::ContentTypeElement.new(value)
|
33
|
+
rescue
|
34
|
+
attempt_to_clean
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def attempt_to_clean
|
39
|
+
# Sanitize the value, handle special cases
|
33
40
|
@element ||= Mail::ContentTypeElement.new(sanatize(value))
|
41
|
+
rescue
|
42
|
+
# All else fails, just get the mime type
|
43
|
+
@element ||= Mail::ContentTypeElement.new(get_mime_type(value))
|
34
44
|
end
|
35
45
|
|
36
46
|
def main_type
|
@@ -111,14 +121,50 @@ module Mail
|
|
111
121
|
end
|
112
122
|
end
|
113
123
|
|
124
|
+
# Various special cases from random emails found that I am not going to change
|
125
|
+
# the parser for
|
114
126
|
def sanatize( val )
|
115
127
|
case
|
116
|
-
when val.chomp =~
|
128
|
+
when val.chomp =~ /^\s*([\w\d\-_]+)\/([\w\d\-_]+)\s*;;+(.*)$/i
|
129
|
+
# Handles 'text/plain;; format="flowed"' (double semi colon)
|
130
|
+
"#{$1}/#{$2}; #{$3}"
|
131
|
+
when val.chomp =~ /^\s*([\w\d\-_]+)\/([\w\d\-_]+)\s*;(ISO[\w\d\-_]+)$/i
|
132
|
+
# Microsoft helper:
|
133
|
+
# Handles 'mime/type;ISO-8559-1'
|
134
|
+
"#{$1}/#{$2}; charset=#{quote_atom($3)}"
|
135
|
+
when val.chomp =~ /^text;?$/i
|
136
|
+
# Handles 'text;' and 'text'
|
137
|
+
"text/plain;"
|
138
|
+
when val.chomp =~ /^(\w+);\s(.*)$/i
|
139
|
+
# Handles 'text; <parameters>'
|
140
|
+
"text/plain; #{$2}"
|
141
|
+
when val =~ /([\w\d\-_]+\/[\w\d\-_]+);\scharset="charset="(\w+)""/i
|
142
|
+
# Handles text/html; charset="charset="GB2312""
|
143
|
+
"#{$1}; charset=#{quote_atom($2)}"
|
144
|
+
when val =~ /([\w\d\-_]+\/[\w\d\-_]+);\s+(.*)/i
|
145
|
+
type = $1
|
146
|
+
# Handles misquoted param values
|
147
|
+
# e.g: application/octet-stream; name=archiveshelp1[1].htm
|
148
|
+
# and: audio/x-midi;\r\n\tname=Part .exe
|
149
|
+
params = $2.to_s.split(/\s+/)
|
150
|
+
params = params.map { |i| i.to_s.chomp.strip }
|
151
|
+
params = params.map { |i| i.split(/\s*\=\s*/) }
|
152
|
+
params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s)}" }.join('; ')
|
153
|
+
"#{type}; #{params}"
|
154
|
+
when val =~ /^\s*$/
|
155
|
+
'text/plain'
|
156
|
+
else
|
157
|
+
''
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def get_mime_type( val )
|
162
|
+
case
|
163
|
+
when val =~ /^([\w\d\-_]+)\/([\w\d\-_]+);.+$/i
|
164
|
+
"#{$1}/#{$2}"
|
165
|
+
else
|
117
166
|
'text/plain'
|
118
|
-
when val =~ /([\w\d_]+\/[\w\d_]+)\s(.*)/
|
119
|
-
"#{$1}; #{$2}"
|
120
167
|
end
|
121
168
|
end
|
122
|
-
|
123
169
|
end
|
124
170
|
end
|
@@ -1,5 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
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
|
+
#
|
3
11
|
# trace = [return]
|
4
12
|
# 1*received
|
5
13
|
#
|
@@ -32,7 +40,7 @@ module Mail
|
|
32
40
|
end
|
33
41
|
|
34
42
|
def encoded
|
35
|
-
|
43
|
+
"#{CAPITALIZED_FIELD}: <#{address}>\r\n"
|
36
44
|
end
|
37
45
|
|
38
46
|
def decoded
|
data/lib/mail/message.rb
CHANGED
@@ -1032,7 +1032,7 @@ module Mail
|
|
1032
1032
|
end
|
1033
1033
|
|
1034
1034
|
def has_content_type?
|
1035
|
-
!!content_type
|
1035
|
+
!!header[:content_type]
|
1036
1036
|
end
|
1037
1037
|
|
1038
1038
|
def has_charset?
|
@@ -1169,7 +1169,7 @@ module Mail
|
|
1169
1169
|
|
1170
1170
|
# Returns true if the message is multipart
|
1171
1171
|
def multipart?
|
1172
|
-
!!(main_type =~ /^multipart$/i)
|
1172
|
+
has_content_type? ? !!(main_type =~ /^multipart$/i) : false
|
1173
1173
|
end
|
1174
1174
|
|
1175
1175
|
# Returns true if the message is a multipart/report
|
@@ -14,8 +14,10 @@ module Mail
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def Sendmail.deliver!(mail)
|
17
|
-
|
17
|
+
mail.return_path ? return_path = "-f \"#{mail.return_path}\"" : reply_to = ''
|
18
|
+
IO.popen("#{Mail.defaults.sendmail.path} #{return_path} #{mail.destinations.join(" ")}", "w+") do |io|
|
18
19
|
io.puts mail.to_s
|
20
|
+
io.flush
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -5,6 +5,7 @@ module Mail
|
|
5
5
|
def initialize
|
6
6
|
@user = nil
|
7
7
|
@pass = nil
|
8
|
+
@tls = false
|
8
9
|
end
|
9
10
|
|
10
11
|
def settings(&block)
|
@@ -61,13 +62,13 @@ module Mail
|
|
61
62
|
|
62
63
|
config = Mail.defaults
|
63
64
|
|
64
|
-
#
|
65
|
-
|
66
|
-
raise ArgumentError.new('An
|
67
|
-
|
68
|
-
raise ArgumentError.new('At least one recipient
|
69
|
-
|
70
|
-
raise ArgumentError.new('A encoded content is required to send a message') if
|
65
|
+
# Set the envelope from to be either the return-path, the sender or the first from address
|
66
|
+
envelope_from = mail.return_path || mail.sender || mail.from_addrs.first
|
67
|
+
raise ArgumentError.new('An sender (Return-Path, Sender or From) required to send a message') if envelope_from.blank?
|
68
|
+
destinations ||= mail.destinations if mail.respond_to?(:destinations) && mail.destinations
|
69
|
+
raise ArgumentError.new('At least one recipient (To, Cc or Bcc) is required to send a message') if destinations.blank?
|
70
|
+
message ||= mail.encoded if mail.respond_to?(:encoded)
|
71
|
+
raise ArgumentError.new('A encoded content is required to send a message') if message.blank?
|
71
72
|
|
72
73
|
smtp = Net::SMTP.new(config.smtp.host, config.smtp.port)
|
73
74
|
if config.smtp.tls?
|
@@ -81,7 +82,7 @@ module Mail
|
|
81
82
|
end
|
82
83
|
|
83
84
|
smtp.start(config.smtp.helo, config.smtp.user, config.smtp.pass, authentication = :plain) do |smtp|
|
84
|
-
smtp.sendmail(
|
85
|
+
smtp.sendmail(message, envelope_from, destinations)
|
85
86
|
end
|
86
87
|
|
87
88
|
self
|
data/lib/mail/version.rb
CHANGED
data/lib/tasks/corpus.rake
CHANGED
@@ -10,7 +10,7 @@ namespace :corpus do
|
|
10
10
|
desc "Provide a LOCATION=/some/dir to verify parsing in bulk, otherwise defaults"
|
11
11
|
task :verify_all => :load_mail do
|
12
12
|
|
13
|
-
root_of_corpus = ENV['LOCATION'] || '
|
13
|
+
root_of_corpus = ENV['LOCATION'] || 'corpus/spam'
|
14
14
|
@save_failures_to = ENV['SAVE_TO'] || 'spec/fixtures/emails/failed_emails'
|
15
15
|
@failed_emails = []
|
16
16
|
@checked_count = 0
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Lindsaar
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-08 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|