mail 2.4.4 → 2.5.5
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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +140 -1
- data/CONTRIBUTING.md +4 -4
- data/Gemfile +14 -8
- data/MIT-LICENSE +20 -0
- data/README.md +24 -23
- data/Rakefile +3 -22
- data/lib/VERSION +2 -2
- data/lib/load_parsers.rb +35 -0
- data/lib/mail/attachments_list.rb +2 -2
- data/lib/mail/body.rb +5 -5
- data/lib/mail/check_delivery_params.rb +57 -0
- data/lib/mail/configuration.rb +1 -1
- data/lib/mail/core_extensions/nil.rb +4 -2
- data/lib/mail/core_extensions/object.rb +8 -8
- data/lib/mail/core_extensions/smtp.rb +12 -13
- data/lib/mail/core_extensions/string.rb +4 -4
- data/lib/mail/elements/address.rb +13 -5
- data/lib/mail/elements/envelope_from_element.rb +15 -2
- data/lib/mail/elements.rb +12 -12
- data/lib/mail/encodings/quoted_printable.rb +4 -3
- data/lib/mail/encodings.rb +66 -35
- data/lib/mail/field.rb +76 -99
- data/lib/mail/fields/bcc_field.rb +2 -2
- data/lib/mail/fields/cc_field.rb +2 -2
- data/lib/mail/fields/comments_field.rb +1 -1
- data/lib/mail/fields/common/common_address.rb +19 -4
- data/lib/mail/fields/common/common_field.rb +8 -2
- data/lib/mail/fields/common/common_message_id.rb +9 -5
- data/lib/mail/fields/content_disposition_field.rb +1 -0
- data/lib/mail/fields/content_id_field.rb +1 -2
- data/lib/mail/fields/content_transfer_encoding_field.rb +2 -2
- data/lib/mail/fields/content_type_field.rb +5 -2
- data/lib/mail/fields/date_field.rb +14 -14
- data/lib/mail/fields/from_field.rb +2 -2
- data/lib/mail/fields/in_reply_to_field.rb +2 -1
- data/lib/mail/fields/keywords_field.rb +1 -1
- data/lib/mail/fields/message_id_field.rb +2 -3
- data/lib/mail/fields/references_field.rb +2 -1
- data/lib/mail/fields/reply_to_field.rb +2 -2
- data/lib/mail/fields/resent_bcc_field.rb +2 -2
- data/lib/mail/fields/resent_cc_field.rb +2 -2
- data/lib/mail/fields/resent_from_field.rb +2 -2
- data/lib/mail/fields/resent_sender_field.rb +2 -2
- data/lib/mail/fields/resent_to_field.rb +2 -2
- data/lib/mail/fields/sender_field.rb +7 -7
- data/lib/mail/fields/to_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +34 -27
- data/lib/mail/fields.rb +32 -32
- data/lib/mail/header.rb +37 -14
- data/lib/mail/message.rb +140 -45
- data/lib/mail/multibyte/chars.rb +4 -4
- data/lib/mail/multibyte/unicode.rb +8 -0
- data/lib/mail/network/delivery_methods/exim.rb +6 -11
- data/lib/mail/network/delivery_methods/file_delivery.rb +7 -6
- data/lib/mail/network/delivery_methods/sendmail.rb +40 -11
- data/lib/mail/network/delivery_methods/smtp.rb +33 -47
- data/lib/mail/network/delivery_methods/smtp_connection.rb +7 -24
- data/lib/mail/network/delivery_methods/test_mailer.rb +9 -8
- data/lib/mail/network/retriever_methods/imap.rb +14 -6
- data/lib/mail/network/retriever_methods/pop3.rb +2 -2
- data/lib/mail/network/retriever_methods/test_retriever.rb +11 -15
- data/lib/mail/network.rb +9 -9
- data/lib/mail/parsers/content_transfer_encoding.rb +81 -42
- data/lib/mail/parsers/content_transfer_encoding.treetop +4 -6
- data/lib/mail/parsers/content_type.rb +16 -12
- data/lib/mail/parsers/content_type.treetop +2 -2
- data/lib/mail/parsers/rfc2045.rb +12 -55
- data/lib/mail/parsers/rfc2045.treetop +1 -2
- data/lib/mail/parsers/rfc2822.rb +127 -71
- data/lib/mail/parsers/rfc2822.treetop +22 -24
- data/lib/mail/part.rb +6 -2
- data/lib/mail/parts_list.rb +1 -1
- data/lib/mail/patterns.rb +1 -1
- data/lib/mail/utilities.rb +25 -17
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version_specific/ruby_1_8.rb +23 -2
- data/lib/mail/version_specific/ruby_1_9.rb +55 -21
- data/lib/mail.rb +18 -18
- metadata +89 -37
- data/Gemfile.lock +0 -36
- data/lib/mail/core_extensions/shell_escape.rb +0 -56
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mail/check_delivery_params'
|
2
|
+
|
1
3
|
module Mail
|
2
4
|
# A delivery method implementation which sends via sendmail.
|
3
5
|
#
|
@@ -35,28 +37,55 @@ module Mail
|
|
35
37
|
#
|
36
38
|
# mail.deliver!
|
37
39
|
class Sendmail
|
40
|
+
DEFAULTS = {
|
41
|
+
:location => '/usr/sbin/sendmail',
|
42
|
+
:arguments => '-i'
|
43
|
+
}
|
44
|
+
|
45
|
+
attr_accessor :settings
|
38
46
|
|
39
47
|
def initialize(values)
|
40
|
-
self.settings =
|
41
|
-
:arguments => '-i -t' }.merge(values)
|
48
|
+
self.settings = self.class::DEFAULTS.merge(values)
|
42
49
|
end
|
43
50
|
|
44
|
-
attr_accessor :settings
|
45
|
-
|
46
51
|
def deliver!(mail)
|
47
|
-
|
48
|
-
return_path = "-f " + '"' + envelope_from.escape_for_shell + '"' if envelope_from
|
52
|
+
smtp_from, smtp_to, message = Mail::CheckDeliveryParams.check(mail)
|
49
53
|
|
50
|
-
|
54
|
+
from = "-f #{self.class.shellquote(smtp_from)}"
|
55
|
+
to = smtp_to.map { |to| self.class.shellquote(to) }.join(' ')
|
51
56
|
|
52
|
-
|
57
|
+
arguments = "#{settings[:arguments]} #{from} --"
|
58
|
+
self.class.call(settings[:location], arguments, to, message)
|
53
59
|
end
|
54
60
|
|
55
|
-
def self.call(path, arguments, destinations,
|
56
|
-
|
57
|
-
io.puts
|
61
|
+
def self.call(path, arguments, destinations, encoded_message)
|
62
|
+
popen "#{path} #{arguments} #{destinations}" do |io|
|
63
|
+
io.puts encoded_message.to_lf
|
58
64
|
io.flush
|
59
65
|
end
|
60
66
|
end
|
67
|
+
|
68
|
+
if RUBY_VERSION < '1.9.0'
|
69
|
+
def self.popen(command, &block)
|
70
|
+
IO.popen "#{command} 2>&1", 'w+', &block
|
71
|
+
end
|
72
|
+
else
|
73
|
+
def self.popen(command, &block)
|
74
|
+
IO.popen command, 'w+', :err => :out, &block
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# The following is an adaptation of ruby 1.9.2's shellwords.rb file,
|
79
|
+
# it is modified to include '+' in the allowed list to allow for
|
80
|
+
# sendmail to accept email addresses as the sender with a + in them.
|
81
|
+
def self.shellquote(address)
|
82
|
+
# Process as a single byte sequence because not all shell
|
83
|
+
# implementations are multibyte aware.
|
84
|
+
#
|
85
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
86
|
+
# combo is regarded as line continuation and simply ignored. Strip it.
|
87
|
+
escaped = address.gsub(/([^A-Za-z0-9_\s\+\-.,:\/@])/n, "\\\\\\1").gsub("\n", '')
|
88
|
+
%("#{escaped}")
|
89
|
+
end
|
61
90
|
end
|
62
91
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mail/check_delivery_params'
|
2
|
+
|
1
3
|
module Mail
|
2
4
|
# == Sending Email with SMTP
|
3
5
|
#
|
@@ -72,6 +74,7 @@ module Mail
|
|
72
74
|
#
|
73
75
|
# mail.deliver!
|
74
76
|
class SMTP
|
77
|
+
attr_accessor :settings
|
75
78
|
|
76
79
|
def initialize(values)
|
77
80
|
self.settings = { :address => "localhost",
|
@@ -86,68 +89,51 @@ module Mail
|
|
86
89
|
:tls => nil
|
87
90
|
}.merge!(values)
|
88
91
|
end
|
89
|
-
|
90
|
-
attr_accessor :settings
|
91
|
-
|
92
|
+
|
92
93
|
# Send the message via SMTP.
|
93
94
|
# The from and to attributes are optional. If not set, they are retrieve from the Message.
|
94
95
|
def deliver!(mail)
|
96
|
+
smtp_from, smtp_to, message = Mail::CheckDeliveryParams.check(mail)
|
95
97
|
|
96
|
-
# Set the envelope from to be either the return-path, the sender or the first from address
|
97
|
-
envelope_from = mail.return_path || mail.sender || mail.from_addrs.first
|
98
|
-
if envelope_from.blank?
|
99
|
-
raise ArgumentError.new('A sender (Return-Path, Sender or From) required to send a message')
|
100
|
-
end
|
101
|
-
|
102
|
-
destinations ||= mail.destinations if mail.respond_to?(:destinations) && mail.destinations
|
103
|
-
if destinations.blank?
|
104
|
-
raise ArgumentError.new('At least one recipient (To, Cc or Bcc) is required to send a message')
|
105
|
-
end
|
106
|
-
|
107
|
-
message ||= mail.encoded if mail.respond_to?(:encoded)
|
108
|
-
if message.blank?
|
109
|
-
raise ArgumentError.new('A encoded content is required to send a message')
|
110
|
-
end
|
111
|
-
|
112
98
|
smtp = Net::SMTP.new(settings[:address], settings[:port])
|
113
99
|
if settings[:tls] || settings[:ssl]
|
114
100
|
if smtp.respond_to?(:enable_tls)
|
115
|
-
|
116
|
-
smtp.enable_tls
|
117
|
-
else
|
118
|
-
openssl_verify_mode = settings[:openssl_verify_mode]
|
119
|
-
if openssl_verify_mode.kind_of?(String)
|
120
|
-
openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
|
121
|
-
end
|
122
|
-
context = Net::SMTP.default_ssl_context
|
123
|
-
context.verify_mode = openssl_verify_mode
|
124
|
-
smtp.enable_tls(context)
|
125
|
-
end
|
101
|
+
smtp.enable_tls(ssl_context)
|
126
102
|
end
|
127
103
|
elsif settings[:enable_starttls_auto]
|
128
|
-
if smtp.respond_to?(:enable_starttls_auto)
|
129
|
-
|
130
|
-
smtp.enable_starttls_auto
|
131
|
-
else
|
132
|
-
openssl_verify_mode = settings[:openssl_verify_mode]
|
133
|
-
if openssl_verify_mode.kind_of?(String)
|
134
|
-
openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
|
135
|
-
end
|
136
|
-
context = Net::SMTP.default_ssl_context
|
137
|
-
context.verify_mode = openssl_verify_mode
|
138
|
-
smtp.enable_starttls_auto(context)
|
139
|
-
end
|
104
|
+
if smtp.respond_to?(:enable_starttls_auto)
|
105
|
+
smtp.enable_starttls_auto(ssl_context)
|
140
106
|
end
|
141
107
|
end
|
142
|
-
|
108
|
+
|
143
109
|
response = nil
|
144
110
|
smtp.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication]) do |smtp_obj|
|
145
|
-
response = smtp_obj.sendmail(message,
|
111
|
+
response = smtp_obj.sendmail(message, smtp_from, smtp_to)
|
112
|
+
end
|
113
|
+
|
114
|
+
if settings[:return_response]
|
115
|
+
response
|
116
|
+
else
|
117
|
+
self
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
# Allow SSL context to be configured via settings, for Ruby >= 1.9
|
124
|
+
# Just returns openssl verify mode for Ruby 1.8.x
|
125
|
+
def ssl_context
|
126
|
+
openssl_verify_mode = settings[:openssl_verify_mode]
|
127
|
+
|
128
|
+
if openssl_verify_mode.kind_of?(String)
|
129
|
+
openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
|
146
130
|
end
|
147
131
|
|
148
|
-
|
132
|
+
context = Net::SMTP.default_ssl_context
|
133
|
+
context.verify_mode = openssl_verify_mode
|
134
|
+
context.ca_path = settings[:ca_path] if settings[:ca_path]
|
135
|
+
context.ca_file = settings[:ca_file] if settings[:ca_file]
|
136
|
+
context
|
149
137
|
end
|
150
|
-
|
151
|
-
|
152
138
|
end
|
153
139
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mail/check_delivery_params'
|
2
|
+
|
1
3
|
module Mail
|
2
4
|
# == Sending Email with SMTP
|
3
5
|
#
|
@@ -35,40 +37,21 @@ module Mail
|
|
35
37
|
#
|
36
38
|
# mail.deliver!
|
37
39
|
class SMTPConnection
|
40
|
+
attr_accessor :smtp, :settings
|
38
41
|
|
39
42
|
def initialize(values)
|
40
43
|
raise ArgumentError.new('A Net::SMTP object is required for this delivery method') if values[:connection].nil?
|
41
44
|
self.smtp = values[:connection]
|
42
45
|
self.settings = values
|
43
46
|
end
|
44
|
-
|
45
|
-
attr_accessor :smtp
|
46
|
-
attr_accessor :settings
|
47
|
-
|
47
|
+
|
48
48
|
# Send the message via SMTP.
|
49
49
|
# The from and to attributes are optional. If not set, they are retrieve from the Message.
|
50
50
|
def deliver!(mail)
|
51
|
+
smtp_from, smtp_to, message = Mail::CheckDeliveryParams.check(mail)
|
52
|
+
response = smtp.sendmail(message, smtp_from, smtp_to)
|
51
53
|
|
52
|
-
|
53
|
-
envelope_from = mail.return_path || mail.sender || mail.from_addrs.first
|
54
|
-
if envelope_from.blank?
|
55
|
-
raise ArgumentError.new('A sender (Return-Path, Sender or From) required to send a message')
|
56
|
-
end
|
57
|
-
|
58
|
-
destinations ||= mail.destinations if mail.respond_to?(:destinations) && mail.destinations
|
59
|
-
if destinations.blank?
|
60
|
-
raise ArgumentError.new('At least one recipient (To, Cc or Bcc) is required to send a message')
|
61
|
-
end
|
62
|
-
|
63
|
-
message ||= mail.encoded if mail.respond_to?(:encoded)
|
64
|
-
if message.blank?
|
65
|
-
raise ArgumentError.new('A encoded content is required to send a message')
|
66
|
-
end
|
67
|
-
|
68
|
-
response = smtp.sendmail(message, envelope_from, destinations)
|
69
|
-
|
70
|
-
settings[:return_response] ? response : self
|
54
|
+
settings[:return_response] ? response : self
|
71
55
|
end
|
72
|
-
|
73
56
|
end
|
74
57
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mail/check_delivery_params'
|
2
|
+
|
1
3
|
module Mail
|
2
4
|
# The TestMailer is a bare bones mailer that does nothing. It is useful
|
3
5
|
# when you are testing.
|
@@ -5,9 +7,8 @@ module Mail
|
|
5
7
|
# It also provides a template of the minimum methods you require to implement
|
6
8
|
# if you want to make a custom mailer for Mail
|
7
9
|
class TestMailer
|
8
|
-
|
9
10
|
# Provides a store of all the emails sent with the TestMailer so you can check them.
|
10
|
-
def
|
11
|
+
def self.deliveries
|
11
12
|
@@deliveries ||= []
|
12
13
|
end
|
13
14
|
|
@@ -22,19 +23,19 @@ module Mail
|
|
22
23
|
# * length
|
23
24
|
# * size
|
24
25
|
# * and other common Array methods
|
25
|
-
def
|
26
|
+
def self.deliveries=(val)
|
26
27
|
@@deliveries = val
|
27
28
|
end
|
28
29
|
|
30
|
+
attr_accessor :settings
|
31
|
+
|
29
32
|
def initialize(values)
|
30
|
-
@settings =
|
33
|
+
@settings = values.dup
|
31
34
|
end
|
32
|
-
|
33
|
-
attr_accessor :settings
|
34
35
|
|
35
36
|
def deliver!(mail)
|
37
|
+
Mail::CheckDeliveryParams.check(mail)
|
36
38
|
Mail::TestMailer.deliveries << mail
|
37
39
|
end
|
38
|
-
|
39
40
|
end
|
40
|
-
end
|
41
|
+
end
|
@@ -18,7 +18,7 @@ module Mail
|
|
18
18
|
#
|
19
19
|
# Mail.all #=> Returns an array of all emails
|
20
20
|
# Mail.first #=> Returns the first unread email
|
21
|
-
# Mail.last #=> Returns the
|
21
|
+
# Mail.last #=> Returns the last unread email
|
22
22
|
#
|
23
23
|
# You can also pass options into Mail.find to locate an email in your imap mailbox
|
24
24
|
# with the following options:
|
@@ -28,12 +28,15 @@ module Mail
|
|
28
28
|
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
29
29
|
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
30
30
|
# instance of Message, not an array of Message instances.
|
31
|
+
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
32
|
+
# or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
|
33
|
+
# The default is 'ALL'
|
31
34
|
#
|
32
|
-
# Mail.find(:what => :first, :count => 10, :order => :asc)
|
35
|
+
# Mail.find(:what => :first, :count => 10, :order => :asc, :keys=>'ALL')
|
33
36
|
# #=> Returns the first 10 emails in ascending order
|
34
37
|
#
|
35
38
|
class IMAP < Retriever
|
36
|
-
require 'net/imap'
|
39
|
+
require 'net/imap' unless defined?(Net::IMAP)
|
37
40
|
|
38
41
|
def initialize(values)
|
39
42
|
self.settings = { :address => "localhost",
|
@@ -54,16 +57,21 @@ module Mail
|
|
54
57
|
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
55
58
|
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
56
59
|
# instance of Message, not an array of Message instances.
|
57
|
-
#
|
58
|
-
#
|
60
|
+
# read_only: will ensure that no writes are made to the inbox during the session. Specifically, if this is
|
61
|
+
# set to true, the code will use the EXAMINE command to retrieve the mail. If set to false, which
|
62
|
+
# is the default, a SELECT command will be used to retrieve the mail
|
63
|
+
# This is helpful when you don't want your messages to be set to read automatically. Default is false.
|
59
64
|
# delete_after_find: flag for whether to delete each retreived email after find. Default
|
60
65
|
# is false. Use #find_and_delete if you would like this to default to true.
|
66
|
+
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
67
|
+
# or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
|
68
|
+
# The default is 'ALL'
|
61
69
|
#
|
62
70
|
def find(options={}, &block)
|
63
71
|
options = validate_options(options)
|
64
72
|
|
65
73
|
start do |imap|
|
66
|
-
options[:read_only] ? imap.
|
74
|
+
options[:read_only] ? imap.examine(options[:mailbox]) : imap.select(options[:mailbox])
|
67
75
|
|
68
76
|
message_ids = imap.uid_search(options[:keys])
|
69
77
|
message_ids.reverse! if options[:what].to_sym == :last
|
@@ -18,7 +18,7 @@ module Mail
|
|
18
18
|
#
|
19
19
|
# Mail.all #=> Returns an array of all emails
|
20
20
|
# Mail.first #=> Returns the first unread email
|
21
|
-
# Mail.last #=> Returns the
|
21
|
+
# Mail.last #=> Returns the last unread email
|
22
22
|
#
|
23
23
|
# You can also pass options into Mail.find to locate an email in your pop mailbox
|
24
24
|
# with the following options:
|
@@ -32,7 +32,7 @@ module Mail
|
|
32
32
|
# #=> Returns the first 10 emails in ascending order
|
33
33
|
#
|
34
34
|
class POP3 < Retriever
|
35
|
-
require 'net/pop'
|
35
|
+
require 'net/pop' unless defined?(Net::POP)
|
36
36
|
|
37
37
|
def initialize(values)
|
38
38
|
self.settings = { :address => "localhost",
|
@@ -20,26 +20,22 @@ module Mail
|
|
20
20
|
options[:count] ||= :all
|
21
21
|
options[:order] ||= :asc
|
22
22
|
options[:what] ||= :first
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
when :all then
|
27
|
-
when
|
28
|
-
when Fixnum then emails[0, count]
|
23
|
+
emails_index = (0...@@emails.size).to_a
|
24
|
+
emails_index.reverse! if options[:what] == :last
|
25
|
+
emails_index = case count = options[:count]
|
26
|
+
when :all then emails_index
|
27
|
+
when Fixnum then emails_index[0, count]
|
29
28
|
else
|
30
29
|
raise 'Invalid count option value: ' + count.inspect
|
31
30
|
end
|
32
31
|
if options[:what] == :last && options[:order] == :asc || options[:what] == :first && options[:order] == :desc
|
33
|
-
|
34
|
-
end
|
35
|
-
emails.each { |email| email.mark_for_delete = true } if options[:delete_after_find]
|
36
|
-
if block_given?
|
37
|
-
emails.each { |email| yield email }
|
38
|
-
else
|
39
|
-
emails
|
40
|
-
end.tap do |results|
|
41
|
-
emails.each { |email| @@emails.delete(email) if email.is_marked_for_delete? } if options[:delete_after_find]
|
32
|
+
emails_index.reverse!
|
42
33
|
end
|
34
|
+
emails_index.each { |idx| @@emails[idx].mark_for_delete = true } if options[:delete_after_find]
|
35
|
+
emails = emails_index.map { |idx| @@emails[idx] }
|
36
|
+
emails.each { |email| yield email } if block_given?
|
37
|
+
@@emails.reject!(&:is_marked_for_delete?) if options[:delete_after_find]
|
38
|
+
emails.size == 1 && options[:count] == 1 ? emails.first : emails
|
43
39
|
end
|
44
40
|
|
45
41
|
end
|
data/lib/mail/network.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'mail/network/retriever_methods/base'
|
2
2
|
|
3
3
|
module Mail
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
register_autoload :SMTP, 'mail/network/delivery_methods/smtp'
|
5
|
+
register_autoload :FileDelivery, 'mail/network/delivery_methods/file_delivery'
|
6
|
+
register_autoload :Sendmail, 'mail/network/delivery_methods/sendmail'
|
7
|
+
register_autoload :Exim, 'mail/network/delivery_methods/exim'
|
8
|
+
register_autoload :SMTPConnection, 'mail/network/delivery_methods/smtp_connection'
|
9
|
+
register_autoload :TestMailer, 'mail/network/delivery_methods/test_mailer'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
register_autoload :POP3, 'mail/network/retriever_methods/pop3'
|
12
|
+
register_autoload :IMAP, 'mail/network/retriever_methods/imap'
|
13
|
+
register_autoload :TestRetriever, 'mail/network/retriever_methods/test_retriever'
|
14
14
|
end
|
@@ -85,19 +85,6 @@ module Mail
|
|
85
85
|
r0
|
86
86
|
end
|
87
87
|
|
88
|
-
module Encoding0
|
89
|
-
def ietf_token
|
90
|
-
elements[0]
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
module Encoding1
|
96
|
-
def text_value
|
97
|
-
ietf_token.text_value
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
88
|
def _nt_encoding
|
102
89
|
start_index = index
|
103
90
|
if node_cache[:encoding].has_key?(index)
|
@@ -110,41 +97,93 @@ module Mail
|
|
110
97
|
end
|
111
98
|
|
112
99
|
i0 = index
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
if r2
|
117
|
-
if has_terminal?("s", false, index)
|
118
|
-
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
119
|
-
@index += 1
|
120
|
-
else
|
121
|
-
terminal_parse_failure("s")
|
122
|
-
r4 = nil
|
123
|
-
end
|
124
|
-
if r4
|
125
|
-
r3 = r4
|
126
|
-
else
|
127
|
-
r3 = instantiate_node(SyntaxNode,input, index...index)
|
128
|
-
end
|
129
|
-
s1 << r3
|
130
|
-
end
|
131
|
-
if s1.last
|
132
|
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
|
133
|
-
r1.extend(Encoding0)
|
134
|
-
r1.extend(Encoding1)
|
100
|
+
if has_terminal?("7bits", false, index)
|
101
|
+
r1 = instantiate_node(SyntaxNode,input, index...(index + 5))
|
102
|
+
@index += 5
|
135
103
|
else
|
136
|
-
|
104
|
+
terminal_parse_failure("7bits")
|
137
105
|
r1 = nil
|
138
106
|
end
|
139
107
|
if r1
|
140
108
|
r0 = r1
|
141
109
|
else
|
142
|
-
|
143
|
-
|
144
|
-
|
110
|
+
if has_terminal?("8bits", false, index)
|
111
|
+
r2 = instantiate_node(SyntaxNode,input, index...(index + 5))
|
112
|
+
@index += 5
|
113
|
+
else
|
114
|
+
terminal_parse_failure("8bits")
|
115
|
+
r2 = nil
|
116
|
+
end
|
117
|
+
if r2
|
118
|
+
r0 = r2
|
145
119
|
else
|
146
|
-
|
147
|
-
|
120
|
+
if has_terminal?("7bit", false, index)
|
121
|
+
r3 = instantiate_node(SyntaxNode,input, index...(index + 4))
|
122
|
+
@index += 4
|
123
|
+
else
|
124
|
+
terminal_parse_failure("7bit")
|
125
|
+
r3 = nil
|
126
|
+
end
|
127
|
+
if r3
|
128
|
+
r0 = r3
|
129
|
+
else
|
130
|
+
if has_terminal?("8bit", false, index)
|
131
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 4))
|
132
|
+
@index += 4
|
133
|
+
else
|
134
|
+
terminal_parse_failure("8bit")
|
135
|
+
r4 = nil
|
136
|
+
end
|
137
|
+
if r4
|
138
|
+
r0 = r4
|
139
|
+
else
|
140
|
+
if has_terminal?("binary", false, index)
|
141
|
+
r5 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
142
|
+
@index += 6
|
143
|
+
else
|
144
|
+
terminal_parse_failure("binary")
|
145
|
+
r5 = nil
|
146
|
+
end
|
147
|
+
if r5
|
148
|
+
r0 = r5
|
149
|
+
else
|
150
|
+
if has_terminal?("quoted-printable", false, index)
|
151
|
+
r6 = instantiate_node(SyntaxNode,input, index...(index + 16))
|
152
|
+
@index += 16
|
153
|
+
else
|
154
|
+
terminal_parse_failure("quoted-printable")
|
155
|
+
r6 = nil
|
156
|
+
end
|
157
|
+
if r6
|
158
|
+
r0 = r6
|
159
|
+
else
|
160
|
+
if has_terminal?("base64", false, index)
|
161
|
+
r7 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
162
|
+
@index += 6
|
163
|
+
else
|
164
|
+
terminal_parse_failure("base64")
|
165
|
+
r7 = nil
|
166
|
+
end
|
167
|
+
if r7
|
168
|
+
r0 = r7
|
169
|
+
else
|
170
|
+
r8 = _nt_ietf_token
|
171
|
+
if r8
|
172
|
+
r0 = r8
|
173
|
+
else
|
174
|
+
r9 = _nt_custom_x_token
|
175
|
+
if r9
|
176
|
+
r0 = r9
|
177
|
+
else
|
178
|
+
@index = i0
|
179
|
+
r0 = nil
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
148
187
|
end
|
149
188
|
end
|
150
189
|
|
@@ -159,4 +198,4 @@ module Mail
|
|
159
198
|
include ContentTransferEncoding
|
160
199
|
end
|
161
200
|
|
162
|
-
end
|
201
|
+
end
|
@@ -9,12 +9,10 @@ module Mail
|
|
9
9
|
end
|
10
10
|
|
11
11
|
rule encoding
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
} / custom_x_token
|
12
|
+
"7bits" / "8bits" /
|
13
|
+
"7bit" / "8bit" / "binary" / "quoted-printable" / "base64" /
|
14
|
+
ietf_token / custom_x_token
|
17
15
|
end
|
18
16
|
|
19
17
|
end
|
20
|
-
end
|
18
|
+
end
|
@@ -82,18 +82,22 @@ module Mail
|
|
82
82
|
r6 = _nt_CFWS
|
83
83
|
s5 << r6
|
84
84
|
if r6
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
85
|
+
s7, i7 = [], index
|
86
|
+
loop do
|
87
|
+
if has_terminal?(";", false, index)
|
88
|
+
r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
89
|
+
@index += 1
|
90
|
+
else
|
91
|
+
terminal_parse_failure(";")
|
92
|
+
r8 = nil
|
93
|
+
end
|
94
|
+
if r8
|
95
|
+
s7 << r8
|
96
|
+
else
|
97
|
+
break
|
98
|
+
end
|
96
99
|
end
|
100
|
+
r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
|
97
101
|
s5 << r7
|
98
102
|
if r7
|
99
103
|
r9 = _nt_parameter
|
@@ -964,4 +968,4 @@ module Mail
|
|
964
968
|
include ContentType
|
965
969
|
end
|
966
970
|
|
967
|
-
end
|
971
|
+
end
|
@@ -5,7 +5,7 @@ module Mail
|
|
5
5
|
include RFC2045
|
6
6
|
|
7
7
|
rule content_type
|
8
|
-
main_type "/" sub_type param_hashes:(CFWS ";"
|
8
|
+
main_type "/" sub_type param_hashes:(CFWS ";"* parameter CFWS)* {
|
9
9
|
def parameters
|
10
10
|
param_hashes.elements.map do |param|
|
11
11
|
param.parameter.param_hash
|
@@ -65,4 +65,4 @@ module Mail
|
|
65
65
|
end
|
66
66
|
|
67
67
|
end
|
68
|
-
end
|
68
|
+
end
|