mail 2.8.1 → 2.9.0.beta1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -31
  3. data/lib/mail/attachments_list.rb +3 -1
  4. data/lib/mail/body.rb +28 -28
  5. data/lib/mail/encodings/quoted_printable.rb +1 -1
  6. data/lib/mail/encodings/unix_to_unix.rb +1 -1
  7. data/lib/mail/encodings.rb +2 -2
  8. data/lib/mail/field.rb +65 -35
  9. data/lib/mail/field_list.rb +1 -1
  10. data/lib/mail/fields/bcc_field.rb +0 -1
  11. data/lib/mail/fields/cc_field.rb +0 -1
  12. data/lib/mail/fields/comments_field.rb +0 -1
  13. data/lib/mail/fields/common_address_field.rb +9 -17
  14. data/lib/mail/fields/common_date_field.rb +0 -2
  15. data/lib/mail/fields/common_message_id_field.rb +0 -1
  16. data/lib/mail/fields/content_description_field.rb +0 -1
  17. data/lib/mail/fields/content_disposition_field.rb +0 -2
  18. data/lib/mail/fields/content_id_field.rb +0 -1
  19. data/lib/mail/fields/content_location_field.rb +0 -1
  20. data/lib/mail/fields/content_transfer_encoding_field.rb +0 -1
  21. data/lib/mail/fields/content_type_field.rb +5 -6
  22. data/lib/mail/fields/date_field.rb +0 -1
  23. data/lib/mail/fields/from_field.rb +0 -1
  24. data/lib/mail/fields/in_reply_to_field.rb +0 -1
  25. data/lib/mail/fields/keywords_field.rb +0 -1
  26. data/lib/mail/fields/message_id_field.rb +0 -1
  27. data/lib/mail/fields/mime_version_field.rb +1 -2
  28. data/lib/mail/fields/named_structured_field.rb +0 -1
  29. data/lib/mail/fields/named_unstructured_field.rb +0 -1
  30. data/lib/mail/fields/optional_field.rb +0 -1
  31. data/lib/mail/fields/received_field.rb +0 -1
  32. data/lib/mail/fields/references_field.rb +0 -1
  33. data/lib/mail/fields/reply_to_field.rb +0 -1
  34. data/lib/mail/fields/resent_bcc_field.rb +0 -1
  35. data/lib/mail/fields/resent_cc_field.rb +0 -1
  36. data/lib/mail/fields/resent_date_field.rb +0 -1
  37. data/lib/mail/fields/resent_from_field.rb +0 -1
  38. data/lib/mail/fields/resent_message_id_field.rb +0 -1
  39. data/lib/mail/fields/resent_sender_field.rb +0 -1
  40. data/lib/mail/fields/resent_to_field.rb +0 -1
  41. data/lib/mail/fields/return_path_field.rb +0 -1
  42. data/lib/mail/fields/sender_field.rb +0 -1
  43. data/lib/mail/fields/structured_field.rb +0 -1
  44. data/lib/mail/fields/subject_field.rb +0 -1
  45. data/lib/mail/fields/to_field.rb +0 -1
  46. data/lib/mail/fields/unstructured_field.rb +0 -1
  47. data/lib/mail/fields.rb +9 -0
  48. data/lib/mail/header.rb +1 -1
  49. data/lib/mail/mail.rb +32 -27
  50. data/lib/mail/message.rb +22 -19
  51. data/lib/mail/multibyte/chars.rb +1 -1
  52. data/lib/mail/multibyte/unicode.rb +1 -1
  53. data/lib/mail/network/delivery_methods/file_delivery.rb +2 -2
  54. data/lib/mail/network/delivery_methods/sendmail.rb +2 -48
  55. data/lib/mail/network/delivery_methods/smtp.rb +77 -42
  56. data/lib/mail/network/delivery_methods/smtp_connection.rb +7 -7
  57. data/lib/mail/network/delivery_methods/test_mailer.rb +4 -4
  58. data/lib/mail/network/retriever_methods/base.rb +5 -5
  59. data/lib/mail/network/retriever_methods/imap.rb +6 -3
  60. data/lib/mail/network/retriever_methods/pop3.rb +20 -20
  61. data/lib/mail/parsers/address_lists_parser.rb +8 -5
  62. data/lib/mail/parsers/address_lists_parser.rl +4 -0
  63. data/lib/mail/parsers/content_disposition_parser.rb +15 -12
  64. data/lib/mail/parsers/content_disposition_parser.rl +4 -0
  65. data/lib/mail/parsers/content_location_parser.rb +9 -6
  66. data/lib/mail/parsers/content_location_parser.rl +5 -1
  67. data/lib/mail/parsers/content_transfer_encoding_parser.rb +8 -5
  68. data/lib/mail/parsers/content_transfer_encoding_parser.rl +4 -0
  69. data/lib/mail/parsers/content_type_parser.rb +15 -12
  70. data/lib/mail/parsers/content_type_parser.rl +4 -0
  71. data/lib/mail/parsers/date_time_parser.rb +8 -5
  72. data/lib/mail/parsers/date_time_parser.rl +4 -0
  73. data/lib/mail/parsers/envelope_from_parser.rb +8 -5
  74. data/lib/mail/parsers/envelope_from_parser.rl +4 -0
  75. data/lib/mail/parsers/message_ids_parser.rb +8 -5
  76. data/lib/mail/parsers/message_ids_parser.rl +4 -0
  77. data/lib/mail/parsers/mime_version_parser.rb +8 -5
  78. data/lib/mail/parsers/mime_version_parser.rl +4 -0
  79. data/lib/mail/parsers/phrase_lists_parser.rb +8 -5
  80. data/lib/mail/parsers/phrase_lists_parser.rl +4 -0
  81. data/lib/mail/parsers/received_parser.rb +8 -5
  82. data/lib/mail/parsers/received_parser.rl +4 -0
  83. data/lib/mail/part.rb +19 -19
  84. data/lib/mail/smtp_envelope.rb +1 -1
  85. data/lib/mail/utilities.rb +5 -5
  86. data/lib/mail/version.rb +3 -3
  87. data/lib/mail.rb +2 -5
  88. metadata +3 -4
  89. data/lib/mail/check_delivery_params.rb +0 -65
@@ -49,12 +49,8 @@ module Mail
49
49
  end
50
50
 
51
51
  def initialize(values)
52
- if values[:arguments].is_a?(String)
53
- deprecation_warn.call \
54
- 'Initializing Mail::Sendmail with :arguments of type String is deprecated.' \
55
- ' Instead ensure :arguments is an array of strings, e.g. ["-i", "-t"]'
56
- end
57
52
  self.settings = self.class::DEFAULTS.merge(values)
53
+ raise ArgumentError, ":arguments expected to be an Array of individual string args" if settings[:arguments].is_a?(String)
58
54
  end
59
55
 
60
56
  def destinations_for(envelope)
@@ -64,13 +60,8 @@ module Mail
64
60
  def deliver!(mail)
65
61
  envelope = Mail::SmtpEnvelope.new(mail)
66
62
 
67
- arguments = settings[:arguments]
68
- if arguments.is_a? String
69
- return old_deliver(envelope)
70
- end
71
-
72
63
  command = [settings[:location]]
73
- command.concat Array(arguments)
64
+ command.concat Array(settings[:arguments])
74
65
  command.concat [ '-f', envelope.from ] if envelope.from
75
66
 
76
67
  if destinations = destinations_for(envelope)
@@ -92,42 +83,5 @@ module Mail
92
83
  end
93
84
  end
94
85
  end
95
-
96
- #+ support for delivery using string arguments (deprecated)
97
- def old_deliver(envelope)
98
- smtp_from = envelope.from
99
- smtp_to = destinations_for(envelope)
100
-
101
- from = "-f #{shellquote(smtp_from)}" if smtp_from
102
- destination = smtp_to.map { |to| shellquote(to) }.join(' ')
103
-
104
- arguments = "#{settings[:arguments]} #{from} --"
105
- command = "#{settings[:location]} #{arguments} #{destination}"
106
- popen command do |io|
107
- io.puts ::Mail::Utilities.binary_unsafe_to_lf(envelope.message)
108
- io.flush
109
- end
110
- end
111
-
112
- # The following is an adaptation of ruby 1.9.2's shellwords.rb file,
113
- # with the following modifications:
114
- #
115
- # - Wraps in double quotes
116
- # - Allows '+' to accept email addresses with them
117
- # - Allows '~' as it is not unescaped in double quotes
118
- def shellquote(address)
119
- # Process as a single byte sequence because not all shell
120
- # implementations are multibyte aware.
121
- #
122
- # A LF cannot be escaped with a backslash because a backslash + LF
123
- # combo is regarded as line continuation and simply ignored. Strip it.
124
- escaped = address.gsub(/([^A-Za-z0-9_\s\+\-.,:\/@~])/n, "\\\\\\1").gsub("\n", '')
125
- %("#{escaped}")
126
- end
127
- #- support for delivery using string arguments
128
-
129
- def deprecation_warn
130
- defined?(ActiveSupport::Deprecation.warn) ? ActiveSupport::Deprecation.method(:warn) : Kernel.method(:warn)
131
- end
132
86
  end
133
87
  end
@@ -3,18 +3,18 @@ require 'mail/smtp_envelope'
3
3
 
4
4
  module Mail
5
5
  # == Sending Email with SMTP
6
- #
6
+ #
7
7
  # Mail allows you to send emails using SMTP. This is done by wrapping Net::SMTP in
8
8
  # an easy to use manner.
9
- #
9
+ #
10
10
  # === Sending via SMTP server on Localhost
11
- #
11
+ #
12
12
  # Sending locally (to a postfix or sendmail server running on localhost) requires
13
13
  # no special setup. Just to Mail.deliver &block or message.deliver! and it will
14
14
  # be sent in this method.
15
- #
15
+ #
16
16
  # === Sending via MobileMe
17
- #
17
+ #
18
18
  # Mail.defaults do
19
19
  # delivery_method :smtp, { :address => "smtp.me.com",
20
20
  # :port => 587,
@@ -22,11 +22,11 @@ module Mail
22
22
  # :user_name => '<username>',
23
23
  # :password => '<password>',
24
24
  # :authentication => 'plain',
25
- # :enable_starttls_auto => true }
25
+ # :enable_starttls => :auto }
26
26
  # end
27
- #
27
+ #
28
28
  # === Sending via GMail
29
- #
29
+ #
30
30
  # Mail.defaults do
31
31
  # delivery_method :smtp, { :address => "smtp.gmail.com",
32
32
  # :port => 587,
@@ -34,9 +34,17 @@ module Mail
34
34
  # :user_name => '<username>',
35
35
  # :password => '<password>',
36
36
  # :authentication => 'plain',
37
- # :enable_starttls_auto => true }
37
+ # :enable_starttls => :auto }
38
38
  # end
39
39
  #
40
+ # === Configuring TLS/SSL and STARTTLS
41
+ #
42
+ # A few remarks:
43
+ # - when enabling `tls` (or `ssl`), setting (truthy values for) either `enable_starttls` or `enable_starttls_auto` will raise an ArgumentError as TLS and STARTTLS are mutually exclusive.
44
+ # - to configure STARTTLS, use the `enable_starttls`-flag (instead of a combination of `enable_starttls` and `enable_starttls_auto`). Acceptable values are `:always`, `:auto` and `false`.
45
+ # - when providing a truthy value for `enable_starttls`, the `enable_starttls_auto`-flag will be ignored.
46
+ # - when none of `tls`, `ssl`, `enable_starttls` or `enable_starttls_auto` is set, the fallback will be `enable_starttls` `:auto`.
47
+ #
40
48
  # === Certificate verification
41
49
  #
42
50
  # When using TLS, some mail servers provide certificates that are self-signed
@@ -48,30 +56,30 @@ module Mail
48
56
  # verify mode constant (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER),
49
57
  # or a string containing the name of an OpenSSL verify mode (none, peer).
50
58
  #
51
- # === Others
52
- #
59
+ # === Others
60
+ #
53
61
  # Feel free to send me other examples that were tricky
54
- #
62
+ #
55
63
  # === Delivering the email
56
- #
64
+ #
57
65
  # Once you have the settings right, sending the email is done by:
58
- #
66
+ #
59
67
  # Mail.deliver do
60
68
  # to 'mikel@test.lindsaar.net'
61
69
  # from 'ada@test.lindsaar.net'
62
70
  # subject 'testing sendmail'
63
71
  # body 'testing sendmail'
64
72
  # end
65
- #
73
+ #
66
74
  # Or by calling deliver on a Mail message
67
- #
75
+ #
68
76
  # mail = Mail.new do
69
77
  # to 'mikel@test.lindsaar.net'
70
78
  # from 'ada@test.lindsaar.net'
71
79
  # subject 'testing sendmail'
72
80
  # body 'testing sendmail'
73
81
  # end
74
- #
82
+ #
75
83
  # mail.deliver!
76
84
  class SMTP
77
85
  attr_accessor :settings
@@ -84,7 +92,7 @@ module Mail
84
92
  :password => nil,
85
93
  :authentication => nil,
86
94
  :enable_starttls => nil,
87
- :enable_starttls_auto => true,
95
+ :enable_starttls_auto => nil,
88
96
  :openssl_verify_mode => nil,
89
97
  :ssl => nil,
90
98
  :tls => nil,
@@ -105,39 +113,66 @@ module Mail
105
113
  end
106
114
 
107
115
  private
116
+ # `k` is said to be provided when `settings` has a non-nil value for `k`.
117
+ def setting_provided?(k)
118
+ !settings[k].nil?
119
+ end
120
+
121
+ # Yields one of `:always`, `:auto` or `false` based on `enable_starttls` and `enable_starttls_auto` flags.
122
+ # Yields `false` when `smtp_tls?`.
123
+ # Else defaults to `:auto` when neither `enable_starttls*` flag is provided.
124
+ # Providing a truthy value for `enable_starttls` will ignore `enable_starttls_auto`.
125
+ def smtp_starttls
126
+ return false if smtp_tls?
127
+
128
+ if setting_provided?(:enable_starttls) && settings[:enable_starttls]
129
+ # enable_starttls: provided and truthy
130
+ case settings[:enable_starttls]
131
+ when :auto then :auto
132
+ when :always then :always
133
+ else
134
+ :always
135
+ end
136
+ else
137
+ # enable_starttls: not provided or false
138
+ if setting_provided?(:enable_starttls_auto)
139
+ settings[:enable_starttls_auto] ? :auto : false
140
+ else
141
+ # enable_starttls_auto: not provided
142
+ # enable_starttls: when provided then false
143
+ # use :auto when neither enable_starttls* provided
144
+ setting_provided?(:enable_starttls) ? false : :auto
145
+ end
146
+ end
147
+ end
148
+
149
+ def smtp_tls?
150
+ (setting_provided?(:tls) && settings[:tls]) || (setting_provided?(:ssl) && settings[:ssl])
151
+ end
152
+
108
153
  def start_smtp_session(&block)
109
154
  build_smtp_session.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication], &block)
110
155
  end
111
156
 
112
157
  def build_smtp_session
158
+ if smtp_tls? && (settings[:enable_starttls] || settings[:enable_starttls_auto])
159
+ raise ArgumentError, ":enable_starttls and :tls are mutually exclusive. Set :tls if you're on an SMTPS connection. Set :enable_starttls if you're on an SMTP connection and using STARTTLS for secure TLS upgrade."
160
+ end
161
+
113
162
  Net::SMTP.new(settings[:address], settings[:port]).tap do |smtp|
114
- tls = settings[:tls] || settings[:ssl]
115
- if !tls.nil?
116
- case tls
117
- when true
118
- smtp.enable_tls(ssl_context)
119
- when false
120
- smtp.disable_tls
121
- else
122
- raise ArgumentError, "Unrecognized :tls value #{settings[:tls].inspect}; expected true, false, or nil"
123
- end
124
- elsif settings.include?(:enable_starttls) && !settings[:enable_starttls].nil?
125
- case settings[:enable_starttls]
126
- when true
163
+ if smtp_tls?
164
+ smtp.disable_starttls
165
+ smtp.enable_tls(ssl_context)
166
+ else
167
+ smtp.disable_tls
168
+
169
+ case smtp_starttls
170
+ when :always
127
171
  smtp.enable_starttls(ssl_context)
128
- when false
129
- smtp.disable_starttls
130
- else
131
- raise ArgumentError, "Unrecognized :enable_starttls value #{settings[:enable_starttls].inspect}; expected true, false, or nil"
132
- end
133
- elsif settings.include?(:enable_starttls_auto) && !settings[:enable_starttls_auto].nil?
134
- case settings[:enable_starttls_auto]
135
- when true
172
+ when :auto
136
173
  smtp.enable_starttls_auto(ssl_context)
137
- when false
138
- smtp.disable_starttls
139
174
  else
140
- raise ArgumentError, "Unrecognized :enable_starttls_auto value #{settings[:enable_starttls_auto].inspect}; expected true, false, or nil"
175
+ smtp.disable_starttls
141
176
  end
142
177
  end
143
178
 
@@ -3,39 +3,39 @@ require 'mail/smtp_envelope'
3
3
 
4
4
  module Mail
5
5
  # == Sending Email with SMTP
6
- #
6
+ #
7
7
  # Mail allows you to send emails using an open SMTP connection. This is done by
8
8
  # passing a created Net::SMTP object. This way we can get better performance to
9
9
  # our local mail server by reducing the number of connections at any one time.
10
10
  #
11
11
  # === Sending via SMTP server on Localhost
12
- #
12
+ #
13
13
  # To send mail open a connection with Net::Smtp using any options you like
14
14
  # === Delivering the email
15
- #
15
+ #
16
16
  # Once you have the settings right, sending the email is done by:
17
17
  #
18
18
  # smtp_conn = Net::SMTP.start(settings[:address], settings[:port])
19
19
  # Mail.defaults do
20
20
  # delivery_method :smtp_connection, { :connection => smtp_conn }
21
21
  # end
22
- #
22
+ #
23
23
  # Mail.deliver do
24
24
  # to 'mikel@test.lindsaar.net'
25
25
  # from 'ada@test.lindsaar.net'
26
26
  # subject 'testing sendmail'
27
27
  # body 'testing sendmail'
28
28
  # end
29
- #
29
+ #
30
30
  # Or by calling deliver on a Mail message
31
- #
31
+ #
32
32
  # mail = Mail.new do
33
33
  # to 'mikel@test.lindsaar.net'
34
34
  # from 'ada@test.lindsaar.net'
35
35
  # subject 'testing sendmail'
36
36
  # body 'testing sendmail'
37
37
  # end
38
- #
38
+ #
39
39
  # mail.deliver!
40
40
  class SMTPConnection
41
41
  attr_accessor :smtp, :settings
@@ -4,7 +4,7 @@ require 'mail/smtp_envelope'
4
4
  module Mail
5
5
  # The TestMailer is a bare bones mailer that does nothing. It is useful
6
6
  # when you are testing.
7
- #
7
+ #
8
8
  # It also provides a template of the minimum methods you require to implement
9
9
  # if you want to make a custom mailer for Mail
10
10
  class TestMailer
@@ -14,11 +14,11 @@ module Mail
14
14
  end
15
15
 
16
16
  # Allows you to over write the default deliveries store from an array to some
17
- # other object. If you just want to clear the store,
17
+ # other object. If you just want to clear the store,
18
18
  # call TestMailer.deliveries.clear.
19
- #
19
+ #
20
20
  # If you place another object here, please make sure it responds to:
21
- #
21
+ #
22
22
  # * << (message)
23
23
  # * clear
24
24
  # * length
@@ -17,7 +17,7 @@ module Mail
17
17
  options[:count] ||= 1
18
18
  find(options, &block)
19
19
  end
20
-
20
+
21
21
  # Get the most recent received email(s)
22
22
  #
23
23
  # Possible options:
@@ -30,7 +30,7 @@ module Mail
30
30
  options[:count] ||= 1
31
31
  find(options, &block)
32
32
  end
33
-
33
+
34
34
  # Get all emails.
35
35
  #
36
36
  # Possible options:
@@ -42,7 +42,7 @@ module Mail
42
42
  find(options, &block)
43
43
  end
44
44
 
45
- # Find emails in the mailbox, and then deletes them. Without any options, the
45
+ # Find emails in the mailbox, and then deletes them. Without any options, the
46
46
  # five last received emails are returned.
47
47
  #
48
48
  # Possible options:
@@ -56,8 +56,8 @@ module Mail
56
56
  def find_and_delete(options = nil, &block)
57
57
  options = options ? Hash[options] : {}
58
58
  options[:delete_after_find] ||= true
59
- find(options, &block)
60
- end
59
+ find(options, &block)
60
+ end
61
61
 
62
62
  end
63
63
 
@@ -29,7 +29,7 @@ module Mail
29
29
  # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
30
30
  # count: number of emails to retrieve. The default value is 10. A value of 1 returns an
31
31
  # instance of Message, not an array of Message instances.
32
- # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
32
+ # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
33
33
  # or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
34
34
  # The default is 'ALL'
35
35
  #
@@ -38,7 +38,7 @@ module Mail
38
38
  #
39
39
  class IMAP < Retriever
40
40
  require 'net/imap' unless defined?(Net::IMAP)
41
-
41
+
42
42
  def initialize(values)
43
43
  self.settings = { :address => "localhost",
44
44
  :port => 143,
@@ -65,7 +65,7 @@ module Mail
65
65
  # This is helpful when you don't want your messages to be set to read automatically. Default is false.
66
66
  # delete_after_find: flag for whether to delete each retreived email after find. Default
67
67
  # is false. Use #find_and_delete if you would like this to default to true.
68
- # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
68
+ # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
69
69
  # or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
70
70
  # The default is 'ALL'
71
71
  # search_charset: charset to pass to IMAP server search. Omitted by default. Example: 'UTF-8' or 'ASCII'.
@@ -75,7 +75,10 @@ module Mail
75
75
 
76
76
  start do |imap|
77
77
  options[:read_only] ? imap.examine(options[:mailbox]) : imap.select(options[:mailbox])
78
+
78
79
  uids = imap.uid_search(options[:keys], options[:search_charset])
80
+ .to_a # older net-imap may return nil, newer may return ESearchResult struct
81
+ .sort # RFC3501 does _not_ require UIDs to be returned in order
79
82
  uids.reverse! if options[:what].to_sym == :last
80
83
  uids = uids.first(options[:count]) if options[:count].is_a?(Integer)
81
84
  uids.reverse! if (options[:what].to_sym == :last && options[:order].to_sym == :asc) ||
@@ -6,9 +6,9 @@ module Mail
6
6
  # Each email retrieved (RFC2822) is given as an instance of +Message+.
7
7
  #
8
8
  # While being retrieved, emails can be yielded if a block is given.
9
- #
9
+ #
10
10
  # === Example of retrieving Emails from GMail:
11
- #
11
+ #
12
12
  # Mail.defaults do
13
13
  # retriever_method :pop3, { :address => "pop.gmail.com",
14
14
  # :port => 995,
@@ -16,22 +16,22 @@ module Mail
16
16
  # :password => '<password>',
17
17
  # :enable_ssl => true }
18
18
  # end
19
- #
19
+ #
20
20
  # Mail.all #=> Returns an array of all emails
21
21
  # Mail.first #=> Returns the first unread email
22
22
  # Mail.last #=> Returns the last unread email
23
- #
23
+ #
24
24
  # You can also pass options into Mail.find to locate an email in your pop mailbox
25
25
  # with the following options:
26
- #
26
+ #
27
27
  # what: last or first emails. The default is :first.
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
- #
31
+ #
32
32
  # Mail.find(:what => :first, :count => 10, :order => :asc)
33
33
  # #=> Returns the first 10 emails in ascending order
34
- #
34
+ #
35
35
  class POP3 < Retriever
36
36
  require 'net/pop' unless defined?(Net::POP)
37
37
 
@@ -44,9 +44,9 @@ module Mail
44
44
  :enable_ssl => false,
45
45
  :read_timeout => nil }.merge!(values)
46
46
  end
47
-
47
+
48
48
  attr_accessor :settings
49
-
49
+
50
50
  # Find emails in a POP3 mailbox. Without any options, the 5 last received emails are returned.
51
51
  #
52
52
  # Possible options:
@@ -59,18 +59,18 @@ module Mail
59
59
  #
60
60
  def find(options = nil, &block)
61
61
  options = validate_options(options)
62
-
62
+
63
63
  start do |pop3|
64
64
  mails = pop3.mails
65
65
  pop3.reset # Clears all "deleted" marks. This prevents non-explicit/accidental deletions due to server settings.
66
66
  mails.sort! { |m1, m2| m2.number <=> m1.number } if options[:what] == :last
67
67
  mails = mails.first(options[:count]) if options[:count].is_a? Integer
68
-
68
+
69
69
  if options[:what].to_sym == :last && options[:order].to_sym == :desc ||
70
70
  options[:what].to_sym == :first && options[:order].to_sym == :asc ||
71
71
  mails.reverse!
72
72
  end
73
-
73
+
74
74
  if block_given?
75
75
  mails.each do |mail|
76
76
  new_message = Mail.new(mail.pop)
@@ -86,11 +86,11 @@ module Mail
86
86
  end
87
87
  emails.size == 1 && options[:count] == 1 ? emails.first : emails
88
88
  end
89
-
89
+
90
90
  end
91
91
  end
92
-
93
- # Delete all emails from a POP3 server
92
+
93
+ # Delete all emails from a POP3 server
94
94
  def delete_all
95
95
  start do |pop3|
96
96
  unless pop3.mails.empty?
@@ -108,9 +108,9 @@ module Mail
108
108
  yield pop3
109
109
  end
110
110
  end
111
-
111
+
112
112
  private
113
-
113
+
114
114
  # Set default options
115
115
  def validate_options(options)
116
116
  options = options ? Hash[options] : {}
@@ -120,18 +120,18 @@ module Mail
120
120
  options[:delete_after_find] ||= false
121
121
  options
122
122
  end
123
-
123
+
124
124
  # Start a POP3 session and ensure that it will be closed in any case. Any messages
125
125
  # marked for deletion via #find_and_delete or with the :delete_after_find option
126
126
  # will be deleted when the session is closed.
127
127
  def start(config = Configuration.instance, &block)
128
128
  raise ArgumentError.new("Mail::Retrievable#pop3_start takes a block") unless block_given?
129
-
129
+
130
130
  pop3 = Net::POP3.new(settings[:address], settings[:port], false)
131
131
  pop3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if settings[:enable_ssl]
132
132
  pop3.read_timeout = settings[:read_timeout] if settings[:read_timeout]
133
133
  pop3.start(settings[:user_name], settings[:password])
134
-
134
+
135
135
  yield pop3
136
136
  ensure
137
137
  if defined?(pop3) && pop3 && pop3.started?
@@ -1,4 +1,3 @@
1
-
2
1
  # frozen_string_literal: true
3
2
  require "mail/utilities"
4
3
  require "mail/parser_tools"
@@ -32011,10 +32010,10 @@ begin
32011
32010
  _trans = if (_slen > 0 &&
32012
32011
  _trans_keys[_keys] <= _wide &&
32013
32012
  _wide <= _trans_keys[_keys + 1])
32014
- _indicies[_inds + _wide - _trans_keys[_keys]]
32015
- else
32016
- _indicies[_inds + _slen]
32017
- end
32013
+ _indicies[_inds + _wide - _trans_keys[_keys]]
32014
+ else
32015
+ _indicies[_inds + _slen]
32016
+ end
32018
32017
  cs = _trans_targs[_trans]
32019
32018
  if _trans_actions[_trans] != 0
32020
32019
  case _trans_actions[_trans]
@@ -33229,6 +33228,10 @@ begin
33229
33228
  end
33230
33229
  end
33231
33230
 
33231
+ if false
33232
+ testEof
33233
+ end
33234
+
33232
33235
  if p != eof || cs < 2461
33233
33236
  raise Mail::Field::IncompleteParseError.new(Mail::AddressList, data, p)
33234
33237
  end
@@ -165,6 +165,10 @@ module Mail::Parsers
165
165
  %%write init;
166
166
  %%write exec;
167
167
 
168
+ if false
169
+ testEof
170
+ end
171
+
168
172
  if p != eof || cs < %%{ write first_final; }%%
169
173
  raise Mail::Field::IncompleteParseError.new(Mail::AddressList, data, p)
170
174
  end
@@ -1,4 +1,3 @@
1
-
2
1
  # frozen_string_literal: true
3
2
  require "mail/utilities"
4
3
  require "mail/parser_tools"
@@ -610,10 +609,10 @@ begin
610
609
  _trans = if (_slen > 0 &&
611
610
  _trans_keys[_keys] <= _wide &&
612
611
  _wide <= _trans_keys[_keys + 1])
613
- _indicies[_inds + _wide - _trans_keys[_keys]]
614
- else
615
- _indicies[_inds + _slen]
616
- end
612
+ _indicies[_inds + _wide - _trans_keys[_keys]]
613
+ else
614
+ _indicies[_inds + _slen]
615
+ end
617
616
  cs = _trans_targs[_trans]
618
617
  if _trans_actions[_trans] != 0
619
618
  case _trans_actions[_trans]
@@ -654,7 +653,7 @@ begin
654
653
  # Use quoted string value if one exists, otherwise use parameter value
655
654
  value = qstr || chars(data, param_val_s, p - 1)
656
655
 
657
- content_disposition.parameters << {param_attr => value}
656
+ content_disposition.parameters << { param_attr => value }
658
657
  param_attr = nil
659
658
  qstr = nil
660
659
  end
@@ -712,7 +711,7 @@ begin
712
711
  # Use quoted string value if one exists, otherwise use parameter value
713
712
  value = qstr || chars(data, param_val_s, p - 1)
714
713
 
715
- content_disposition.parameters << {param_attr => value}
714
+ content_disposition.parameters << { param_attr => value }
716
715
  param_attr = nil
717
716
  qstr = nil
718
717
  end
@@ -742,7 +741,7 @@ begin
742
741
  # Use quoted string value if one exists, otherwise use parameter value
743
742
  value = qstr || chars(data, param_val_s, p - 1)
744
743
 
745
- content_disposition.parameters << {param_attr => value}
744
+ content_disposition.parameters << { param_attr => value }
746
745
  param_attr = nil
747
746
  qstr = nil
748
747
  end
@@ -799,7 +798,7 @@ begin
799
798
  # Use quoted string value if one exists, otherwise use parameter value
800
799
  value = qstr || chars(data, param_val_s, p - 1)
801
800
 
802
- content_disposition.parameters << {param_attr => value}
801
+ content_disposition.parameters << { param_attr => value }
803
802
  param_attr = nil
804
803
  qstr = nil
805
804
  end
@@ -823,7 +822,7 @@ begin
823
822
  # Use quoted string value if one exists, otherwise use parameter value
824
823
  value = qstr || chars(data, param_val_s, p - 1)
825
824
 
826
- content_disposition.parameters << {param_attr => value}
825
+ content_disposition.parameters << { param_attr => value }
827
826
  param_attr = nil
828
827
  qstr = nil
829
828
  end
@@ -857,7 +856,7 @@ begin
857
856
  # Use quoted string value if one exists, otherwise use parameter value
858
857
  value = qstr || chars(data, param_val_s, p - 1)
859
858
 
860
- content_disposition.parameters << {param_attr => value}
859
+ content_disposition.parameters << { param_attr => value }
861
860
  param_attr = nil
862
861
  qstr = nil
863
862
  end
@@ -875,7 +874,7 @@ begin
875
874
  # Use quoted string value if one exists, otherwise use parameter value
876
875
  value = qstr || chars(data, param_val_s, p - 1)
877
876
 
878
- content_disposition.parameters << {param_attr => value}
877
+ content_disposition.parameters << { param_attr => value }
879
878
  param_attr = nil
880
879
  qstr = nil
881
880
  end
@@ -888,6 +887,10 @@ begin
888
887
  end
889
888
  end
890
889
 
890
+ if false
891
+ testEof
892
+ end
893
+
891
894
  if p != eof || cs < 40
892
895
  raise Mail::Field::IncompleteParseError.new(Mail::ContentDispositionElement, data, p)
893
896
  end
@@ -75,6 +75,10 @@ module Mail::Parsers
75
75
  %%write init;
76
76
  %%write exec;
77
77
 
78
+ if false
79
+ testEof
80
+ end
81
+
78
82
  if p != eof || cs < %%{ write first_final; }%%
79
83
  raise Mail::Field::IncompleteParseError.new(Mail::ContentDispositionElement, data, p)
80
84
  end