mail 2.6.6 → 2.7.1
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 +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +74 -90
- data/lib/mail/attachments_list.rb +8 -4
- data/lib/mail/body.rb +50 -38
- data/lib/mail/check_delivery_params.rb +8 -6
- data/lib/mail/configuration.rb +2 -0
- data/lib/mail/constants.rb +1 -1
- data/lib/mail/core_extensions/smtp.rb +19 -16
- data/lib/mail/core_extensions/string.rb +0 -4
- data/lib/mail/elements/address.rb +28 -22
- data/lib/mail/elements/address_list.rb +10 -18
- data/lib/mail/elements/content_disposition_element.rb +8 -15
- data/lib/mail/elements/content_location_element.rb +5 -10
- data/lib/mail/elements/content_transfer_encoding_element.rb +5 -10
- data/lib/mail/elements/content_type_element.rb +8 -19
- data/lib/mail/elements/date_time_element.rb +6 -14
- data/lib/mail/elements/envelope_from_element.rb +14 -21
- data/lib/mail/elements/message_ids_element.rb +8 -12
- data/lib/mail/elements/mime_version_element.rb +6 -14
- data/lib/mail/elements/phrase_list.rb +6 -9
- data/lib/mail/elements/received_element.rb +9 -15
- data/lib/mail/encodings/7bit.rb +5 -15
- data/lib/mail/encodings/8bit.rb +2 -21
- data/lib/mail/encodings/base64.rb +11 -12
- data/lib/mail/encodings/binary.rb +3 -22
- data/lib/mail/encodings/identity.rb +24 -0
- data/lib/mail/encodings/quoted_printable.rb +6 -6
- data/lib/mail/encodings/transfer_encoding.rb +38 -29
- data/lib/mail/encodings/unix_to_unix.rb +3 -1
- data/lib/mail/encodings.rb +99 -43
- data/lib/mail/envelope.rb +1 -1
- data/lib/mail/field.rb +96 -59
- data/lib/mail/fields/bcc_field.rb +2 -2
- data/lib/mail/fields/cc_field.rb +1 -1
- data/lib/mail/fields/comments_field.rb +1 -1
- data/lib/mail/fields/common/common_address.rb +32 -7
- data/lib/mail/fields/common/common_field.rb +1 -10
- data/lib/mail/fields/common/parameter_hash.rb +1 -1
- data/lib/mail/fields/content_description_field.rb +1 -1
- data/lib/mail/fields/content_disposition_field.rb +3 -3
- data/lib/mail/fields/content_id_field.rb +2 -2
- data/lib/mail/fields/content_location_field.rb +1 -1
- data/lib/mail/fields/content_transfer_encoding_field.rb +1 -1
- data/lib/mail/fields/content_type_field.rb +4 -9
- data/lib/mail/fields/date_field.rb +2 -3
- data/lib/mail/fields/from_field.rb +1 -1
- data/lib/mail/fields/in_reply_to_field.rb +1 -1
- data/lib/mail/fields/keywords_field.rb +1 -1
- data/lib/mail/fields/message_id_field.rb +1 -1
- data/lib/mail/fields/mime_version_field.rb +1 -1
- data/lib/mail/fields/optional_field.rb +4 -1
- data/lib/mail/fields/received_field.rb +1 -1
- data/lib/mail/fields/references_field.rb +1 -1
- data/lib/mail/fields/reply_to_field.rb +1 -1
- data/lib/mail/fields/resent_bcc_field.rb +1 -1
- data/lib/mail/fields/resent_cc_field.rb +1 -1
- data/lib/mail/fields/resent_date_field.rb +0 -1
- data/lib/mail/fields/resent_from_field.rb +1 -1
- data/lib/mail/fields/resent_message_id_field.rb +1 -1
- data/lib/mail/fields/resent_sender_field.rb +1 -1
- data/lib/mail/fields/resent_to_field.rb +1 -1
- data/lib/mail/fields/return_path_field.rb +1 -1
- data/lib/mail/fields/sender_field.rb +1 -1
- data/lib/mail/fields/subject_field.rb +1 -1
- data/lib/mail/fields/to_field.rb +1 -1
- data/lib/mail/fields/unstructured_field.rb +21 -4
- data/lib/mail/header.rb +10 -8
- data/lib/mail/mail.rb +2 -10
- data/lib/mail/matchers/has_sent_mail.rb +21 -1
- data/lib/mail/message.rb +78 -68
- data/lib/mail/multibyte/chars.rb +29 -28
- data/lib/mail/multibyte/unicode.rb +10 -10
- data/lib/mail/multibyte.rb +64 -15
- data/lib/mail/network/delivery_methods/logger_delivery.rb +37 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +8 -5
- data/lib/mail/network/delivery_methods/smtp.rb +58 -49
- data/lib/mail/network/delivery_methods/smtp_connection.rb +9 -1
- data/lib/mail/network/retriever_methods/imap.rb +18 -5
- data/lib/mail/network/retriever_methods/pop3.rb +3 -1
- data/lib/mail/network.rb +1 -0
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +33207 -104
- data/lib/mail/parsers/address_lists_parser.rl +172 -0
- data/lib/mail/parsers/content_disposition_parser.rb +876 -49
- data/lib/mail/parsers/content_disposition_parser.rl +82 -0
- data/lib/mail/parsers/content_location_parser.rb +803 -23
- data/lib/mail/parsers/content_location_parser.rl +71 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +501 -19
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +64 -0
- data/lib/mail/parsers/content_type_parser.rb +1023 -48
- data/lib/mail/parsers/content_type_parser.rl +83 -0
- data/lib/mail/parsers/date_time_parser.rb +870 -24
- data/lib/mail/parsers/date_time_parser.rl +62 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3569 -34
- data/lib/mail/parsers/envelope_from_parser.rl +82 -0
- data/lib/mail/parsers/message_ids_parser.rb +2839 -25
- data/lib/mail/parsers/message_ids_parser.rl +82 -0
- data/lib/mail/parsers/mime_version_parser.rb +491 -26
- data/lib/mail/parsers/mime_version_parser.rl +61 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +860 -18
- data/lib/mail/parsers/phrase_lists_parser.rl +83 -0
- data/lib/mail/parsers/received_parser.rb +8764 -37
- data/lib/mail/parsers/received_parser.rl +84 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
- data/lib/mail/parsers/rfc2045_mime.rl +16 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
- data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
- data/lib/mail/parsers/rfc5322.rl +59 -0
- data/lib/mail/parsers/rfc5322_address.rl +72 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/lib/mail/parsers.rb +16 -24
- data/lib/mail/part.rb +3 -3
- data/lib/mail/parts_list.rb +5 -6
- data/lib/mail/utilities.rb +59 -28
- data/lib/mail/version.rb +2 -2
- data/lib/mail/version_specific/ruby_1_8.rb +40 -3
- data/lib/mail/version_specific/ruby_1_9.rb +61 -9
- data/lib/mail.rb +3 -16
- metadata +44 -53
- data/CHANGELOG.rdoc +0 -803
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -2
- data/Gemfile +0 -14
- data/Rakefile +0 -29
- data/TODO.rdoc +0 -9
- data/lib/mail/core_extensions/string/access.rb +0 -146
- data/lib/mail/core_extensions/string/multibyte.rb +0 -79
- data/lib/mail/multibyte/exceptions.rb +0 -9
- data/lib/mail/parsers/ragel/common.rl +0 -185
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
- data/lib/mail/parsers/ragel/ruby.rb +0 -40
- data/lib/mail/parsers/ragel.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2e806bc9b7c6c6df8de9c9dc80b4cf3a099bad3153f568d0ee4d9287cd34a014
|
4
|
+
data.tar.gz: 182ed03957858cce70691eb79543f13d53e4ddf43684bf50bc011e904d3a84ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c42702e6529565ae63c486fef492b89a19eb394fb6fe5aaf004862257ef3d840579a3cabb95dd2075ddbc617e077110684d8f47052e51d0435b94ef4a2373c3
|
7
|
+
data.tar.gz: 31278e7d48271cfec8541d1094fedd1cc62578a6d9f18e0eafd09ebcac4e5edf3e78a3b902aca3e97d7416d37b0f0c07ba2dde2f5462d6317058552bbc0dbfe7
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
Mail [](https://travis-ci.org/mikel/mail)
|
2
|
-
====
|
1
|
+
# Mail [](https://travis-ci.org/mikel/mail)
|
3
2
|
|
4
|
-
Introduction
|
5
|
-
------------
|
3
|
+
## Introduction
|
6
4
|
|
7
5
|
Mail is an internet library for Ruby that is designed to handle emails
|
8
6
|
generation, parsing and sending in a simple, rubyesque manner.
|
@@ -25,8 +23,7 @@ Finally, Mail has been designed with a very simple object oriented system
|
|
25
23
|
that really opens up the email messages you are parsing, if you know what
|
26
24
|
you are doing, you can fiddle with every last bit of your email directly.
|
27
25
|
|
28
|
-
Donations
|
29
|
-
-------------
|
26
|
+
## Donations
|
30
27
|
|
31
28
|
Mail has been downloaded millions of times, by people around the world, in fact,
|
32
29
|
it represents more than 1% of *all* gems downloaded.
|
@@ -38,44 +35,48 @@ me a nice email :)
|
|
38
35
|
|
39
36
|
<a href='http://www.pledgie.com/campaigns/8790'><img alt='Click here to lend your support to: mail and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/8790.png?skin_name=chrome' border='0' /></a>
|
40
37
|
|
41
|
-
|
42
|
-
Compatibility
|
43
|
-
|
38
|
+
# Contents
|
39
|
+
* [Compatibility](#compatibility)
|
40
|
+
* [Discussion](#discussion)
|
41
|
+
* [Current Capabilities of Mail](#current-capabilities-of-mail)
|
42
|
+
* [Roadmap](#roadmap)
|
43
|
+
* [Testing Policy](#testing-policy)
|
44
|
+
* [API Policy](#api-policy)
|
45
|
+
* [Installation](#installation)
|
46
|
+
* [Encodings](#encodings)
|
47
|
+
* [Contributing](#contributing)
|
48
|
+
* [Usage](#usage)
|
49
|
+
* [Core Extensions](#core-extensions)
|
50
|
+
* [Excerpts from TREC Span Corpus 2005](#excerpts-from-trec-span-corpus-2005)
|
51
|
+
* [License](#license)
|
52
|
+
|
53
|
+
## Compatibility
|
44
54
|
|
45
55
|
Mail supports Ruby 1.8.7+, including JRuby and Rubinius.
|
46
56
|
|
47
57
|
Every Mail commit is tested by Travis on [all supported Ruby versions](https://github.com/mikel/mail/blob/master/.travis.yml).
|
48
58
|
|
49
|
-
|
50
|
-
|
51
|
-
```sh
|
52
|
-
BUNDLE_GEMFILE=gemfiles/mime_types_1.16.gemfile bundle && rake
|
53
|
-
```
|
54
|
-
|
55
|
-
Discussion
|
56
|
-
----------
|
59
|
+
## Discussion
|
57
60
|
|
58
61
|
If you want to discuss mail with like minded individuals, please subscribe to
|
59
62
|
the [Google Group](http://groups.google.com/group/mail-ruby).
|
60
63
|
|
61
|
-
Current Capabilities of Mail
|
62
|
-
----------------------------
|
64
|
+
## Current Capabilities of Mail
|
63
65
|
|
64
|
-
*
|
66
|
+
* RFC5322 Support, Reading and Writing
|
67
|
+
* RFC6532 Support, reading UTF-8 headers
|
65
68
|
* RFC2045-2049 Support for multipart emails
|
66
69
|
* Support for creating multipart alternate emails
|
67
70
|
* Support for reading multipart/report emails & getting details from such
|
68
|
-
* Support for multibyte emails - needs quite a lot of work and testing
|
69
71
|
* Wrappers for File, Net/POP3, Net/SMTP
|
70
|
-
* Auto
|
71
|
-
* Auto encoding of non US-ASCII bodies
|
72
|
+
* Auto-encoding of non-US-ASCII bodies and header fields
|
72
73
|
|
73
|
-
Mail is
|
74
|
-
emails.
|
75
|
-
it also is quite robust, meaning, if it finds something
|
76
|
-
not crash, instead, it will skip the problem and keep
|
77
|
-
it doesn't understand, it will initialise the header
|
78
|
-
field and continue parsing.
|
74
|
+
Mail is RFC5322 and RFC6532 compliant now, that is, it can parse US-ASCII and UTF-8
|
75
|
+
emails and generate US-ASCII emails. There are a few obsoleted syntax emails that
|
76
|
+
it will have problems with, but it also is quite robust, meaning, if it finds something
|
77
|
+
it doesn't understand it will not crash, instead, it will skip the problem and keep
|
78
|
+
parsing. In the case of a header it doesn't understand, it will initialise the header
|
79
|
+
as an optional unstructured field and continue parsing.
|
79
80
|
|
80
81
|
This means Mail won't (ever) crunch your data (I think).
|
81
82
|
|
@@ -83,16 +84,14 @@ You can also create MIME emails. There are helper methods for making a
|
|
83
84
|
multipart/alternate email for text/plain and text/html (the most common pair)
|
84
85
|
and you can manually create any other type of MIME email.
|
85
86
|
|
86
|
-
Roadmap
|
87
|
-
-------
|
87
|
+
## Roadmap
|
88
88
|
|
89
89
|
Next TODO:
|
90
90
|
|
91
91
|
* Improve MIME support for character sets in headers, currently works, mostly, needs
|
92
92
|
refinement.
|
93
93
|
|
94
|
-
Testing Policy
|
95
|
-
--------------
|
94
|
+
## Testing Policy
|
96
95
|
|
97
96
|
Basically... we do BDD on Mail. No method gets written in Mail without a
|
98
97
|
corresponding or covering spec. We expect as a minimum 100% coverage
|
@@ -104,23 +103,20 @@ It also means you can be sure Mail will behave correctly.
|
|
104
103
|
|
105
104
|
Note: If you care about core extensions (aka "monkey-patching"), please read the Core Extensions section near the end of this README.
|
106
105
|
|
107
|
-
API Policy
|
108
|
-
----------
|
106
|
+
## API Policy
|
109
107
|
|
110
108
|
No API removals within a single point release. All removals to be deprecated with
|
111
109
|
warnings for at least one MINOR point release before removal.
|
112
110
|
|
113
111
|
Also, all private or protected methods to be declared as such - though this is still I/P.
|
114
112
|
|
115
|
-
Installation
|
116
|
-
------------
|
113
|
+
## Installation
|
117
114
|
|
118
115
|
Installation is fairly simple, I host mail on rubygems, so you can just do:
|
119
116
|
|
120
117
|
# gem install mail
|
121
118
|
|
122
|
-
Encodings
|
123
|
-
---------
|
119
|
+
## Encodings
|
124
120
|
|
125
121
|
If you didn't know, handling encodings in Emails is not as straight forward as you
|
126
122
|
would hope.
|
@@ -152,13 +148,11 @@ I have tried to simplify it some:
|
|
152
148
|
provide encoded parameter values when you call the parameter names through the
|
153
149
|
<code>object.parameters['<parameter_name>']</code> method call.
|
154
150
|
|
155
|
-
Contributing
|
156
|
-
------------
|
151
|
+
## Contributing
|
157
152
|
|
158
153
|
Please do! Contributing is easy in Mail. Please read the CONTRIBUTING.md document for more info
|
159
154
|
|
160
|
-
Usage
|
161
|
-
-----
|
155
|
+
## Usage
|
162
156
|
|
163
157
|
All major mail functions should be able to happen from the Mail module.
|
164
158
|
So, you should be able to just <code>require 'mail'</code> to get started.
|
@@ -226,7 +220,7 @@ what you are doing.
|
|
226
220
|
### Sending an email:
|
227
221
|
|
228
222
|
Mail defaults to sending via SMTP to local host port 25. If you have a
|
229
|
-
sendmail or postfix daemon running on
|
223
|
+
sendmail or postfix daemon running on this port, sending email is as
|
230
224
|
easy as:
|
231
225
|
|
232
226
|
```ruby
|
@@ -286,7 +280,17 @@ mail.delivery_method :exim, :location => "/usr/bin/exim"
|
|
286
280
|
mail.deliver
|
287
281
|
```
|
288
282
|
|
289
|
-
|
283
|
+
Mail may be "delivered" to a logfile, too, for development and testing:
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
# Delivers by logging the encoded message to $stdout
|
287
|
+
mail.delivery_method :logger
|
288
|
+
|
289
|
+
# Delivers to an existing logger at :debug severity
|
290
|
+
mail.delivery_method :logger, logger: other_logger, severity: :debug
|
291
|
+
```
|
292
|
+
|
293
|
+
### Getting Emails from a POP Server:
|
290
294
|
|
291
295
|
You can configure Mail to receive email using <code>retriever_method</code>
|
292
296
|
within <code>Mail.defaults</code>:
|
@@ -339,7 +343,7 @@ mail.cc #=> 'sam@test.lindsaar.net'
|
|
339
343
|
mail.subject #=> "This is the subject"
|
340
344
|
mail.date.to_s #=> '21 Nov 1997 09:55:06 -0600'
|
341
345
|
mail.message_id #=> '<4D6AA7EB.6490534@xxx.xxx>'
|
342
|
-
mail.
|
346
|
+
mail.decoded #=> 'This is the body of the email...
|
343
347
|
```
|
344
348
|
|
345
349
|
Many more methods available.
|
@@ -365,7 +369,7 @@ is another message which can have many or no parts.
|
|
365
369
|
A message will only have parts if it is a multipart/mixed or multipart/related
|
366
370
|
content type and has a boundary defined.
|
367
371
|
|
368
|
-
### Testing and
|
372
|
+
### Testing and Extracting Attachments
|
369
373
|
```ruby
|
370
374
|
mail.attachments.each do | attachment |
|
371
375
|
# Attachments is an AttachmentsList object containing a
|
@@ -374,14 +378,14 @@ mail.attachments.each do | attachment |
|
|
374
378
|
# extracting images for example...
|
375
379
|
filename = attachment.filename
|
376
380
|
begin
|
377
|
-
File.open(images_dir + filename, "w+b", 0644) {|f| f.write attachment.
|
381
|
+
File.open(images_dir + filename, "w+b", 0644) {|f| f.write attachment.decoded}
|
378
382
|
rescue => e
|
379
383
|
puts "Unable to save data for #{filename} because #{e.message}"
|
380
384
|
end
|
381
385
|
end
|
382
386
|
end
|
383
387
|
```
|
384
|
-
### Writing and
|
388
|
+
### Writing and Sending a Multipart/Alternative (HTML and Text) Email
|
385
389
|
|
386
390
|
Mail makes some basic assumptions and makes doing the common thing as
|
387
391
|
simple as possible.... (asking a lot from a mail library)
|
@@ -447,7 +451,7 @@ Mail assumes that if your text in the body is only us-ascii, that your
|
|
447
451
|
transfer encoding is 7bit and it is text/plain. You can override this
|
448
452
|
by explicitly declaring it.
|
449
453
|
|
450
|
-
### Making Multipart/Alternate,
|
454
|
+
### Making Multipart/Alternate, Without a Block
|
451
455
|
|
452
456
|
You don't have to use a block with the text and html part included, you
|
453
457
|
can just do it declaratively. However, you need to add Mail::Parts to
|
@@ -475,7 +479,7 @@ mail.html_part = html_part
|
|
475
479
|
|
476
480
|
Results in the same email as done using the block form
|
477
481
|
|
478
|
-
### Getting
|
482
|
+
### Getting Error Reports from an Email:
|
479
483
|
|
480
484
|
```ruby
|
481
485
|
@mail = Mail.read('/path/to/bounce_message.eml')
|
@@ -519,7 +523,6 @@ than mail (this should be rarely needed)
|
|
519
523
|
|
520
524
|
```ruby
|
521
525
|
@mail = Mail.new
|
522
|
-
file_data = File.read('path/to/myfile.pdf')
|
523
526
|
@mail.attachments['myfile.pdf'] = { :mime_type => 'application/x-pdf',
|
524
527
|
:content => File.read('path/to/myfile.pdf') }
|
525
528
|
@mail.parts.first.mime_type #=> 'application/x-pdf'
|
@@ -552,8 +555,7 @@ end
|
|
552
555
|
```
|
553
556
|
See "Testing and extracting attachments" above for more details.
|
554
557
|
|
555
|
-
Using Mail with Testing or Spec'ing Libraries
|
556
|
-
---------------------------------------------
|
558
|
+
## Using Mail with Testing or Spec'ing Libraries
|
557
559
|
|
558
560
|
If mail is part of your system, you'll need a way to test it without actually
|
559
561
|
sending emails, the TestMailer can do this for you.
|
@@ -603,70 +605,53 @@ describe "sending an email" do
|
|
603
605
|
end
|
604
606
|
end
|
605
607
|
|
606
|
-
it {
|
608
|
+
it { is_expected.to have_sent_email } # passes if any email at all was sent
|
607
609
|
|
608
|
-
it {
|
609
|
-
it {
|
610
|
+
it { is_expected.to have_sent_email.from('you@you.com') }
|
611
|
+
it { is_expected.to have_sent_email.to('mike1@me.com') }
|
610
612
|
|
611
613
|
# can specify a list of recipients...
|
612
|
-
it {
|
614
|
+
it { is_expected.to have_sent_email.to(['mike1@me.com', 'mike2@me.com']) }
|
613
615
|
|
614
616
|
# ...or chain recipients together
|
615
|
-
it {
|
617
|
+
it { is_expected.to have_sent_email.to('mike1@me.com').to('mike2@me.com') }
|
616
618
|
|
617
|
-
it {
|
619
|
+
it { is_expected.to have_sent_email.with_subject('testing') }
|
618
620
|
|
619
|
-
it {
|
621
|
+
it { is_expected.to have_sent_email.with_body('hello') }
|
620
622
|
|
621
623
|
# Can match subject or body with a regex
|
622
624
|
# (or anything that responds_to? :match)
|
623
625
|
|
624
|
-
it {
|
625
|
-
it {
|
626
|
+
it { is_expected.to have_sent_email.matching_subject(/test(ing)?/) }
|
627
|
+
it { is_expected.to have_sent_email.matching_body(/h(a|e)llo/) }
|
626
628
|
|
627
629
|
# Can chain together modifiers
|
628
630
|
# Note that apart from recipients, repeating a modifier overwrites old value.
|
629
631
|
|
630
|
-
it {
|
632
|
+
it { is_expected.to have_sent_email.from('you@you.com').to('mike1@me.com').matching_body(/hell/)
|
631
633
|
|
632
634
|
# test for attachments
|
633
635
|
|
634
636
|
# ... by specific attachment
|
635
|
-
it {
|
637
|
+
it { is_expected.to have_sent_email.with_attachments(my_attachment) }
|
636
638
|
|
637
639
|
# ... or any attachment
|
638
|
-
it {
|
640
|
+
it { is_expected.to have_sent_email.with_attachments(any_attachment) }
|
639
641
|
|
640
642
|
# ... by array of attachments
|
641
|
-
it {
|
643
|
+
it { is_expected.to have_sent_email.with_attachments([my_attachment1, my_attachment2]) } #note that order is important
|
642
644
|
|
643
645
|
#... by presence
|
644
|
-
it {
|
646
|
+
it { is_expected.to have_sent_email.with_any_attachments }
|
645
647
|
|
646
648
|
#... or by absence
|
647
|
-
it {
|
649
|
+
it { is_expected.to have_sent_email.with_no_attachments }
|
648
650
|
|
649
651
|
end
|
650
652
|
```
|
651
653
|
|
652
|
-
|
653
|
-
---------------
|
654
|
-
|
655
|
-
The mail gem adds several constants and methods to Ruby's core objects (similar to the activesupport gem from the Rails project). For example:
|
656
|
-
|
657
|
-
NilClass::blank?
|
658
|
-
NilClass::to_crlf
|
659
|
-
NilClass::to_lf
|
660
|
-
Object::blank?
|
661
|
-
String::to_crlf
|
662
|
-
String::to_lf
|
663
|
-
String::blank?
|
664
|
-
...etc...
|
665
|
-
|
666
|
-
For all the details, check out lib/mail/core_extensions/.
|
667
|
-
|
668
|
-
Excerpts from TREC Spam Corpus 2005
|
669
|
-
-----------------------------------
|
654
|
+
## Excerpts from TREC Spam Corpus 2005
|
670
655
|
|
671
656
|
The spec fixture files in spec/fixtures/emails/from_trec_2005 are from the
|
672
657
|
2005 TREC Public Spam Corpus. They remain copyrighted under the terms of
|
@@ -684,12 +669,11 @@ They are used as allowed by 'Permitted Uses, Clause 3':
|
|
684
669
|
|
685
670
|
-- http://plg.uwaterloo.ca/~gvcormac/treccorpus/
|
686
671
|
|
687
|
-
License
|
688
|
-
-------
|
672
|
+
## License
|
689
673
|
|
690
674
|
(The MIT License)
|
691
675
|
|
692
|
-
Copyright (c) 2009-
|
676
|
+
Copyright (c) 2009-2016 Mikel Lindsaar
|
693
677
|
|
694
678
|
Permission is hereby granted, free of charge, to any person obtaining
|
695
679
|
a copy of this software and associated documentation files (the
|
@@ -6,8 +6,8 @@ module Mail
|
|
6
6
|
@parts_list = parts_list
|
7
7
|
@content_disposition_type = 'attachment'
|
8
8
|
parts_list.map { |p|
|
9
|
-
if p.
|
10
|
-
Mail.new(p.body).attachments
|
9
|
+
if p.mime_type == 'message/rfc822'
|
10
|
+
Mail.new(p.body.encoded).attachments
|
11
11
|
elsif p.parts.empty?
|
12
12
|
p if p.attachment?
|
13
13
|
else
|
@@ -44,6 +44,9 @@ module Mail
|
|
44
44
|
:content_disposition => "#{@content_disposition_type}; filename=\"#{encoded_name}\"" }
|
45
45
|
|
46
46
|
if value.is_a?(Hash)
|
47
|
+
if path = value.delete(:filename)
|
48
|
+
value[:content] ||= File.open(path, 'rb') { |f| f.read }
|
49
|
+
end
|
47
50
|
|
48
51
|
default_values[:body] = value.delete(:content) if value[:content]
|
49
52
|
|
@@ -60,7 +63,7 @@ module Mail
|
|
60
63
|
|
61
64
|
if value[:mime_type]
|
62
65
|
default_values[:content_type] = value.delete(:mime_type)
|
63
|
-
@mime_type =
|
66
|
+
@mime_type = MiniMime.lookup_by_content_type(default_values[:content_type])
|
64
67
|
default_values[:content_transfer_encoding] ||= guess_encoding
|
65
68
|
end
|
66
69
|
|
@@ -99,7 +102,8 @@ module Mail
|
|
99
102
|
filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
|
100
103
|
end
|
101
104
|
|
102
|
-
@mime_type =
|
105
|
+
@mime_type = MiniMime.lookup_by_filename(filename)
|
106
|
+
@mime_type && @mime_type.content_type
|
103
107
|
end
|
104
108
|
|
105
109
|
end
|
data/lib/mail/body.rb
CHANGED
@@ -32,24 +32,24 @@ module Mail
|
|
32
32
|
@preamble = nil
|
33
33
|
@epilogue = nil
|
34
34
|
@charset = nil
|
35
|
-
@part_sort_order = [ "text/plain", "text/enriched", "text/html" ]
|
35
|
+
@part_sort_order = [ "text/plain", "text/enriched", "text/html", "multipart/alternative" ]
|
36
36
|
@parts = Mail::PartsList.new
|
37
37
|
if Utilities.blank?(string)
|
38
38
|
@raw_source = ''
|
39
39
|
else
|
40
40
|
# Do join first incase we have been given an Array in Ruby 1.9
|
41
41
|
if string.respond_to?(:join)
|
42
|
-
@raw_source = string.join('')
|
42
|
+
@raw_source = ::Mail::Utilities.to_crlf(string.join(''))
|
43
43
|
elsif string.respond_to?(:to_s)
|
44
|
-
@raw_source = string.to_s
|
44
|
+
@raw_source = ::Mail::Utilities.to_crlf(string.to_s)
|
45
45
|
else
|
46
46
|
raise "You can only assign a string or an object that responds_to? :join or :to_s to a body."
|
47
47
|
end
|
48
48
|
end
|
49
|
-
@encoding =
|
49
|
+
@encoding = default_encoding
|
50
50
|
set_charset
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# Matches this body with another body. Also matches the decoded value of this
|
54
54
|
# body with a string.
|
55
55
|
#
|
@@ -115,8 +115,8 @@ module Mail
|
|
115
115
|
end
|
116
116
|
|
117
117
|
# Allows you to set the sort order of the parts, overriding the default sort order.
|
118
|
-
# Defaults to 'text/plain', then 'text/enriched', then 'text/html'
|
119
|
-
# type coming after.
|
118
|
+
# Defaults to 'text/plain', then 'text/enriched', then 'text/html', then 'multipart/alternative'
|
119
|
+
# with any other content type coming after.
|
120
120
|
def set_sort_order(order)
|
121
121
|
@part_sort_order = order
|
122
122
|
end
|
@@ -138,41 +138,45 @@ module Mail
|
|
138
138
|
def raw_source
|
139
139
|
@raw_source
|
140
140
|
end
|
141
|
-
|
142
|
-
def
|
143
|
-
|
144
|
-
target_encoding.get_best_compatible(encoding, raw_source)
|
141
|
+
|
142
|
+
def negotiate_best_encoding(message_encoding, allowed_encodings = nil)
|
143
|
+
Mail::Encodings::TransferEncoding.negotiate(message_encoding, encoding, raw_source, allowed_encodings)
|
145
144
|
end
|
146
|
-
|
145
|
+
|
147
146
|
# Returns a body encoded using transfer_encoding. Multipart always uses an
|
148
147
|
# identiy encoding (i.e. no encoding).
|
149
148
|
# Calling this directly is not a good idea, but supported for compatibility
|
150
149
|
# TODO: Validate that preamble and epilogue are valid for requested encoding
|
151
|
-
def encoded(transfer_encoding =
|
150
|
+
def encoded(transfer_encoding = nil)
|
152
151
|
if multipart?
|
153
152
|
self.sort_parts!
|
154
153
|
encoded_parts = parts.map { |p| p.encoded }
|
155
154
|
([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
|
156
155
|
else
|
157
|
-
|
158
|
-
|
159
|
-
|
156
|
+
dec = Mail::Encodings.get_encoding(encoding)
|
157
|
+
enc =
|
158
|
+
if Utilities.blank?(transfer_encoding)
|
159
|
+
dec
|
160
|
+
else
|
161
|
+
negotiate_best_encoding(transfer_encoding)
|
162
|
+
end
|
163
|
+
|
160
164
|
if dec.nil?
|
161
|
-
|
162
|
-
|
165
|
+
# Cannot decode, so skip normalization
|
166
|
+
raw_source
|
163
167
|
else
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
168
|
+
# Decode then encode to normalize and allow transforming
|
169
|
+
# from base64 to Q-P and vice versa
|
170
|
+
decoded = dec.decode(raw_source)
|
171
|
+
if defined?(Encoding) && charset && charset != "US-ASCII"
|
172
|
+
decoded = decoded.encode(charset)
|
173
|
+
decoded.force_encoding('BINARY') unless Encoding.find(charset).ascii_compatible?
|
174
|
+
end
|
175
|
+
enc.encode(decoded)
|
172
176
|
end
|
173
177
|
end
|
174
178
|
end
|
175
|
-
|
179
|
+
|
176
180
|
def decoded
|
177
181
|
if !Encodings.defined?(encoding)
|
178
182
|
raise UnknownEncodingType, "Don't know how to decode #{encoding}, please call #encoded and decode it yourself."
|
@@ -200,13 +204,14 @@ module Mail
|
|
200
204
|
@encoding
|
201
205
|
end
|
202
206
|
end
|
203
|
-
|
207
|
+
|
204
208
|
def encoding=( val )
|
205
|
-
@encoding =
|
206
|
-
|
207
|
-
|
209
|
+
@encoding =
|
210
|
+
if val == "text" || Utilities.blank?(val)
|
211
|
+
default_encoding
|
212
|
+
else
|
208
213
|
val
|
209
|
-
|
214
|
+
end
|
210
215
|
end
|
211
216
|
|
212
217
|
# Returns the preamble (any text that is before the first MIME boundary)
|
@@ -268,14 +273,21 @@ module Mail
|
|
268
273
|
self
|
269
274
|
end
|
270
275
|
|
271
|
-
def
|
272
|
-
|
276
|
+
def ascii_only?
|
277
|
+
unless defined? @ascii_only
|
278
|
+
@ascii_only = raw_source.ascii_only?
|
279
|
+
end
|
280
|
+
@ascii_only
|
273
281
|
end
|
274
|
-
|
282
|
+
|
275
283
|
def empty?
|
276
284
|
!!raw_source.to_s.empty?
|
277
285
|
end
|
278
|
-
|
286
|
+
|
287
|
+
def default_encoding
|
288
|
+
ascii_only? ? '7bit' : '8bit'
|
289
|
+
end
|
290
|
+
|
279
291
|
private
|
280
292
|
|
281
293
|
# split parts by boundary, ignore first part if empty, append final part when closing boundary was missing
|
@@ -308,9 +320,9 @@ module Mail
|
|
308
320
|
def end_boundary
|
309
321
|
"\r\n--#{boundary}--\r\n"
|
310
322
|
end
|
311
|
-
|
323
|
+
|
312
324
|
def set_charset
|
313
|
-
|
325
|
+
@charset = ascii_only? ? 'US-ASCII' : nil
|
314
326
|
end
|
315
327
|
end
|
316
328
|
end
|
@@ -33,12 +33,14 @@ module Mail
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def validate_smtp_addr(addr)
|
36
|
-
if addr
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
if addr
|
37
|
+
if addr.bytesize > 2048
|
38
|
+
yield 'may not exceed 2kB'
|
39
|
+
end
|
40
|
+
|
41
|
+
if /[\r\n]/ =~ addr
|
42
|
+
yield 'may not contain CR or LF line breaks'
|
43
|
+
end
|
42
44
|
end
|
43
45
|
|
44
46
|
addr
|
data/lib/mail/configuration.rb
CHANGED
data/lib/mail/constants.rb
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
|
-
module Net
|
4
|
-
class SMTP
|
5
|
-
# This is a backport of r30294 from ruby trunk because of a bug in net/smtp.
|
6
|
-
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30294
|
7
|
-
#
|
8
|
-
# Fixed in what will be Ruby 1.9.3 - tlsconnect also does not exist in some early versions of ruby
|
9
|
-
begin
|
10
|
-
alias_method :original_tlsconnect, :tlsconnect
|
11
3
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
4
|
+
# This is a backport of r30294 from ruby trunk because of a bug in net/smtp.
|
5
|
+
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30294
|
6
|
+
#
|
7
|
+
# Fixed in Ruby 1.9.3 - tlsconnect also does not exist in some early versions of ruby
|
8
|
+
if RUBY_VERSION < '1.9.3'
|
9
|
+
module Net
|
10
|
+
class SMTP
|
11
|
+
begin
|
12
|
+
alias_method :original_tlsconnect, :tlsconnect
|
13
|
+
|
14
|
+
def tlsconnect(s)
|
15
|
+
verified = false
|
16
|
+
begin
|
17
|
+
original_tlsconnect(s).tap { verified = true }
|
18
|
+
ensure
|
19
|
+
unless verified
|
20
|
+
s.close rescue nil
|
21
|
+
end
|
19
22
|
end
|
20
23
|
end
|
24
|
+
rescue NameError
|
21
25
|
end
|
22
|
-
rescue NameError
|
23
26
|
end
|
24
27
|
end
|
25
28
|
end
|