mail 2.5.5 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +8 -9
- data/CONTRIBUTING.md +13 -0
- data/Dependencies.txt +0 -1
- data/Gemfile +7 -24
- data/README.md +36 -15
- data/Rakefile +10 -2
- data/VERSION +4 -0
- data/lib/mail.rb +1 -1
- data/lib/mail/body.rb +2 -2
- data/lib/mail/check_delivery_params.rb +10 -47
- data/lib/mail/core_extensions/string.rb +12 -2
- data/lib/mail/elements/address.rb +38 -82
- data/lib/mail/elements/address_list.rb +19 -42
- data/lib/mail/elements/content_disposition_element.rb +3 -7
- data/lib/mail/elements/content_location_element.rb +2 -6
- data/lib/mail/elements/content_transfer_encoding_element.rb +3 -10
- data/lib/mail/elements/content_type_element.rb +4 -8
- data/lib/mail/elements/date_time_element.rb +3 -7
- data/lib/mail/elements/envelope_from_element.rb +3 -11
- data/lib/mail/elements/message_ids_element.rb +1 -6
- data/lib/mail/elements/mime_version_element.rb +3 -7
- data/lib/mail/elements/phrase_list.rb +2 -7
- data/lib/mail/elements/received_element.rb +3 -7
- data/lib/mail/encodings.rb +0 -1
- data/lib/mail/envelope.rb +0 -5
- data/lib/mail/field.rb +53 -17
- data/lib/mail/field_list.rb +18 -18
- data/lib/mail/fields/common/common_address.rb +15 -20
- data/lib/mail/fields/common/common_date.rb +0 -7
- data/lib/mail/fields/common/common_field.rb +1 -1
- data/lib/mail/fields/content_transfer_encoding_field.rb +0 -6
- data/lib/mail/fields/resent_sender_field.rb +1 -1
- data/lib/mail/fields/sender_field.rb +1 -1
- data/lib/mail/fields/unstructured_field.rb +7 -1
- data/lib/mail/header.rb +8 -22
- data/lib/mail/mail.rb +12 -0
- data/lib/mail/matchers/has_sent_mail.rb +34 -1
- data/lib/mail/message.rb +18 -11
- data/lib/mail/multibyte/unicode.rb +1 -1
- data/lib/mail/network/delivery_methods/exim.rb +10 -6
- data/lib/mail/network/delivery_methods/file_delivery.rb +8 -4
- data/lib/mail/network/delivery_methods/sendmail.rb +7 -9
- data/lib/mail/network/delivery_methods/smtp.rb +5 -2
- data/lib/mail/network/delivery_methods/smtp_connection.rb +6 -2
- data/lib/mail/network/delivery_methods/test_mailer.rb +8 -5
- data/lib/mail/network/retriever_methods/imap.rb +18 -13
- data/lib/mail/parsers.rb +26 -0
- data/lib/mail/parsers/address_lists_parser.rb +132 -0
- data/lib/mail/parsers/content_disposition_parser.rb +67 -0
- data/lib/mail/parsers/content_location_parser.rb +35 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
- data/lib/mail/parsers/content_type_parser.rb +64 -0
- data/lib/mail/parsers/date_time_parser.rb +36 -0
- data/lib/mail/parsers/envelope_from_parser.rb +45 -0
- data/lib/mail/parsers/message_ids_parser.rb +39 -0
- data/lib/mail/parsers/mime_version_parser.rb +41 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
- data/lib/mail/parsers/ragel.rb +17 -0
- data/lib/mail/parsers/ragel/common.rl +184 -0
- data/lib/mail/parsers/ragel/date_time.rl +30 -0
- data/lib/mail/parsers/ragel/parser_info.rb +61 -0
- data/lib/mail/parsers/ragel/ruby.rb +29 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
- data/lib/mail/parsers/received_parser.rb +47 -0
- data/lib/mail/parts_list.rb +4 -2
- data/lib/mail/patterns.rb +3 -1
- data/lib/mail/utilities.rb +3 -1
- data/lib/mail/version.rb +1 -1
- data/lib/mail/version_specific/ruby_1_8.rb +1 -1
- data/lib/mail/version_specific/ruby_1_9.rb +13 -1
- metadata +55 -51
- data/lib/VERSION +0 -4
- data/lib/load_parsers.rb +0 -35
- data/lib/mail/parsers/address_lists.rb +0 -64
- data/lib/mail/parsers/address_lists.treetop +0 -19
- data/lib/mail/parsers/content_disposition.rb +0 -535
- data/lib/mail/parsers/content_disposition.treetop +0 -46
- data/lib/mail/parsers/content_location.rb +0 -139
- data/lib/mail/parsers/content_location.treetop +0 -20
- data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
- data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
- data/lib/mail/parsers/content_type.rb +0 -971
- data/lib/mail/parsers/content_type.treetop +0 -68
- data/lib/mail/parsers/date_time.rb +0 -114
- data/lib/mail/parsers/date_time.treetop +0 -11
- data/lib/mail/parsers/envelope_from.rb +0 -194
- data/lib/mail/parsers/envelope_from.treetop +0 -32
- data/lib/mail/parsers/message_ids.rb +0 -45
- data/lib/mail/parsers/message_ids.treetop +0 -15
- data/lib/mail/parsers/mime_version.rb +0 -144
- data/lib/mail/parsers/mime_version.treetop +0 -19
- data/lib/mail/parsers/phrase_lists.rb +0 -45
- data/lib/mail/parsers/phrase_lists.treetop +0 -15
- data/lib/mail/parsers/received.rb +0 -71
- data/lib/mail/parsers/received.treetop +0 -11
- data/lib/mail/parsers/rfc2045.rb +0 -421
- data/lib/mail/parsers/rfc2045.treetop +0 -35
- data/lib/mail/parsers/rfc2822.rb +0 -5397
- data/lib/mail/parsers/rfc2822.treetop +0 -408
- data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
- data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
- data/lib/tasks/corpus.rake +0 -125
- data/lib/tasks/treetop.rake +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecb5e9115e61802f251480eef90c6698ac665d0b
|
4
|
+
data.tar.gz: a1105d5defc2c7b374598a392e5f5dc4d1452a21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 103d2126c02d1aeb5ffd4982f261407af16652fd181f6e0fc63bf12702e5aa1ea3c7f863a3c39f822ba3b8e8cf704782d1beb7c4e2e28cba5f4fc2931151cf0e
|
7
|
+
data.tar.gz: 6f25c0decaf77a0314b42d0fbf6c61edfc7f2fe9b4bbeef004e34a7127882093b660108cd7728a108f26b1b3dcf2664beac4e5e6d0d0d3e68565f78fdd273d4e
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,15 +1,10 @@
|
|
1
|
-
==
|
1
|
+
== HEAD
|
2
2
|
|
3
|
-
|
4
|
-
* #1097 – SMTP security: prevent command injection via To/From addresses. (jeremy)
|
5
|
-
|
6
|
-
Bugs:
|
7
|
-
* #633 – Cope with message parts that have an empty Content-Type (ThomasKoppensteiner, zeepeeare)
|
8
|
-
* #689 - Fix Exim delivery method broken by #477 in 2.5.4. (jethrogb)
|
9
|
-
|
10
|
-
== Version 2.5.4 - Tue May 14 14:45:00 +1100 2013 Mikel Lindsaar <mikel@lindsaar.net>
|
3
|
+
== Version 2.6.0 - Mon Jun 2 22:49 +1100 2014 Mikel Lindsaar <mikel@reinteractive.net>
|
11
4
|
|
12
5
|
Features:
|
6
|
+
* Allow interceptors and observers to be unregistered (zuhao)
|
7
|
+
* Added feature to find the mail in uid (taketin)
|
13
8
|
* Save settings passed to TestMailer#new (svanderbleek)
|
14
9
|
* Allow the setting of envelope from directly (jeremy)
|
15
10
|
* Accept other IETF/IANA-registered Content-Types and Content-Transfer-Encodings (jeremy)
|
@@ -25,9 +20,13 @@ Features:
|
|
25
20
|
* Close pull request 389 - Don't add superfluous message headers to MIME parts (djmaze, jeremy)
|
26
21
|
|
27
22
|
Performance:
|
23
|
+
* Migrate to RAGEL based parser, awesome work by (bpot)
|
24
|
+
* Performance improvements for people parsing email headers (ConradIrwin)
|
28
25
|
* Close pull request 488 - Speed up field construction & comparison (bpot)
|
29
26
|
|
30
27
|
Bugs:
|
28
|
+
* Fix for when content looks like field name (kjg)
|
29
|
+
* Don't change original when you change a copy (TylerRick)
|
31
30
|
* Don't include separating semicolon in paramter value when sanitizing (bpot)
|
32
31
|
* Fix fencepost encoding problem with binhex strings and only one token (drasch)
|
33
32
|
* Fix sendmail delivery to addresses with a leading hyphen (lifo, jeremy)
|
data/CONTRIBUTING.md
CHANGED
@@ -43,3 +43,16 @@ Syntax:
|
|
43
43
|
* Follow the conventions you see used in the source already.
|
44
44
|
|
45
45
|
And in case we didn't emphasize it enough: we love specs!
|
46
|
+
|
47
|
+
### Testing against mime-types versions:
|
48
|
+
|
49
|
+
Use [appraisal](https://github.com/thoughtbot/appraisal) to run against all supported versions of mime-types.
|
50
|
+
|
51
|
+
1. Run `(bundle check || bundle) && appraisal` so that all the 'appraised' gemfiles are bundled.
|
52
|
+
2. Run either `appraisal rake` or `rake appraisal` to run all the tests.
|
53
|
+
|
54
|
+
To run only one 'appraised' gemfile, run. e.g. `BUNDLE_GEMFILE=gemfiles/mime_types_edge.gemfile (bundle check || bundle) && rake`
|
55
|
+
|
56
|
+
To change the appraisals, modify the `Appraisals` file, run `appraisal`, commit the generated gemfiles, and modify the .travis.yml matrix.
|
57
|
+
|
58
|
+
To run on all rubies / gemfiles, just like TravisCI, see [WWTD](https://github.com/grosser/wwtd).
|
data/Dependencies.txt
CHANGED
data/Gemfile
CHANGED
@@ -1,32 +1,15 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
if RUBY_VERSION
|
6
|
-
|
7
|
-
elsif RUBY_VERSION < '2.2.2'
|
8
|
-
gem 'activesupport', '< 5'
|
9
|
-
end
|
10
|
-
gem 'i18n', '< 0.7.0' if RUBY_VERSION < '1.9.3'
|
11
|
-
gem "tlsmail" if RUBY_VERSION <= '1.8.6'
|
12
|
-
gem "mime-types", "~> 1.16"
|
13
|
-
gem "treetop", "~> 1.4.10"
|
5
|
+
gem "tlsmail", "~> 0.0.1" if RUBY_VERSION <= "1.8.6"
|
6
|
+
gem "jruby-openssl", :platforms => :jruby
|
14
7
|
|
15
|
-
|
8
|
+
group :development, :test do
|
9
|
+
gem "appraisal", "~> 1.0"
|
10
|
+
end
|
16
11
|
|
17
12
|
# For gems not required to run tests
|
18
13
|
group :local_development, :test do
|
19
|
-
gem
|
20
|
-
gem 'rdoc', '< 4.3' if RUBY_VERSION < '1.9.3'
|
21
|
-
gem "rspec", "~> 2.8.0"
|
22
|
-
case
|
23
|
-
when defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
|
24
|
-
# Skip it
|
25
|
-
when RUBY_PLATFORM == 'java'
|
26
|
-
# Skip it
|
27
|
-
when RUBY_VERSION < '1.9'
|
28
|
-
gem "ruby-debug"
|
29
|
-
else
|
30
|
-
# Skip it
|
31
|
-
end
|
14
|
+
gem "ruby-debug", :platforms => :mri_18
|
32
15
|
end
|
data/README.md
CHANGED
@@ -42,15 +42,25 @@ me a nice email :)
|
|
42
42
|
Compatibility
|
43
43
|
-------------
|
44
44
|
|
45
|
-
Mail
|
45
|
+
Every Mail commit is tested by Travis on the [following platforms](https://github.com/mikel/mail/blob/master/.travis.yml)
|
46
46
|
|
47
|
-
|
47
|
+
* ruby-1.8.7-p374 [ i686 ]
|
48
|
+
* ruby-1.9.2-p320 [ x86_64 ]
|
49
|
+
* ruby-1.9.3-p327 [ x86_64 ]
|
50
|
+
* ruby-2.0.0-p451 [ x86_64 ]
|
51
|
+
* ruby-2.1.2 [ x86_64 ]
|
52
|
+
* ruby-head [ x86_64 ]
|
53
|
+
* jruby [ x86_64 ]
|
54
|
+
* jruby-head [ x86_64 ]
|
55
|
+
* rbx-2 [ x86_64 ]
|
56
|
+
|
57
|
+
Testing a specific mime type (needed for 1.8.7 for example) can be done manually with:
|
58
|
+
|
59
|
+
$ BUNDLE_GEMFILE=gemfiles/mime_types_1.16.gemfile bundle check
|
60
|
+
$ BUNDLE_GEMFILE=gemfiles/mime_types_1.16.gemfile bundle
|
61
|
+
$ BUNDLE_GEMFILE=gemfiles/mime_types_1.16.gemfile rake
|
48
62
|
|
49
|
-
Testing a specific version of mime-types (needed for Ruby 1.8.7, for example) can be done manually with:
|
50
63
|
|
51
|
-
```sh
|
52
|
-
BUNDLE_GEMFILE=gemfiles/mime_types_1.16.gemfile bundle && rake
|
53
|
-
```
|
54
64
|
|
55
65
|
Discussion
|
56
66
|
----------
|
@@ -185,6 +195,8 @@ mail['from'] = 'mikel@test.lindsaar.net'
|
|
185
195
|
mail[:to] = 'you@test.lindsaar.net'
|
186
196
|
mail.subject = 'This is a test email'
|
187
197
|
|
198
|
+
mail.header['X-Custom-Header'] = 'custom value'
|
199
|
+
|
188
200
|
mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
|
189
201
|
```
|
190
202
|
|
@@ -227,10 +239,10 @@ easy as:
|
|
227
239
|
|
228
240
|
```ruby
|
229
241
|
Mail.deliver do
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
242
|
+
from 'me@test.lindsaar.net'
|
243
|
+
to 'you@test.lindsaar.net'
|
244
|
+
subject 'Here is the image you wanted'
|
245
|
+
body File.read('body.txt')
|
234
246
|
add_file '/full/path/to/somefile.png'
|
235
247
|
end
|
236
248
|
```
|
@@ -265,6 +277,15 @@ mail.delivery_method :sendmail
|
|
265
277
|
mail.deliver
|
266
278
|
```
|
267
279
|
|
280
|
+
Sending via smtp (for example to [mailcatcher](https://github.com/sj26/mailcatcher))
|
281
|
+
```ruby
|
282
|
+
|
283
|
+
Mail.defaults do
|
284
|
+
delivery_method :smtp, address: "localhost", port: 1025
|
285
|
+
end
|
286
|
+
```
|
287
|
+
|
288
|
+
|
268
289
|
Exim requires its own delivery manager, and can be used like so:
|
269
290
|
|
270
291
|
```ruby
|
@@ -318,7 +339,7 @@ emails.length #=> LOTS!
|
|
318
339
|
```ruby
|
319
340
|
mail = Mail.read('/path/to/message.eml')
|
320
341
|
|
321
|
-
mail.
|
342
|
+
mail.envelope_from #=> 'mikel@test.lindsaar.net'
|
322
343
|
mail.from.addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
323
344
|
mail.sender.address #=> 'mikel@test.lindsaar.net'
|
324
345
|
mail.to #=> 'bob@test.lindsaar.net'
|
@@ -349,7 +370,7 @@ mail.parts[1].content_type_parameters #=> {'name' => 'my.pdf'}
|
|
349
370
|
Mail generates a tree of parts. Each message has many or no parts. Each part
|
350
371
|
is another message which can have many or no parts.
|
351
372
|
|
352
|
-
A message will only have parts if it is a multipart/mixed or related
|
373
|
+
A message will only have parts if it is a multipart/mixed or multipart/related
|
353
374
|
content type and has a boundary defined.
|
354
375
|
|
355
376
|
### Testing and extracting attachments
|
@@ -362,7 +383,7 @@ mail.attachments.each do | attachment |
|
|
362
383
|
filename = attachment.filename
|
363
384
|
begin
|
364
385
|
File.open(images_dir + filename, "w+b", 0644) {|f| f.write attachment.body.decoded}
|
365
|
-
rescue
|
386
|
+
rescue => e
|
366
387
|
puts "Unable to save data for #{filename} because #{e.message}"
|
367
388
|
end
|
368
389
|
end
|
@@ -545,7 +566,7 @@ Using Mail with Testing or Spec'ing Libraries
|
|
545
566
|
If mail is part of your system, you'll need a way to test it without actually
|
546
567
|
sending emails, the TestMailer can do this for you.
|
547
568
|
|
548
|
-
```
|
569
|
+
```ruby
|
549
570
|
require 'mail'
|
550
571
|
=> true
|
551
572
|
Mail.defaults do
|
@@ -571,7 +592,7 @@ Mail::TestMailer.deliveries.clear
|
|
571
592
|
|
572
593
|
There is also a set of RSpec matchers stolen fr^H^H^H^H^H^H^H^H inspired by Shoulda's ActionMailer matchers (you'll want to set <code>delivery_method</code> as above too):
|
573
594
|
|
574
|
-
```
|
595
|
+
```ruby
|
575
596
|
Mail.defaults do
|
576
597
|
delivery_method :test # in practice you'd do this in spec_helper.rb
|
577
598
|
end
|
data/Rakefile
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
ENV[
|
1
|
+
if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
|
2
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
|
3
|
+
end
|
2
4
|
require 'rubygems'
|
3
5
|
require 'bundler/setup'
|
4
6
|
|
@@ -17,5 +19,11 @@ RSpec::Core::RakeTask.new(:spec) do |t|
|
|
17
19
|
t.rspec_opts = %w(--backtrace --color)
|
18
20
|
end
|
19
21
|
|
22
|
+
begin
|
23
|
+
require "appraisal"
|
24
|
+
rescue LoadError
|
25
|
+
warn "Appraisal is only available in test/development"
|
26
|
+
end
|
27
|
+
|
20
28
|
# load custom rake tasks
|
21
|
-
Dir["#{File.dirname(__FILE__)}/
|
29
|
+
Dir["#{File.dirname(__FILE__)}/tasks/**/*.rake"].sort.each { |ext| load ext }
|
data/VERSION
ADDED
data/lib/mail.rb
CHANGED
data/lib/mail/body.rb
CHANGED
@@ -127,9 +127,9 @@ module Mail
|
|
127
127
|
def sort_parts!
|
128
128
|
@parts.each do |p|
|
129
129
|
p.body.set_sort_order(@part_sort_order)
|
130
|
-
@parts.sort!(@part_sort_order)
|
131
130
|
p.body.sort_parts!
|
132
131
|
end
|
132
|
+
@parts.sort!(@part_sort_order)
|
133
133
|
end
|
134
134
|
|
135
135
|
# Returns the raw source that the body was initialized with, without
|
@@ -257,7 +257,7 @@ module Mail
|
|
257
257
|
|
258
258
|
def split!(boundary)
|
259
259
|
self.boundary = boundary
|
260
|
-
parts = raw_source.split(/(?:\A|\r\n)--#{Regexp.escape(boundary)}(?=(?:--)?\s*$)/)
|
260
|
+
parts = raw_source.split(/(?:\A|\r\n)--#{Regexp.escape(boundary || "")}(?=(?:--)?\s*$)/)
|
261
261
|
# Make the preamble equal to the preamble (if any)
|
262
262
|
self.preamble = parts[0].to_s.strip
|
263
263
|
# Make the epilogue equal to the epilogue (if any)
|
@@ -1,57 +1,20 @@
|
|
1
1
|
module Mail
|
2
|
-
module CheckDeliveryParams
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
check_to(mail.smtp_envelope_to),
|
7
|
-
check_message(mail) ]
|
2
|
+
module CheckDeliveryParams
|
3
|
+
def check_delivery_params(mail)
|
4
|
+
if mail.smtp_envelope_from.blank?
|
5
|
+
raise ArgumentError.new('An SMTP From address is required to send a message. Set the message smtp_envelope_from, return_path, sender, or from address.')
|
8
6
|
end
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
raise ArgumentError, "SMTP From address may not be blank: #{addr.inspect}"
|
13
|
-
end
|
14
|
-
|
15
|
-
check_addr 'From', addr
|
16
|
-
end
|
17
|
-
|
18
|
-
def check_to(addrs)
|
19
|
-
if addrs.blank?
|
20
|
-
raise ArgumentError, "SMTP To address may not be blank: #{addrs.inspect}"
|
21
|
-
end
|
22
|
-
|
23
|
-
Array(addrs).map do |addr|
|
24
|
-
check_addr 'To', addr
|
25
|
-
end
|
8
|
+
if mail.smtp_envelope_to.blank?
|
9
|
+
raise ArgumentError.new('An SMTP To address is required to send a message. Set the message smtp_envelope_to, to, cc, or bcc address.')
|
26
10
|
end
|
27
11
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
12
|
+
message = mail.encoded if mail.respond_to?(:encoded)
|
13
|
+
if message.blank?
|
14
|
+
raise ArgumentError.new('An encoded message is required to send an email')
|
32
15
|
end
|
33
16
|
|
34
|
-
|
35
|
-
if addr.bytesize > 2048
|
36
|
-
yield 'may not exceed 2kB'
|
37
|
-
end
|
38
|
-
|
39
|
-
if /[\r\n]/ =~ addr
|
40
|
-
yield 'may not contain CR or LF line breaks'
|
41
|
-
end
|
42
|
-
|
43
|
-
addr
|
44
|
-
end
|
45
|
-
|
46
|
-
def check_message(message)
|
47
|
-
message = message.encoded if message.respond_to?(:encoded)
|
48
|
-
|
49
|
-
if message.blank?
|
50
|
-
raise ArgumentError, 'An encoded message is required to send an email'
|
51
|
-
end
|
52
|
-
|
53
|
-
message
|
54
|
-
end
|
17
|
+
[mail.smtp_envelope_from, mail.smtp_envelope_to, message]
|
55
18
|
end
|
56
19
|
end
|
57
20
|
end
|
@@ -1,11 +1,21 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
class String #:nodoc:
|
3
|
+
|
4
|
+
if RUBY_VERSION >= '1.9'
|
5
|
+
# This 1.9 only regex can save a reasonable amount of time (~20%)
|
6
|
+
# by not matching "\r\n" so the string is returned unchanged in
|
7
|
+
# the common case.
|
8
|
+
CRLF_REGEX = Regexp.new("(?<!\r)\n|\r(?!\n)")
|
9
|
+
else
|
10
|
+
CRLF_REGEX = /\n|\r\n|\r/
|
11
|
+
end
|
12
|
+
|
3
13
|
def to_crlf
|
4
|
-
to_str.gsub(
|
14
|
+
to_str.gsub(CRLF_REGEX, "\r\n")
|
5
15
|
end
|
6
16
|
|
7
17
|
def to_lf
|
8
|
-
to_str.gsub(/\
|
18
|
+
to_str.gsub(/\r\n|\r/, "\n")
|
9
19
|
end
|
10
20
|
|
11
21
|
unless String.instance_methods(false).map {|m| m.to_sym}.include?(:blank?)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mail
|
3
3
|
class Address
|
4
|
-
|
4
|
+
|
5
5
|
include Mail::Utilities
|
6
6
|
|
7
7
|
# Mail::Address handles all email addresses in Mail. It takes an email address string
|
@@ -22,21 +22,19 @@ module Mail
|
|
22
22
|
# a.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
23
23
|
def initialize(value = nil)
|
24
24
|
@output_type = :decode
|
25
|
-
|
26
|
-
@raw_text = value
|
27
|
-
case
|
28
|
-
when value.nil?
|
25
|
+
if value.nil?
|
29
26
|
@parsed = false
|
27
|
+
@data = nil
|
30
28
|
return
|
31
29
|
else
|
32
30
|
parse(value)
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
36
|
-
# Returns the raw
|
34
|
+
# Returns the raw input of the passed in string, this is before it is passed
|
37
35
|
# by the parser.
|
38
36
|
def raw
|
39
|
-
@
|
37
|
+
@data.raw
|
40
38
|
end
|
41
39
|
|
42
40
|
# Returns a correctly formatted address for the email going out. If given
|
@@ -48,15 +46,14 @@ module Mail
|
|
48
46
|
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
49
47
|
def format
|
50
48
|
parse unless @parsed
|
51
|
-
|
52
|
-
when tree.nil?
|
49
|
+
if @data.nil?
|
53
50
|
''
|
54
|
-
|
51
|
+
elsif display_name
|
55
52
|
[quote_phrase(display_name), "<#{address}>", format_comments].compact.join(" ")
|
56
|
-
|
53
|
+
elsif address
|
57
54
|
[address, format_comments].compact.join(" ")
|
58
55
|
else
|
59
|
-
|
56
|
+
raw
|
60
57
|
end
|
61
58
|
end
|
62
59
|
|
@@ -106,7 +103,7 @@ module Mail
|
|
106
103
|
# a.local #=> 'mikel'
|
107
104
|
def local
|
108
105
|
parse unless @parsed
|
109
|
-
"#{obs_domain_list}#{get_local.strip}" if get_local
|
106
|
+
"#{@data.obs_domain_list}#{get_local.strip}" if get_local
|
110
107
|
end
|
111
108
|
|
112
109
|
# Returns the domain part (the right hand side of the @ sign in the email address) of
|
@@ -174,29 +171,24 @@ module Mail
|
|
174
171
|
|
175
172
|
def parse(value = nil)
|
176
173
|
@parsed = true
|
177
|
-
|
178
|
-
|
174
|
+
|
175
|
+
case value
|
176
|
+
when NilClass
|
177
|
+
@data = nil
|
179
178
|
nil
|
180
|
-
when
|
181
|
-
|
182
|
-
|
183
|
-
|
179
|
+
when Mail::Parsers::AddressStruct
|
180
|
+
@data = value
|
181
|
+
when String
|
182
|
+
@raw_text = value
|
183
|
+
if value.blank?
|
184
|
+
@data = nil
|
185
|
+
else
|
186
|
+
address_list = Mail::Parsers::AddressListsParser.new.parse(value)
|
187
|
+
@data = address_list.addresses.first
|
188
|
+
end
|
184
189
|
end
|
185
190
|
end
|
186
191
|
|
187
|
-
|
188
|
-
def get_domain
|
189
|
-
if tree.respond_to?(:angle_addr) && tree.angle_addr.respond_to?(:addr_spec) && tree.angle_addr.addr_spec.respond_to?(:domain)
|
190
|
-
@domain_text ||= tree.angle_addr.addr_spec.domain.text_value.strip
|
191
|
-
elsif tree.respond_to?(:domain)
|
192
|
-
@domain_text ||= tree.domain.text_value.strip
|
193
|
-
elsif tree.respond_to?(:addr_spec) && tree.addr_spec.respond_to?(:domain)
|
194
|
-
tree.addr_spec.domain.text_value.strip
|
195
|
-
else
|
196
|
-
nil
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
192
|
def strip_all_comments(string)
|
201
193
|
unless comments.blank?
|
202
194
|
comments.each do |comment|
|
@@ -209,7 +201,7 @@ module Mail
|
|
209
201
|
def strip_domain_comments(value)
|
210
202
|
unless comments.blank?
|
211
203
|
comments.each do |comment|
|
212
|
-
if
|
204
|
+
if @data.domain && @data.domain.include?("(#{comment})")
|
213
205
|
value = value.gsub("(#{comment})", '')
|
214
206
|
end
|
215
207
|
end
|
@@ -217,20 +209,11 @@ module Mail
|
|
217
209
|
value.to_s.strip
|
218
210
|
end
|
219
211
|
|
220
|
-
def get_comments
|
221
|
-
if tree.respond_to?(:comments)
|
222
|
-
@comments = tree.comments.map { |c| unparen(c.text_value.to_str) }
|
223
|
-
else
|
224
|
-
@comments = []
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
212
|
def get_display_name
|
229
|
-
if
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
if domain
|
213
|
+
if @data.display_name
|
214
|
+
str = strip_all_comments(@data.display_name.to_s)
|
215
|
+
elsif @data.comments
|
216
|
+
if @data.domain
|
234
217
|
str = strip_domain_comments(format_comments)
|
235
218
|
else
|
236
219
|
str = nil
|
@@ -263,15 +246,6 @@ module Mail
|
|
263
246
|
end
|
264
247
|
end
|
265
248
|
|
266
|
-
# Provides access to the Treetop parse tree for this address
|
267
|
-
def tree
|
268
|
-
@tree
|
269
|
-
end
|
270
|
-
|
271
|
-
def tree=(value)
|
272
|
-
@tree = value
|
273
|
-
end
|
274
|
-
|
275
249
|
def format_comments
|
276
250
|
if comments
|
277
251
|
comment_text = comments.map {|c| escape_paren(c) }.join(' ').squeeze(" ")
|
@@ -280,35 +254,17 @@ module Mail
|
|
280
254
|
nil
|
281
255
|
end
|
282
256
|
end
|
283
|
-
|
284
|
-
def obs_domain_list
|
285
|
-
if tree.respond_to?(:angle_addr)
|
286
|
-
obs = tree.angle_addr.elements.select { |e| e.respond_to?(:obs_domain_list) }
|
287
|
-
!obs.empty? ? obs.first.text_value : nil
|
288
|
-
else
|
289
|
-
nil
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
257
|
+
|
293
258
|
def get_local
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
when tree.respond_to?(:addr_spec) && tree.addr_spec.respond_to?(:local_part)
|
300
|
-
tree.addr_spec.local_part.text_value
|
301
|
-
when tree.respond_to?(:angle_addr) && tree.angle_addr.respond_to?(:addr_spec) && tree.angle_addr.addr_spec.respond_to?(:local_dot_atom_text)
|
302
|
-
# Ignore local dot atom text when in angle brackets
|
303
|
-
nil
|
304
|
-
when tree.respond_to?(:addr_spec) && tree.addr_spec.respond_to?(:local_dot_atom_text)
|
305
|
-
# Ignore local dot atom text when in angle brackets
|
306
|
-
nil
|
307
|
-
else
|
308
|
-
tree && tree.respond_to?(:local_part) ? tree.local_part.text_value : nil
|
309
|
-
end
|
259
|
+
@data && @data.local
|
260
|
+
end
|
261
|
+
|
262
|
+
def get_domain
|
263
|
+
@data && @data.domain
|
310
264
|
end
|
311
265
|
|
312
|
-
|
266
|
+
def get_comments
|
267
|
+
@data && @data.comments
|
268
|
+
end
|
313
269
|
end
|
314
270
|
end
|