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.
- 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
|