mailcatcher 0.5.12 → 0.6.0pre1
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +24 -11
- data/bin/catchmail +23 -2
- data/bin/mailcatcher +1 -0
- data/lib/mail_catcher.rb +49 -43
- data/lib/mail_catcher/events.rb +5 -3
- data/lib/mail_catcher/mail.rb +15 -15
- data/lib/mail_catcher/smtp.rb +6 -2
- data/lib/mail_catcher/version.rb +1 -1
- data/lib/mail_catcher/web.rb +14 -141
- data/lib/mail_catcher/web/application.rb +188 -0
- data/lib/mailcatcher.rb +3 -0
- data/public/{images → assets}/logo.png +0 -0
- data/public/{images → assets}/logo_large.png +0 -0
- data/public/assets/mailcatcher.css +1 -0
- data/public/assets/mailcatcher.js +5 -0
- data/views/404.erb +6 -0
- data/views/index.erb +62 -0
- metadata +148 -77
- metadata.gz.sig +0 -0
- data/lib/mail_catcher/growl.rb +0 -16
- data/public/javascripts/application.js +0 -408
- data/public/javascripts/date.js +0 -104
- data/public/javascripts/flexie.min.js +0 -36
- data/public/javascripts/jquery.js +0 -6883
- data/public/javascripts/keymaster.min.js +0 -4
- data/public/javascripts/modernizr.js +0 -3
- data/public/javascripts/xslt-3.2.js +0 -1
- data/public/stylesheets/analysis.xsl +0 -33
- data/public/stylesheets/application.css +0 -375
- data/views/index.haml +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20a21ec3f69fd47bbc8c269689998ace77da0c1b
|
4
|
+
data.tar.gz: f55e1936c3fb237909fb0bf1bc1282af1c709175
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 693e35eb5cec71175f37e7c7c57a08a591985a65284c71c4a8684e7c020114f9f7733b522f6df404fca1ba5a922b098836fb7b02497ed25e93ca834b06f3d216
|
7
|
+
data.tar.gz: 8e474863a1a3bd887322bb4b9007aba2c14a44d5a3b783cc3384adc5df7ca1f89d07df069e0ed040a8315d47791568b22fc05fff54dbdcf15633308ea4fed0ba
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -10,13 +10,11 @@ MailCatcher runs a super simple SMTP server which catches any message sent to it
|
|
10
10
|
|
11
11
|
* Catches all mail and stores it for display.
|
12
12
|
* Shows HTML, Plain Text and Source version of messages, as applicable.
|
13
|
-
* Rewrites HTML enabling display of embedded, inline images/etc and open links in a new window.
|
14
|
-
* Can send HTML for analysis by [Fractal][fractal].
|
13
|
+
* Rewrites HTML enabling display of embedded, inline images/etc and open links in a new window.
|
15
14
|
* Lists attachments and allows separate downloading of parts.
|
16
15
|
* Download original email to view in your native mail client(s).
|
17
16
|
* Command line options to override the default SMTP/HTTP IP and port settings.
|
18
17
|
* Mail appears instantly if your browser supports [WebSockets][websockets], otherwise updates every thirty seconds.
|
19
|
-
* Growl notifications when you receive a new message.
|
20
18
|
* Runs as a daemon run in the background.
|
21
19
|
* Sendmail-analogue command, `catchmail`, makes [using mailcatcher from PHP][withphp] a lot easier.
|
22
20
|
* Written super-simply in EventMachine, easy to dig in and change.
|
@@ -29,7 +27,7 @@ MailCatcher runs a super simple SMTP server which catches any message sent to it
|
|
29
27
|
3. Go to http://localhost:1080/
|
30
28
|
4. Send mail through smtp://localhost:1025
|
31
29
|
|
32
|
-
The brave can get the source from [the GitHub repository][mailcatcher-github].
|
30
|
+
Use `mailcatcher --help` to see the command line options. The brave can get the source from [the GitHub repository][mailcatcher-github].
|
33
31
|
|
34
32
|
### Bundler
|
35
33
|
|
@@ -46,7 +44,7 @@ Under RVM your mailcatcher command may only be available under the ruby you inst
|
|
46
44
|
|
47
45
|
### Rails
|
48
46
|
|
49
|
-
To set up your rails app, I recommend adding this to your `
|
47
|
+
To set up your rails app, I recommend adding this to your `environments/development.rb`:
|
50
48
|
|
51
49
|
config.action_mailer.delivery_method = :smtp
|
52
50
|
config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
|
@@ -55,14 +53,31 @@ To set up your rails app, I recommend adding this to your `environment/developme
|
|
55
53
|
|
56
54
|
For projects using PHP, or PHP frameworks and application platforms like Drupal, you can set [PHP's mail configuration](http://www.php.net/manual/en/mail.configuration.php) in your [php.ini](http://www.php.net/manual/en/configuration.file.php) to send via MailCatcher with:
|
57
55
|
|
58
|
-
sendmail_path = /usr/bin/env catchmail
|
56
|
+
sendmail_path = /usr/bin/env catchmail -f some@from.address
|
59
57
|
|
60
|
-
You can do this in
|
58
|
+
You can do this in your [Apache configuration](http://php.net/manual/en/configuration.changes.php) like so:
|
61
59
|
|
62
|
-
|
60
|
+
php_admin_value sendmail_path "/usr/bin/env catchmail -f some@from.address"
|
63
61
|
|
64
62
|
If you've installed via RVM this probably won't work unless you've manually added your RVM bin paths to your system environment's PATH. In that case, run `which catchmail` and put that path into the `sendmail_path` directive above instead of `/usr/bin/env catchmail`.
|
65
63
|
|
64
|
+
If starting `mailcatcher` on alternative SMTP IP and/or port with parameters like `--smtp-ip 192.168.0.1 --smtp-port 10025`, add the same parameters to your `catchmail` command:
|
65
|
+
|
66
|
+
sendmail_path = /usr/bin/env catchmail --smtp-ip 192.160.0.1 --smtp-port 10025 -f some@from.address
|
67
|
+
|
68
|
+
### Django
|
69
|
+
|
70
|
+
For use in Django, simply add the following configuration to your projects' settings.py
|
71
|
+
|
72
|
+
```python
|
73
|
+
if DEBUG:
|
74
|
+
EMAIL_HOST = '127.0.0.1'
|
75
|
+
EMAIL_HOST_USER = ''
|
76
|
+
EMAIL_HOST_PASSWORD = ''
|
77
|
+
EMAIL_PORT = 1025
|
78
|
+
EMAIL_USE_TLS = False
|
79
|
+
```
|
80
|
+
|
66
81
|
### API
|
67
82
|
|
68
83
|
A fairly RESTful URL schema means you can download a list of messages in JSON from `/messages`, each message's metadata with `/messages/:id.json`, and then the pertinent parts with `/messages/:id.html` and `/messages/:id.plain` for the default HTML and plain text version, `/messages/:id/:cid` for individual attachments by CID, or the whole message with `/messages/:id.source`.
|
@@ -75,10 +90,9 @@ A fairly RESTful URL schema means you can download a list of messages in JSON fr
|
|
75
90
|
## TODO
|
76
91
|
|
77
92
|
* Add mail delivery on request, optionally multiple times.
|
78
|
-
* Better Growl support in MacRuby and RubyCocoa with click notifications which takes you to the received message.
|
79
93
|
* An API-compatible nodejs version, for fun and profit (and non-ruby npm users).
|
80
94
|
* Test suite.
|
81
|
-
* Compatibility testing against CampaignMonitor's [design guidelines](http://www.campaignmonitor.com/design-guidelines/) and [CSS support matrix](http://www.campaignmonitor.com/
|
95
|
+
* Compatibility testing against CampaignMonitor's [design guidelines](http://www.campaignmonitor.com/design-guidelines/) and [CSS support matrix](http://www.campaignmonitor.com/css/).
|
82
96
|
* Forward mail to rendering service, maybe CampaignMonitor?
|
83
97
|
* Package as an app? Native interfaces? HotCocoa?
|
84
98
|
|
@@ -101,7 +115,6 @@ Copyright © 2010-2011 Samuel Cochran (sj26@sj26.com). Released under the MIT Li
|
|
101
115
|
For dream catching, try [this](http://goo.gl/kgbh). OR [THIS](http://www.nyanicorn.com), OMG.
|
102
116
|
|
103
117
|
[donate]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=522WUPLRWUSKE
|
104
|
-
[fractal]: http://getfractal.com
|
105
118
|
[license]: https://github.com/sj26/mailcatcher/blob/master/LICENSE
|
106
119
|
[mailcatcher-github]: https://github.com/sj26/mailcatcher
|
107
120
|
[mailcatcher-issues]: https://github.com/sj26/mailcatcher/issues
|
data/bin/catchmail
CHANGED
@@ -13,7 +13,7 @@ options = {:smtp_ip => '127.0.0.1', :smtp_port => 1025}
|
|
13
13
|
|
14
14
|
OptionParser.new do |parser|
|
15
15
|
parser.banner = <<-BANNER.gsub /^ +/, ""
|
16
|
-
Usage: catchmail [options]
|
16
|
+
Usage: catchmail [options] [recipient ...]
|
17
17
|
sendmail-like interface to forward mail to MailCatcher.
|
18
18
|
BANNER
|
19
19
|
|
@@ -33,6 +33,17 @@ OptionParser.new do |parser|
|
|
33
33
|
options[:from] = from
|
34
34
|
end
|
35
35
|
|
36
|
+
parser.on('-oi', 'Ignored option -oi') do |ignored|
|
37
|
+
end
|
38
|
+
parser.on('-t', 'Ignored option -t') do |ignored|
|
39
|
+
end
|
40
|
+
parser.on('-q', 'Ignored option -q') do |ignored|
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on('-x', '--no-exit', 'Can\'t exit from the application') do
|
44
|
+
options[:no_exit] = true
|
45
|
+
end
|
46
|
+
|
36
47
|
parser.on('-h', '--help', 'Display this help information') do
|
37
48
|
puts parser
|
38
49
|
exit!
|
@@ -45,6 +56,16 @@ Mail.defaults do
|
|
45
56
|
:port => options[:smtp_port]
|
46
57
|
end
|
47
58
|
|
48
|
-
message = Mail.new
|
59
|
+
message = Mail.new($stdin.read)
|
60
|
+
|
49
61
|
message.return_path = options[:from] if options[:from]
|
62
|
+
|
63
|
+
ARGV.each do |recipient|
|
64
|
+
if message.to.nil?
|
65
|
+
message.to = recipient
|
66
|
+
else
|
67
|
+
message.to << recipient
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
50
71
|
message.deliver
|
data/bin/mailcatcher
CHANGED
data/lib/mail_catcher.rb
CHANGED
@@ -1,14 +1,19 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require 'optparse'
|
5
|
-
require 'rbconfig'
|
6
|
-
require 'thin'
|
1
|
+
require "open3"
|
2
|
+
require "optparse"
|
3
|
+
require "rbconfig"
|
7
4
|
|
8
|
-
require
|
5
|
+
require "active_support/all"
|
6
|
+
require "eventmachine"
|
7
|
+
require "thin"
|
8
|
+
|
9
|
+
require "mail_catcher/events"
|
10
|
+
require "mail_catcher/mail"
|
11
|
+
require "mail_catcher/smtp"
|
12
|
+
require "mail_catcher/web"
|
13
|
+
require "mail_catcher/version"
|
9
14
|
|
10
15
|
module MailCatcher extend self
|
11
|
-
def which
|
16
|
+
def which(command)
|
12
17
|
not windows? and Open3.popen3 'which', 'command' do |stdin, stdout, stderr|
|
13
18
|
return stdout.read.chomp.presence
|
14
19
|
end
|
@@ -26,14 +31,6 @@ module MailCatcher extend self
|
|
26
31
|
mac? and const_defined? :MACRUBY_VERSION
|
27
32
|
end
|
28
33
|
|
29
|
-
def growlnotify?
|
30
|
-
which "growlnotify"
|
31
|
-
end
|
32
|
-
|
33
|
-
def growl?
|
34
|
-
growlnotify?
|
35
|
-
end
|
36
|
-
|
37
34
|
def browse?
|
38
35
|
windows? or which "open"
|
39
36
|
end
|
@@ -46,19 +43,27 @@ module MailCatcher extend self
|
|
46
43
|
end
|
47
44
|
end
|
48
45
|
|
49
|
-
|
46
|
+
@@defaults = {
|
50
47
|
:smtp_ip => '127.0.0.1',
|
51
48
|
:smtp_port => '1025',
|
52
49
|
:http_ip => '127.0.0.1',
|
53
50
|
:http_port => '1080',
|
54
51
|
:verbose => false,
|
55
52
|
:daemon => !windows?,
|
56
|
-
:growl => growlnotify?,
|
57
53
|
:browse => false,
|
54
|
+
:quit => true,
|
58
55
|
}
|
59
56
|
|
57
|
+
def options
|
58
|
+
@@options
|
59
|
+
end
|
60
|
+
|
61
|
+
def quittable?
|
62
|
+
options[:quit]
|
63
|
+
end
|
64
|
+
|
60
65
|
def parse! arguments=ARGV, defaults=@defaults
|
61
|
-
|
66
|
+
@@defaults.dup.tap do |options|
|
62
67
|
OptionParser.new do |parser|
|
63
68
|
parser.banner = "Usage: mailcatcher [options]"
|
64
69
|
parser.version = VERSION
|
@@ -83,16 +88,14 @@ module MailCatcher extend self
|
|
83
88
|
options[:http_port] = port
|
84
89
|
end
|
85
90
|
|
91
|
+
parser.on("--no-quit", "Don't allow quitting the process") do
|
92
|
+
options[:quit] = false
|
93
|
+
end
|
94
|
+
|
86
95
|
if mac?
|
87
|
-
parser.on("--[no-]growl"
|
88
|
-
|
89
|
-
|
90
|
-
puts
|
91
|
-
puts "See: http://growl.info/extras.php#growlnotify"
|
92
|
-
exit!
|
93
|
-
end
|
94
|
-
|
95
|
-
options[:growl] = growl
|
96
|
+
parser.on("--[no-]growl") do |growl|
|
97
|
+
puts "Growl is no longer supported"
|
98
|
+
exit -2
|
96
99
|
end
|
97
100
|
end
|
98
101
|
|
@@ -114,7 +117,7 @@ module MailCatcher extend self
|
|
114
117
|
|
115
118
|
parser.on('-h', '--help', 'Display this help information') do
|
116
119
|
puts parser
|
117
|
-
exit
|
120
|
+
exit
|
118
121
|
end
|
119
122
|
end.parse!
|
120
123
|
end
|
@@ -122,19 +125,24 @@ module MailCatcher extend self
|
|
122
125
|
|
123
126
|
def run! options=nil
|
124
127
|
# If we are passed options, fill in the blanks
|
125
|
-
options &&=
|
128
|
+
options &&= options.reverse_merge @@defaults
|
126
129
|
# Otherwise, parse them from ARGV
|
127
130
|
options ||= parse!
|
128
131
|
|
132
|
+
# Stash them away for later
|
133
|
+
@@options = options
|
134
|
+
|
135
|
+
# If we're running in the foreground sync the output.
|
136
|
+
unless options[:daemon]
|
137
|
+
$stdout.sync = $stderr.sync = true
|
138
|
+
end
|
139
|
+
|
129
140
|
puts "Starting MailCatcher"
|
130
141
|
|
131
|
-
Thin::Logging.silent =
|
142
|
+
Thin::Logging.silent = (ENV["MAILCATCHER_ENV"] != "development")
|
132
143
|
|
133
144
|
# One EventMachine loop...
|
134
145
|
EventMachine.run do
|
135
|
-
# Get our lion on if asked
|
136
|
-
MailCatcher::Growl.start if options[:growl]
|
137
|
-
|
138
146
|
smtp_url = "smtp://#{options[:smtp_ip]}:#{options[:smtp_port]}"
|
139
147
|
http_url = "http://#{options[:http_ip]}:#{options[:http_port]}"
|
140
148
|
|
@@ -147,7 +155,7 @@ module MailCatcher extend self
|
|
147
155
|
# Let Thin set itself up inside our EventMachine loop
|
148
156
|
# (Skinny/WebSockets just works on the inside)
|
149
157
|
rescue_port options[:http_port] do
|
150
|
-
Thin::Server.start
|
158
|
+
Thin::Server.start(options[:http_ip], options[:http_port], Web)
|
151
159
|
puts "==> #{http_url}"
|
152
160
|
end
|
153
161
|
|
@@ -161,7 +169,11 @@ module MailCatcher extend self
|
|
161
169
|
# Daemonize, if we should, but only after the servers have started.
|
162
170
|
if options[:daemon]
|
163
171
|
EventMachine.next_tick do
|
164
|
-
|
172
|
+
if quittable?
|
173
|
+
puts "*** MailCatcher runs as a daemon by default. Go to the web interface to quit."
|
174
|
+
else
|
175
|
+
puts "*** MailCatcher is now running as a daemon that cannot be quit."
|
176
|
+
end
|
165
177
|
Process.daemon
|
166
178
|
end
|
167
179
|
end
|
@@ -182,16 +194,10 @@ protected
|
|
182
194
|
rescue RuntimeError
|
183
195
|
if $!.to_s =~ /\bno acceptor\b/
|
184
196
|
puts "~~> ERROR: Something's using port #{port}. Are you already running MailCatcher?"
|
185
|
-
exit
|
197
|
+
exit -1
|
186
198
|
else
|
187
199
|
raise
|
188
200
|
end
|
189
201
|
end
|
190
202
|
end
|
191
203
|
end
|
192
|
-
|
193
|
-
require 'mail_catcher/events'
|
194
|
-
require 'mail_catcher/growl'
|
195
|
-
require 'mail_catcher/mail'
|
196
|
-
require 'mail_catcher/smtp'
|
197
|
-
require 'mail_catcher/web'
|
data/lib/mail_catcher/events.rb
CHANGED
data/lib/mail_catcher/mail.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "active_support/json"
|
2
|
+
require "eventmachine"
|
3
|
+
require "mail"
|
4
|
+
require "sqlite3"
|
5
5
|
|
6
6
|
module MailCatcher::Mail extend self
|
7
7
|
def db
|
8
8
|
@__db ||= begin
|
9
|
-
SQLite3::Database.new(
|
9
|
+
SQLite3::Database.new(":memory:", :type_translation => true).tap do |db|
|
10
10
|
db.execute(<<-SQL)
|
11
11
|
CREATE TABLE message (
|
12
12
|
id INTEGER PRIMARY KEY ASC,
|
@@ -41,7 +41,7 @@ module MailCatcher::Mail extend self
|
|
41
41
|
@add_message_query ||= db.prepare("INSERT INTO message (sender, recipients, subject, source, type, size, created_at) VALUES (?, ?, ?, ?, ?, ?, datetime('now'))")
|
42
42
|
|
43
43
|
mail = Mail.new(message[:source])
|
44
|
-
@add_message_query.execute(message[:sender], message[:recipients].to_json, mail.subject, message[:source], mail.mime_type ||
|
44
|
+
@add_message_query.execute(message[:sender], message[:recipients].to_json, mail.subject, message[:source], mail.mime_type || "text/plain", message[:source].length)
|
45
45
|
message_id = db.last_insert_row_id
|
46
46
|
parts = mail.all_parts
|
47
47
|
parts = [mail] if parts.empty?
|
@@ -49,7 +49,7 @@ module MailCatcher::Mail extend self
|
|
49
49
|
body = part.body.to_s
|
50
50
|
# Only parts have CIDs, not mail
|
51
51
|
cid = part.cid if part.respond_to? :cid
|
52
|
-
add_message_part(message_id, cid, part.mime_type ||
|
52
|
+
add_message_part(message_id, cid, part.mime_type || "text/plain", part.attachment? ? 1 : 0, part.filename, part.charset, body, body.length)
|
53
53
|
end
|
54
54
|
|
55
55
|
EventMachine.next_tick do
|
@@ -69,7 +69,7 @@ module MailCatcher::Mail extend self
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def messages
|
72
|
-
@messages_query ||= db.prepare "SELECT id, sender, recipients, subject, size, created_at FROM message ORDER BY created_at
|
72
|
+
@messages_query ||= db.prepare "SELECT id, sender, recipients, subject, size, created_at FROM message ORDER BY created_at, id ASC"
|
73
73
|
@messages_query.execute.map do |row|
|
74
74
|
Hash[row.fields.zip(row)].tap do |message|
|
75
75
|
message["recipients"] &&= ActiveSupport::JSON.decode message["recipients"]
|
@@ -87,7 +87,7 @@ module MailCatcher::Mail extend self
|
|
87
87
|
|
88
88
|
def message_has_html?(id)
|
89
89
|
@message_has_html_query ||= db.prepare "SELECT 1 FROM message_part WHERE message_id = ? AND is_attachment = 0 AND type IN ('application/xhtml+xml', 'text/html') LIMIT 1"
|
90
|
-
(!!@message_has_html_query.execute(id).next) || [
|
90
|
+
(!!@message_has_html_query.execute(id).next) || ["text/html", "application/xhtml+xml"].include?(message(id)["type"])
|
91
91
|
end
|
92
92
|
|
93
93
|
def message_has_plain?(id)
|
@@ -126,7 +126,7 @@ module MailCatcher::Mail extend self
|
|
126
126
|
part ||= message_part_type(message_id, "application/xhtml+xml")
|
127
127
|
part ||= begin
|
128
128
|
message = message(message_id)
|
129
|
-
message if message.present? and [
|
129
|
+
message if message.present? and ["text/html", "application/xhtml+xml"].include? message["type"]
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -135,7 +135,7 @@ module MailCatcher::Mail extend self
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def message_part_cid(message_id, cid)
|
138
|
-
@message_part_cid_query ||= db.prepare
|
138
|
+
@message_part_cid_query ||= db.prepare "SELECT * FROM message_part WHERE message_id = ?"
|
139
139
|
@message_part_cid_query.execute(message_id).map do |row|
|
140
140
|
Hash[row.fields.zip(row)]
|
141
141
|
end.find do |part|
|
@@ -144,16 +144,16 @@ module MailCatcher::Mail extend self
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def delete!
|
147
|
-
@delete_messages_query ||= db.prepare
|
148
|
-
@delete_message_parts_query ||= db.prepare
|
147
|
+
@delete_messages_query ||= db.prepare "DELETE FROM message"
|
148
|
+
@delete_message_parts_query ||= db.prepare "DELETE FROM message_part"
|
149
149
|
|
150
150
|
@delete_messages_query.execute and
|
151
151
|
@delete_message_parts_query.execute
|
152
152
|
end
|
153
153
|
|
154
154
|
def delete_message!(message_id)
|
155
|
-
@delete_messages_query ||= db.prepare
|
156
|
-
@delete_message_parts_query ||= db.prepare
|
155
|
+
@delete_messages_query ||= db.prepare "DELETE FROM message WHERE id = ?"
|
156
|
+
@delete_message_parts_query ||= db.prepare "DELETE FROM message_part WHERE message_id = ?"
|
157
157
|
@delete_messages_query.execute(message_id) and
|
158
158
|
@delete_message_parts_query.execute(message_id)
|
159
159
|
end
|
data/lib/mail_catcher/smtp.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "eventmachine"
|
2
|
+
|
3
|
+
require "mail_catcher/mail"
|
2
4
|
|
3
5
|
class MailCatcher::Smtp < EventMachine::Protocols::SmtpServer
|
4
6
|
# We override EM's mail from processing to allow multiple mail-from commands
|
@@ -34,7 +36,9 @@ class MailCatcher::Smtp < EventMachine::Protocols::SmtpServer
|
|
34
36
|
|
35
37
|
def receive_data_chunk(lines)
|
36
38
|
current_message[:source] ||= ""
|
37
|
-
|
39
|
+
lines.each do |line|
|
40
|
+
current_message[:source] << line << "\r\n"
|
41
|
+
end
|
38
42
|
true
|
39
43
|
end
|
40
44
|
|
data/lib/mail_catcher/version.rb
CHANGED