mail 2.6.5 → 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 +75 -102
- data/lib/mail/attachments_list.rb +8 -4
- data/lib/mail/body.rb +50 -38
- data/lib/mail/check_delivery_params.rb +49 -10
- 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/exim.rb +6 -10
- data/lib/mail/network/delivery_methods/file_delivery.rb +4 -8
- data/lib/mail/network/delivery_methods/logger_delivery.rb +37 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +16 -11
- data/lib/mail/network/delivery_methods/smtp.rb +59 -53
- data/lib/mail/network/delivery_methods/smtp_connection.rb +10 -6
- data/lib/mail/network/delivery_methods/test_mailer.rb +5 -8
- 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 -795
- 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,55 +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
|
|
|
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)
|
|
41
52
|
|
|
42
|
-
Compatibility
|
|
43
|
-
-------------
|
|
53
|
+
## Compatibility
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
Mail supports Ruby 1.8.7+, including JRuby and Rubinius.
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
* ruby-1.9.2 [ x86_64 ]
|
|
49
|
-
* ruby-1.9.3 [ x86_64 ]
|
|
50
|
-
* ruby-2.0.0 [ x86_64 ]
|
|
51
|
-
* ruby-2.1.10 [ x86_64 ]
|
|
52
|
-
* ruby-2.2.6 [ x86_64 ]
|
|
53
|
-
* ruby-2.3.3 [ x86_64 ]
|
|
54
|
-
* ruby-head [ x86_64 ]
|
|
55
|
-
* jruby [ x86_64 ]
|
|
56
|
-
* jruby-9.1.6.0 [ x86_64 ]
|
|
57
|
-
* jruby-head [ x86_64 ]
|
|
58
|
-
* rbx-2 [ x86_64 ]
|
|
57
|
+
Every Mail commit is tested by Travis on [all supported Ruby versions](https://github.com/mikel/mail/blob/master/.travis.yml).
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```sh
|
|
63
|
-
BUNDLE_GEMFILE=gemfiles/mime_types_1.16.gemfile (bundle check || bundle) && rake
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Discussion
|
|
67
|
-
----------
|
|
59
|
+
## Discussion
|
|
68
60
|
|
|
69
61
|
If you want to discuss mail with like minded individuals, please subscribe to
|
|
70
62
|
the [Google Group](http://groups.google.com/group/mail-ruby).
|
|
71
63
|
|
|
72
|
-
Current Capabilities of Mail
|
|
73
|
-
----------------------------
|
|
64
|
+
## Current Capabilities of Mail
|
|
74
65
|
|
|
75
|
-
*
|
|
66
|
+
* RFC5322 Support, Reading and Writing
|
|
67
|
+
* RFC6532 Support, reading UTF-8 headers
|
|
76
68
|
* RFC2045-2049 Support for multipart emails
|
|
77
69
|
* Support for creating multipart alternate emails
|
|
78
70
|
* Support for reading multipart/report emails & getting details from such
|
|
79
|
-
* Support for multibyte emails - needs quite a lot of work and testing
|
|
80
71
|
* Wrappers for File, Net/POP3, Net/SMTP
|
|
81
|
-
* Auto
|
|
82
|
-
* Auto encoding of non US-ASCII bodies
|
|
72
|
+
* Auto-encoding of non-US-ASCII bodies and header fields
|
|
83
73
|
|
|
84
|
-
Mail is
|
|
85
|
-
emails.
|
|
86
|
-
it also is quite robust, meaning, if it finds something
|
|
87
|
-
not crash, instead, it will skip the problem and keep
|
|
88
|
-
it doesn't understand, it will initialise the header
|
|
89
|
-
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.
|
|
90
80
|
|
|
91
81
|
This means Mail won't (ever) crunch your data (I think).
|
|
92
82
|
|
|
@@ -94,16 +84,14 @@ You can also create MIME emails. There are helper methods for making a
|
|
|
94
84
|
multipart/alternate email for text/plain and text/html (the most common pair)
|
|
95
85
|
and you can manually create any other type of MIME email.
|
|
96
86
|
|
|
97
|
-
Roadmap
|
|
98
|
-
-------
|
|
87
|
+
## Roadmap
|
|
99
88
|
|
|
100
89
|
Next TODO:
|
|
101
90
|
|
|
102
91
|
* Improve MIME support for character sets in headers, currently works, mostly, needs
|
|
103
92
|
refinement.
|
|
104
93
|
|
|
105
|
-
Testing Policy
|
|
106
|
-
--------------
|
|
94
|
+
## Testing Policy
|
|
107
95
|
|
|
108
96
|
Basically... we do BDD on Mail. No method gets written in Mail without a
|
|
109
97
|
corresponding or covering spec. We expect as a minimum 100% coverage
|
|
@@ -115,23 +103,20 @@ It also means you can be sure Mail will behave correctly.
|
|
|
115
103
|
|
|
116
104
|
Note: If you care about core extensions (aka "monkey-patching"), please read the Core Extensions section near the end of this README.
|
|
117
105
|
|
|
118
|
-
API Policy
|
|
119
|
-
----------
|
|
106
|
+
## API Policy
|
|
120
107
|
|
|
121
108
|
No API removals within a single point release. All removals to be deprecated with
|
|
122
109
|
warnings for at least one MINOR point release before removal.
|
|
123
110
|
|
|
124
111
|
Also, all private or protected methods to be declared as such - though this is still I/P.
|
|
125
112
|
|
|
126
|
-
Installation
|
|
127
|
-
------------
|
|
113
|
+
## Installation
|
|
128
114
|
|
|
129
115
|
Installation is fairly simple, I host mail on rubygems, so you can just do:
|
|
130
116
|
|
|
131
117
|
# gem install mail
|
|
132
118
|
|
|
133
|
-
Encodings
|
|
134
|
-
---------
|
|
119
|
+
## Encodings
|
|
135
120
|
|
|
136
121
|
If you didn't know, handling encodings in Emails is not as straight forward as you
|
|
137
122
|
would hope.
|
|
@@ -163,13 +148,11 @@ I have tried to simplify it some:
|
|
|
163
148
|
provide encoded parameter values when you call the parameter names through the
|
|
164
149
|
<code>object.parameters['<parameter_name>']</code> method call.
|
|
165
150
|
|
|
166
|
-
Contributing
|
|
167
|
-
------------
|
|
151
|
+
## Contributing
|
|
168
152
|
|
|
169
153
|
Please do! Contributing is easy in Mail. Please read the CONTRIBUTING.md document for more info
|
|
170
154
|
|
|
171
|
-
Usage
|
|
172
|
-
-----
|
|
155
|
+
## Usage
|
|
173
156
|
|
|
174
157
|
All major mail functions should be able to happen from the Mail module.
|
|
175
158
|
So, you should be able to just <code>require 'mail'</code> to get started.
|
|
@@ -237,7 +220,7 @@ what you are doing.
|
|
|
237
220
|
### Sending an email:
|
|
238
221
|
|
|
239
222
|
Mail defaults to sending via SMTP to local host port 25. If you have a
|
|
240
|
-
sendmail or postfix daemon running on
|
|
223
|
+
sendmail or postfix daemon running on this port, sending email is as
|
|
241
224
|
easy as:
|
|
242
225
|
|
|
243
226
|
```ruby
|
|
@@ -297,7 +280,17 @@ mail.delivery_method :exim, :location => "/usr/bin/exim"
|
|
|
297
280
|
mail.deliver
|
|
298
281
|
```
|
|
299
282
|
|
|
300
|
-
|
|
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:
|
|
301
294
|
|
|
302
295
|
You can configure Mail to receive email using <code>retriever_method</code>
|
|
303
296
|
within <code>Mail.defaults</code>:
|
|
@@ -350,7 +343,7 @@ mail.cc #=> 'sam@test.lindsaar.net'
|
|
|
350
343
|
mail.subject #=> "This is the subject"
|
|
351
344
|
mail.date.to_s #=> '21 Nov 1997 09:55:06 -0600'
|
|
352
345
|
mail.message_id #=> '<4D6AA7EB.6490534@xxx.xxx>'
|
|
353
|
-
mail.
|
|
346
|
+
mail.decoded #=> 'This is the body of the email...
|
|
354
347
|
```
|
|
355
348
|
|
|
356
349
|
Many more methods available.
|
|
@@ -376,7 +369,7 @@ is another message which can have many or no parts.
|
|
|
376
369
|
A message will only have parts if it is a multipart/mixed or multipart/related
|
|
377
370
|
content type and has a boundary defined.
|
|
378
371
|
|
|
379
|
-
### Testing and
|
|
372
|
+
### Testing and Extracting Attachments
|
|
380
373
|
```ruby
|
|
381
374
|
mail.attachments.each do | attachment |
|
|
382
375
|
# Attachments is an AttachmentsList object containing a
|
|
@@ -385,14 +378,14 @@ mail.attachments.each do | attachment |
|
|
|
385
378
|
# extracting images for example...
|
|
386
379
|
filename = attachment.filename
|
|
387
380
|
begin
|
|
388
|
-
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}
|
|
389
382
|
rescue => e
|
|
390
383
|
puts "Unable to save data for #{filename} because #{e.message}"
|
|
391
384
|
end
|
|
392
385
|
end
|
|
393
386
|
end
|
|
394
387
|
```
|
|
395
|
-
### Writing and
|
|
388
|
+
### Writing and Sending a Multipart/Alternative (HTML and Text) Email
|
|
396
389
|
|
|
397
390
|
Mail makes some basic assumptions and makes doing the common thing as
|
|
398
391
|
simple as possible.... (asking a lot from a mail library)
|
|
@@ -458,7 +451,7 @@ Mail assumes that if your text in the body is only us-ascii, that your
|
|
|
458
451
|
transfer encoding is 7bit and it is text/plain. You can override this
|
|
459
452
|
by explicitly declaring it.
|
|
460
453
|
|
|
461
|
-
### Making Multipart/Alternate,
|
|
454
|
+
### Making Multipart/Alternate, Without a Block
|
|
462
455
|
|
|
463
456
|
You don't have to use a block with the text and html part included, you
|
|
464
457
|
can just do it declaratively. However, you need to add Mail::Parts to
|
|
@@ -486,7 +479,7 @@ mail.html_part = html_part
|
|
|
486
479
|
|
|
487
480
|
Results in the same email as done using the block form
|
|
488
481
|
|
|
489
|
-
### Getting
|
|
482
|
+
### Getting Error Reports from an Email:
|
|
490
483
|
|
|
491
484
|
```ruby
|
|
492
485
|
@mail = Mail.read('/path/to/bounce_message.eml')
|
|
@@ -530,7 +523,6 @@ than mail (this should be rarely needed)
|
|
|
530
523
|
|
|
531
524
|
```ruby
|
|
532
525
|
@mail = Mail.new
|
|
533
|
-
file_data = File.read('path/to/myfile.pdf')
|
|
534
526
|
@mail.attachments['myfile.pdf'] = { :mime_type => 'application/x-pdf',
|
|
535
527
|
:content => File.read('path/to/myfile.pdf') }
|
|
536
528
|
@mail.parts.first.mime_type #=> 'application/x-pdf'
|
|
@@ -563,8 +555,7 @@ end
|
|
|
563
555
|
```
|
|
564
556
|
See "Testing and extracting attachments" above for more details.
|
|
565
557
|
|
|
566
|
-
Using Mail with Testing or Spec'ing Libraries
|
|
567
|
-
---------------------------------------------
|
|
558
|
+
## Using Mail with Testing or Spec'ing Libraries
|
|
568
559
|
|
|
569
560
|
If mail is part of your system, you'll need a way to test it without actually
|
|
570
561
|
sending emails, the TestMailer can do this for you.
|
|
@@ -614,70 +605,53 @@ describe "sending an email" do
|
|
|
614
605
|
end
|
|
615
606
|
end
|
|
616
607
|
|
|
617
|
-
it {
|
|
608
|
+
it { is_expected.to have_sent_email } # passes if any email at all was sent
|
|
618
609
|
|
|
619
|
-
it {
|
|
620
|
-
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') }
|
|
621
612
|
|
|
622
613
|
# can specify a list of recipients...
|
|
623
|
-
it {
|
|
614
|
+
it { is_expected.to have_sent_email.to(['mike1@me.com', 'mike2@me.com']) }
|
|
624
615
|
|
|
625
616
|
# ...or chain recipients together
|
|
626
|
-
it {
|
|
617
|
+
it { is_expected.to have_sent_email.to('mike1@me.com').to('mike2@me.com') }
|
|
627
618
|
|
|
628
|
-
it {
|
|
619
|
+
it { is_expected.to have_sent_email.with_subject('testing') }
|
|
629
620
|
|
|
630
|
-
it {
|
|
621
|
+
it { is_expected.to have_sent_email.with_body('hello') }
|
|
631
622
|
|
|
632
623
|
# Can match subject or body with a regex
|
|
633
624
|
# (or anything that responds_to? :match)
|
|
634
625
|
|
|
635
|
-
it {
|
|
636
|
-
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/) }
|
|
637
628
|
|
|
638
629
|
# Can chain together modifiers
|
|
639
630
|
# Note that apart from recipients, repeating a modifier overwrites old value.
|
|
640
631
|
|
|
641
|
-
it {
|
|
632
|
+
it { is_expected.to have_sent_email.from('you@you.com').to('mike1@me.com').matching_body(/hell/)
|
|
642
633
|
|
|
643
634
|
# test for attachments
|
|
644
635
|
|
|
645
636
|
# ... by specific attachment
|
|
646
|
-
it {
|
|
637
|
+
it { is_expected.to have_sent_email.with_attachments(my_attachment) }
|
|
647
638
|
|
|
648
639
|
# ... or any attachment
|
|
649
|
-
it {
|
|
640
|
+
it { is_expected.to have_sent_email.with_attachments(any_attachment) }
|
|
650
641
|
|
|
651
642
|
# ... by array of attachments
|
|
652
|
-
it {
|
|
643
|
+
it { is_expected.to have_sent_email.with_attachments([my_attachment1, my_attachment2]) } #note that order is important
|
|
653
644
|
|
|
654
645
|
#... by presence
|
|
655
|
-
it {
|
|
646
|
+
it { is_expected.to have_sent_email.with_any_attachments }
|
|
656
647
|
|
|
657
648
|
#... or by absence
|
|
658
|
-
it {
|
|
649
|
+
it { is_expected.to have_sent_email.with_no_attachments }
|
|
659
650
|
|
|
660
651
|
end
|
|
661
652
|
```
|
|
662
653
|
|
|
663
|
-
|
|
664
|
-
---------------
|
|
665
|
-
|
|
666
|
-
The mail gem adds several constants and methods to Ruby's core objects (similar to the activesupport gem from the Rails project). For example:
|
|
667
|
-
|
|
668
|
-
NilClass::blank?
|
|
669
|
-
NilClass::to_crlf
|
|
670
|
-
NilClass::to_lf
|
|
671
|
-
Object::blank?
|
|
672
|
-
String::to_crlf
|
|
673
|
-
String::to_lf
|
|
674
|
-
String::blank?
|
|
675
|
-
...etc...
|
|
676
|
-
|
|
677
|
-
For all the details, check out lib/mail/core_extensions/.
|
|
678
|
-
|
|
679
|
-
Excerpts from TREC Spam Corpus 2005
|
|
680
|
-
-----------------------------------
|
|
654
|
+
## Excerpts from TREC Spam Corpus 2005
|
|
681
655
|
|
|
682
656
|
The spec fixture files in spec/fixtures/emails/from_trec_2005 are from the
|
|
683
657
|
2005 TREC Public Spam Corpus. They remain copyrighted under the terms of
|
|
@@ -695,12 +669,11 @@ They are used as allowed by 'Permitted Uses, Clause 3':
|
|
|
695
669
|
|
|
696
670
|
-- http://plg.uwaterloo.ca/~gvcormac/treccorpus/
|
|
697
671
|
|
|
698
|
-
License
|
|
699
|
-
-------
|
|
672
|
+
## License
|
|
700
673
|
|
|
701
674
|
(The MIT License)
|
|
702
675
|
|
|
703
|
-
Copyright (c) 2009-
|
|
676
|
+
Copyright (c) 2009-2016 Mikel Lindsaar
|
|
704
677
|
|
|
705
678
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
706
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
|
|
@@ -1,21 +1,60 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module Mail
|
|
3
|
-
module CheckDeliveryParams
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
module CheckDeliveryParams #:nodoc:
|
|
4
|
+
class << self
|
|
5
|
+
def check(mail)
|
|
6
|
+
[ check_from(mail.smtp_envelope_from),
|
|
7
|
+
check_to(mail.smtp_envelope_to),
|
|
8
|
+
check_message(mail) ]
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
def check_from(addr)
|
|
12
|
+
if Utilities.blank?(addr)
|
|
13
|
+
raise ArgumentError, "SMTP From address may not be blank: #{addr.inspect}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
check_addr 'From', addr
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def check_to(addrs)
|
|
20
|
+
if Utilities.blank?(addrs)
|
|
21
|
+
raise ArgumentError, "SMTP To address may not be blank: #{addrs.inspect}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
Array(addrs).map do |addr|
|
|
25
|
+
check_addr 'To', addr
|
|
26
|
+
end
|
|
11
27
|
end
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
def check_addr(addr_name, addr)
|
|
30
|
+
validate_smtp_addr addr do |error_message|
|
|
31
|
+
raise ArgumentError, "SMTP #{addr_name} address #{error_message}: #{addr.inspect}"
|
|
32
|
+
end
|
|
16
33
|
end
|
|
17
34
|
|
|
18
|
-
|
|
35
|
+
def validate_smtp_addr(addr)
|
|
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
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
addr
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def check_message(message)
|
|
50
|
+
message = message.encoded if message.respond_to?(:encoded)
|
|
51
|
+
|
|
52
|
+
if Utilities.blank?(message)
|
|
53
|
+
raise ArgumentError, 'An encoded message is required to send an email'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
message
|
|
57
|
+
end
|
|
19
58
|
end
|
|
20
59
|
end
|
|
21
60
|
end
|
data/lib/mail/configuration.rb
CHANGED