multi_mail 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -0
- data/.yardopts +4 -0
- data/Gemfile +1 -1
- data/README.md +107 -12
- data/Rakefile +75 -52
- data/lib/multi_mail/cloudmailin/receiver.rb +100 -0
- data/lib/multi_mail/mailgun/receiver.rb +74 -36
- data/lib/multi_mail/mailgun/sender.rb +14 -0
- data/lib/multi_mail/mandrill/receiver.rb +77 -35
- data/lib/multi_mail/mandrill/sender.rb +14 -0
- data/lib/multi_mail/postmark/receiver.rb +68 -0
- data/lib/multi_mail/postmark/sender.rb +14 -0
- data/lib/multi_mail/receiver/base.rb +125 -8
- data/lib/multi_mail/receiver.rb +10 -4
- data/lib/multi_mail/sender/base.rb +7 -0
- data/lib/multi_mail/sender.rb +10 -4
- data/lib/multi_mail/sendgrid/receiver.rb +42 -0
- data/lib/multi_mail/sendgrid/sender.rb +11 -0
- data/lib/multi_mail/service.rb +15 -4
- data/lib/multi_mail/simple/receiver.rb +15 -0
- data/lib/multi_mail/simple/sender.rb +14 -0
- data/lib/multi_mail/version.rb +1 -1
- data/lib/multi_mail.rb +71 -3
- data/multi_mail.gemspec +12 -5
- data/spec/cloudmailin/receiver_spec.rb +112 -0
- data/spec/fixtures/cloudmailin/json/spam.txt +59 -0
- data/spec/fixtures/cloudmailin/json/valid.txt +59 -0
- data/spec/fixtures/cloudmailin/multipart/spam.txt +135 -0
- data/spec/fixtures/cloudmailin/multipart/valid.txt +135 -0
- data/spec/fixtures/cloudmailin/raw/spam.txt +137 -0
- data/spec/fixtures/cloudmailin/raw/valid.txt +137 -0
- data/spec/fixtures/mailgun/parsed/invalid.txt +8 -0
- data/spec/fixtures/mailgun/parsed/missing.txt +8 -0
- data/spec/fixtures/mailgun/parsed/spam.txt +8 -0
- data/spec/fixtures/mailgun/parsed/valid.txt +187 -0
- data/spec/fixtures/mandrill/spam.txt +9 -0
- data/spec/fixtures/mandrill/valid.txt +10 -0
- data/spec/fixtures/multipart.txt +99 -0
- data/spec/fixtures/postmark/spam.txt +83 -0
- data/spec/fixtures/postmark/valid.txt +92 -0
- data/spec/fixtures/simple/valid.txt +4 -0
- data/spec/mailgun/receiver_spec.rb +105 -50
- data/spec/mailgun/sender_spec.rb +0 -0
- data/spec/mandrill/receiver_spec.rb +35 -35
- data/spec/mandrill/sender_spec.rb +0 -0
- data/spec/multi_mail_spec.rb +63 -0
- data/spec/postmark/receiver_spec.rb +60 -0
- data/spec/postmark/sender_spec.rb +0 -0
- data/spec/receiver/base_spec.rb +73 -8
- data/spec/sender/base_spec.rb +21 -0
- data/spec/service_spec.rb +2 -2
- data/spec/simple/receiver_spec.rb +36 -0
- data/spec/simple/sender_spec.rb +0 -0
- data/spec/spec_helper.rb +123 -10
- metadata +141 -21
- data/spec/fixtures/mailgun/invalid.txt +0 -8
- data/spec/fixtures/mailgun/missing.txt +0 -8
- data/spec/fixtures/mailgun/spam.txt +0 -8
- data/spec/fixtures/mailgun/valid.txt +0 -8
data/lib/multi_mail.rb
CHANGED
@@ -1,16 +1,84 @@
|
|
1
|
+
require 'base64'
|
1
2
|
require 'cgi'
|
2
3
|
require 'json'
|
3
4
|
require 'openssl'
|
4
5
|
|
5
6
|
require 'mail'
|
6
7
|
require 'multimap'
|
8
|
+
require 'rack'
|
7
9
|
|
8
10
|
module MultiMail
|
9
11
|
# @see http://rdoc.info/gems/fog/Fog/Errors
|
10
12
|
class Error < StandardError; end
|
13
|
+
# Raise if an incoming POST request is forged.
|
11
14
|
class ForgedRequest < MultiMail::Error; end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
class << self
|
17
|
+
# @return [RegExp] a message whose subject matches this pattern will be
|
18
|
+
# considered an autoresponse
|
19
|
+
attr_accessor :autoresponse_pattern
|
20
|
+
|
21
|
+
# Configures MultiMail.
|
22
|
+
#
|
23
|
+
# * `autoresponse_pattern`: a message whose subject matches this pattern will
|
24
|
+
# be considered an autoresponse
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# require 'multi_mail'
|
28
|
+
#
|
29
|
+
# MultiMail.setup do |config|
|
30
|
+
# config.autoresponse_pattern = /^Out of Office AutoReply:/i
|
31
|
+
# end
|
32
|
+
def setup
|
33
|
+
yield self
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns whether a message is an autoresponse.
|
37
|
+
#
|
38
|
+
# @param [Mail::Message] message a message
|
39
|
+
# @return [Boolean] whether a message is an autoresponse
|
40
|
+
# @see https://github.com/opennorth/multi_mail/wiki/Detecting-autoresponders
|
41
|
+
def autoresponse?(message)
|
42
|
+
!!(
|
43
|
+
# If any of the following headers are present and have the given value.
|
44
|
+
{
|
45
|
+
'Delivered-To' => 'Autoresponder',
|
46
|
+
'Precedence' => 'auto_reply',
|
47
|
+
'Return-Path' => nil, # in most cases, this would signify a bounce
|
48
|
+
'X-Autoreply' => 'yes',
|
49
|
+
'X-FC-MachineGenerated' => 'true',
|
50
|
+
'X-POST-MessageClass' => '9; Autoresponder',
|
51
|
+
'X-Precedence' => 'auto_reply',
|
52
|
+
}.find do |name,value|
|
53
|
+
message[name] && message[name].decoded == value
|
54
|
+
end ||
|
55
|
+
# If any of the following headers are present.
|
56
|
+
[
|
57
|
+
'X-Autogenerated', # value is one of Forward, Group, Letter, Mirror, Redirect or Reply
|
58
|
+
'X-AutoReply-From', # value is an email address
|
59
|
+
'X-Autorespond', # value is an email subject
|
60
|
+
'X-Mail-Autoreply', # value is often "dtc-autoreply" but can be another tag
|
61
|
+
].any? do |name|
|
62
|
+
message[name]
|
63
|
+
end ||
|
64
|
+
# If the Auto-Submitted header is present and is not equal to "no".
|
65
|
+
(
|
66
|
+
message['Auto-Submitted'] &&
|
67
|
+
message['Auto-Submitted'].decoded != 'no'
|
68
|
+
) ||
|
69
|
+
# If the message subject matches the autoresponse pattern.
|
70
|
+
(
|
71
|
+
MultiMail.autoresponse_pattern &&
|
72
|
+
message.subject &&
|
73
|
+
message.subject[MultiMail.autoresponse_pattern]
|
74
|
+
)
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
16
78
|
end
|
79
|
+
|
80
|
+
require 'multi_mail/service'
|
81
|
+
require 'multi_mail/receiver'
|
82
|
+
require 'multi_mail/receiver/base'
|
83
|
+
require 'multi_mail/sender'
|
84
|
+
require 'multi_mail/sender/base'
|
data/multi_mail.gemspec
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
require "multi_mail/version"
|
2
|
+
require File.expand_path('../lib/multi_mail/version', __FILE__)
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = "multi_mail"
|
@@ -16,10 +15,18 @@ Gem::Specification.new do |s|
|
|
16
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
16
|
s.require_paths = ["lib"]
|
18
17
|
|
19
|
-
s.add_runtime_dependency 'mail', '~> 2.
|
18
|
+
s.add_runtime_dependency 'mail', '~> 2.5.3' # Rails 3.2.13, less buggy than 2.4.x
|
20
19
|
s.add_runtime_dependency 'multimap', '~> 1.1.2'
|
20
|
+
s.add_runtime_dependency 'rack', '~> 1.4'
|
21
|
+
|
22
|
+
# For testing
|
23
|
+
s.add_development_dependency 'coveralls'
|
24
|
+
s.add_development_dependency 'json', '~> 1.7.7' # to silence coveralls warning
|
25
|
+
s.add_development_dependency 'rake'
|
21
26
|
s.add_development_dependency 'rspec', '~> 2.10'
|
22
|
-
|
27
|
+
|
28
|
+
# For Rake tasks
|
23
29
|
s.add_development_dependency 'mandrill-api', '~> 1.0.12'
|
24
|
-
s.add_development_dependency '
|
30
|
+
s.add_development_dependency 'postmark'
|
31
|
+
s.add_development_dependency 'rest-client', '~> 1.6.7'
|
25
32
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'multi_mail/cloudmailin/receiver'
|
3
|
+
|
4
|
+
describe MultiMail::Receiver::Cloudmailin do
|
5
|
+
context 'after initialization' do
|
6
|
+
context 'with invalid HTTP POST format' do
|
7
|
+
let :service do
|
8
|
+
MultiMail::Receiver.new({
|
9
|
+
:provider => :cloudmailin,
|
10
|
+
:http_post_format => 'invalid',
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#transform' do
|
15
|
+
it 'should raise an error if :http_post_format is invalid' do
|
16
|
+
expect{ service.transform({}) }.to raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
[false, true].each do |action_dispatch|
|
22
|
+
let :action_dispatch do
|
23
|
+
action_dispatch
|
24
|
+
end
|
25
|
+
|
26
|
+
['raw', 'json', 'multipart', '', nil].each do |http_post_format|
|
27
|
+
context "with #{http_post_format.inspect} format and #{action_dispatch ? 'ActionDispatch' : 'Rack'}" do
|
28
|
+
let :http_post_format do
|
29
|
+
http_post_format
|
30
|
+
end
|
31
|
+
|
32
|
+
let :actual_http_post_format do
|
33
|
+
http_post_format.to_s.empty? ? 'raw' : http_post_format
|
34
|
+
end
|
35
|
+
|
36
|
+
let :service do
|
37
|
+
MultiMail::Receiver.new({
|
38
|
+
:provider => :cloudmailin,
|
39
|
+
:http_post_format => http_post_format,
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
def params(fixture)
|
44
|
+
MultiMail::Receiver::Cloudmailin.parse(response("cloudmailin/#{actual_http_post_format}", fixture, action_dispatch))
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#transform' do
|
48
|
+
it 'should return a mail message' do
|
49
|
+
messages = service.transform(params('valid'))
|
50
|
+
messages.size.should == 1
|
51
|
+
message = messages[0]
|
52
|
+
|
53
|
+
# Headers
|
54
|
+
message.date.should == DateTime.parse('Mon, 15 Apr 2013 20:20:12 -04:00')
|
55
|
+
message.from.should == ['james@opennorth.ca']
|
56
|
+
message.to.should == ['5dae6f85cd65d30d384a@cloudmailin.net']
|
57
|
+
message.subject.should == 'Test'
|
58
|
+
|
59
|
+
# Body
|
60
|
+
message.multipart?.should == true
|
61
|
+
message.parts.size.should == 4
|
62
|
+
text_part = message.parts.find{|part| part.content_type == 'text/plain'}
|
63
|
+
html_part = message.parts.find{|part| part.content_type == 'text/html; charset=UTF-8'}
|
64
|
+
text_part.body.decoded.should == "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n\n> multiline\n> quoted\n> text\n\n\n--\nSignature block"
|
65
|
+
|
66
|
+
# @note Due to a Cloudmailin bug, the HTML part is missing content
|
67
|
+
# unless you use the "raw" HTTP POST format.
|
68
|
+
if actual_http_post_format == 'raw'
|
69
|
+
html_part.body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html><html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><head></head><br><div></div><div><br></div><div><b>some more bold text</b></div><div><b><br></b></div><div><b></b></div></body></html><html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><b></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><br></span></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><i>some italic text</i></span></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><br></span></b></div><div><blockquote type="cite">multiline</blockquote><blockquote type="cite">quoted</blockquote><blockquote type="cite">text</blockquote></div><div><br></div><div>--</div><div>Signature block</div></body></html>)
|
70
|
+
else
|
71
|
+
html_part.body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html>)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Attachments
|
75
|
+
attachment0 = message.attachments.find{|attachment| attachment.filename == 'foo.txt'}
|
76
|
+
attachment1 = message.attachments.find{|attachment| attachment.filename == 'bar.txt'}
|
77
|
+
# @note Cloudmailin removes the newline at the end of the file,
|
78
|
+
# unless you use the "raw" HTTP POST format.
|
79
|
+
if actual_http_post_format == 'raw'
|
80
|
+
attachment0.read.should == "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
|
81
|
+
attachment1.read.should == "Nam accumsan euismod eros et rhoncus.\n"
|
82
|
+
else
|
83
|
+
attachment0.read.should == "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
84
|
+
attachment1.read.should == "Nam accumsan euismod eros et rhoncus."
|
85
|
+
end
|
86
|
+
|
87
|
+
# Extra Cloudmailin parameters
|
88
|
+
if actual_http_post_format == 'raw'
|
89
|
+
message['reply_plain'].should be_nil
|
90
|
+
else
|
91
|
+
message['reply_plain'].value.should == "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n"
|
92
|
+
end
|
93
|
+
message['spf-result'].value.should == 'pass'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#spam?' do
|
98
|
+
it 'should return true if the response is spam' do
|
99
|
+
message = service.transform(params('spam'))[0]
|
100
|
+
service.spam?(message).should == true
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should return false if the response is ham' do
|
104
|
+
message = service.transform(params('valid'))[0]
|
105
|
+
service.spam?(message).should == false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
User-Agent: CloudMailin Server
|
3
|
+
Host: requestb.in
|
4
|
+
Content-Type: application/json
|
5
|
+
Content-Length: 2886
|
6
|
+
Connection: close
|
7
|
+
|
8
|
+
{
|
9
|
+
"headers": {
|
10
|
+
"Return-Path": "james@opennorth.ca",
|
11
|
+
"Received": [
|
12
|
+
"by mail-ie0-f179.google.com with SMTP id 16so1969083iea.10 for <5dae6f85cd65d30d384a@cloudmailin.net>; Mon, 15 Apr 2013 18:42:49 -0700",
|
13
|
+
"from [192.168.0.110] ([69.165.215.199]) by mx.google.com with ESMTPS id n7sm13633177igb.9.2013.04.15.18.42.47 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 15 Apr 2013 18:42:48 -0700"
|
14
|
+
],
|
15
|
+
"Date": "Mon, 15 Apr 2013 20:20:12 -0400",
|
16
|
+
"From": "James McKinney <james@opennorth.ca>",
|
17
|
+
"To": "5dae6f85cd65d30d384a@cloudmailin.net",
|
18
|
+
"Message-ID": "<68CFE2AD-5B45-4092-B96B-857C7C83F2FD@opennorth.ca>",
|
19
|
+
"Subject": "Test",
|
20
|
+
"Mime-Version": "1.0",
|
21
|
+
"Content-Type": "multipart/alternative; boundary=\"Apple-Mail=_5BFC0BD3-5B75-44B5-969D-945C65A1B798\"",
|
22
|
+
"X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:content-type:subject:date:message-id:to :mime-version:x-mailer:x-gm-message-state; bh=GOPBHZuTURFHkef2tJkyotDoTS4aiD6AxzXm86f7T4c=; b=G4+E8pKvwe4/vfLKfUaocHshj6nysczApUpAg1IhwQYcWS2+42fLNhMQXg7biOMxXD 6UrdP4vCiOcKqmk5w+hhtggYrMF5N1UHnI6Ou+JhaHbpBX87YpvgxGAbQkQPMMufgdfN eaCDVMcnOMoa3zNaDG/JPwEavU2rXzSqwjbcy2zHxUtxdfc30HW6G15xr5cNZAYPXo0N 43AdVeBRTLOKHFOkHkBNx7CT3bnpAXTdq3uXPkHVrjuE+UqQgU5uW+zBbqskEboKZIXe mqdWtkmUkrAcC/XQEF6w4WQEMJmh0X3onMcWe7ZJJwdLPQ7uAPtdleRFyMwLSe6nX159 8/ww==",
|
23
|
+
"X-Received": "by 10.50.178.105 with SMTP id cx9mr6523935igc.111.1366076569637; Mon, 15 Apr 2013 18:42:49 -0700 (PDT)",
|
24
|
+
"X-Mailer": "Apple Mail (2.1283)",
|
25
|
+
"X-Gm-Message-State": "ALoCoQluErpLKQotSpx3bJ2xN652WvYooGCb2C1yra99Um8DODvBLQbHdtsQoEFb//aIB219tHGO"
|
26
|
+
},
|
27
|
+
"envelope": {
|
28
|
+
"to": "5dae6f85cd65d30d384a@cloudmailin.net",
|
29
|
+
"recipients": [
|
30
|
+
"5dae6f85cd65d30d384a@cloudmailin.net"
|
31
|
+
],
|
32
|
+
"from": "james@opennorth.ca",
|
33
|
+
"helo_domain": "mail-ie0-f179.google.com",
|
34
|
+
"remote_ip": "209.85.223.179",
|
35
|
+
"spf": {
|
36
|
+
"result": "fail",
|
37
|
+
"domain": "opennorth.ca"
|
38
|
+
}
|
39
|
+
},
|
40
|
+
"plain": "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n\n> multiline\n> quoted\n> text\n\n\n--\nSignature block",
|
41
|
+
"html": "<html><head></head><body style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; \"><b>bold text</b><div><br></div><div></div></body></html>",
|
42
|
+
"reply_plain": "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n",
|
43
|
+
"attachments": [
|
44
|
+
{
|
45
|
+
"content": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=",
|
46
|
+
"file_name": "foo.txt",
|
47
|
+
"content_type": "text/plain",
|
48
|
+
"size": "56",
|
49
|
+
"disposition": "attachment"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"content": "TmFtIGFjY3Vtc2FuIGV1aXNtb2QgZXJvcyBldCByaG9uY3VzLg==",
|
53
|
+
"file_name": "bar.txt",
|
54
|
+
"content_type": "text/plain",
|
55
|
+
"size": "37",
|
56
|
+
"disposition": "attachment"
|
57
|
+
}
|
58
|
+
]
|
59
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
User-Agent: CloudMailin Server
|
3
|
+
Host: requestb.in
|
4
|
+
Content-Type: application/json
|
5
|
+
Content-Length: 2886
|
6
|
+
Connection: close
|
7
|
+
|
8
|
+
{
|
9
|
+
"headers": {
|
10
|
+
"Return-Path": "james@opennorth.ca",
|
11
|
+
"Received": [
|
12
|
+
"by mail-ie0-f179.google.com with SMTP id 16so1969083iea.10 for <5dae6f85cd65d30d384a@cloudmailin.net>; Mon, 15 Apr 2013 18:42:49 -0700",
|
13
|
+
"from [192.168.0.110] ([69.165.215.199]) by mx.google.com with ESMTPS id n7sm13633177igb.9.2013.04.15.18.42.47 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 15 Apr 2013 18:42:48 -0700"
|
14
|
+
],
|
15
|
+
"Date": "Mon, 15 Apr 2013 20:20:12 -0400",
|
16
|
+
"From": "James McKinney <james@opennorth.ca>",
|
17
|
+
"To": "5dae6f85cd65d30d384a@cloudmailin.net",
|
18
|
+
"Message-ID": "<68CFE2AD-5B45-4092-B96B-857C7C83F2FD@opennorth.ca>",
|
19
|
+
"Subject": "Test",
|
20
|
+
"Mime-Version": "1.0",
|
21
|
+
"Content-Type": "multipart/alternative; boundary=\"Apple-Mail=_5BFC0BD3-5B75-44B5-969D-945C65A1B798\"",
|
22
|
+
"X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:content-type:subject:date:message-id:to :mime-version:x-mailer:x-gm-message-state; bh=GOPBHZuTURFHkef2tJkyotDoTS4aiD6AxzXm86f7T4c=; b=G4+E8pKvwe4/vfLKfUaocHshj6nysczApUpAg1IhwQYcWS2+42fLNhMQXg7biOMxXD 6UrdP4vCiOcKqmk5w+hhtggYrMF5N1UHnI6Ou+JhaHbpBX87YpvgxGAbQkQPMMufgdfN eaCDVMcnOMoa3zNaDG/JPwEavU2rXzSqwjbcy2zHxUtxdfc30HW6G15xr5cNZAYPXo0N 43AdVeBRTLOKHFOkHkBNx7CT3bnpAXTdq3uXPkHVrjuE+UqQgU5uW+zBbqskEboKZIXe mqdWtkmUkrAcC/XQEF6w4WQEMJmh0X3onMcWe7ZJJwdLPQ7uAPtdleRFyMwLSe6nX159 8/ww==",
|
23
|
+
"X-Received": "by 10.50.178.105 with SMTP id cx9mr6523935igc.111.1366076569637; Mon, 15 Apr 2013 18:42:49 -0700 (PDT)",
|
24
|
+
"X-Mailer": "Apple Mail (2.1283)",
|
25
|
+
"X-Gm-Message-State": "ALoCoQluErpLKQotSpx3bJ2xN652WvYooGCb2C1yra99Um8DODvBLQbHdtsQoEFb//aIB219tHGO"
|
26
|
+
},
|
27
|
+
"envelope": {
|
28
|
+
"to": "5dae6f85cd65d30d384a@cloudmailin.net",
|
29
|
+
"recipients": [
|
30
|
+
"5dae6f85cd65d30d384a@cloudmailin.net"
|
31
|
+
],
|
32
|
+
"from": "james@opennorth.ca",
|
33
|
+
"helo_domain": "mail-ie0-f179.google.com",
|
34
|
+
"remote_ip": "209.85.223.179",
|
35
|
+
"spf": {
|
36
|
+
"result": "pass",
|
37
|
+
"domain": "opennorth.ca"
|
38
|
+
}
|
39
|
+
},
|
40
|
+
"plain": "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n\n> multiline\n> quoted\n> text\n\n\n--\nSignature block",
|
41
|
+
"html": "<html><head></head><body style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; \"><b>bold text</b><div><br></div><div></div></body></html>",
|
42
|
+
"reply_plain": "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n",
|
43
|
+
"attachments": [
|
44
|
+
{
|
45
|
+
"content": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=",
|
46
|
+
"file_name": "foo.txt",
|
47
|
+
"content_type": "text/plain",
|
48
|
+
"size": "56",
|
49
|
+
"disposition": "attachment"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"content": "TmFtIGFjY3Vtc2FuIGV1aXNtb2QgZXJvcyBldCByaG9uY3VzLg==",
|
53
|
+
"file_name": "bar.txt",
|
54
|
+
"content_type": "text/plain",
|
55
|
+
"size": "37",
|
56
|
+
"disposition": "attachment"
|
57
|
+
}
|
58
|
+
]
|
59
|
+
}
|
@@ -0,0 +1,135 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
User-Agent: CloudMailin Server
|
3
|
+
Host: requestb.in
|
4
|
+
Content-Type: multipart/form-data; boundary=----cloudmailinboundry
|
5
|
+
Content-Length: 4157
|
6
|
+
Connection: close
|
7
|
+
|
8
|
+
------cloudmailinboundry
|
9
|
+
Content-Disposition: form-data; name="plain"
|
10
|
+
|
11
|
+
bold text
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
some more bold text
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
some italic text
|
20
|
+
|
21
|
+
> multiline
|
22
|
+
> quoted
|
23
|
+
> text
|
24
|
+
|
25
|
+
|
26
|
+
--
|
27
|
+
Signature block
|
28
|
+
------cloudmailinboundry
|
29
|
+
Content-Disposition: form-data; name="html"
|
30
|
+
|
31
|
+
<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html>
|
32
|
+
------cloudmailinboundry
|
33
|
+
Content-Disposition: form-data; name="reply_plain"
|
34
|
+
|
35
|
+
bold text
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
some more bold text
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
some italic text
|
44
|
+
|
45
|
+
------cloudmailinboundry
|
46
|
+
Content-Disposition: form-data; name="headers[Return-Path]"
|
47
|
+
|
48
|
+
james@opennorth.ca
|
49
|
+
------cloudmailinboundry
|
50
|
+
Content-Disposition: form-data; name="headers[Received][0]"
|
51
|
+
|
52
|
+
by mail-ie0-f177.google.com with SMTP id 9so6080549iec.8 for <5dae6f85cd65d30d384a@cloudmailin.net>; Mon, 15 Apr 2013 17:57:43 -0700
|
53
|
+
------cloudmailinboundry
|
54
|
+
Content-Disposition: form-data; name="headers[Received][1]"
|
55
|
+
|
56
|
+
from [192.168.0.110] ([69.165.215.199]) by mx.google.com with ESMTPS id in10sm13631125igc.1.2013.04.15.17.57.41 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 15 Apr 2013 17:57:42 -0700
|
57
|
+
------cloudmailinboundry
|
58
|
+
Content-Disposition: form-data; name="headers[Date]"
|
59
|
+
|
60
|
+
Mon, 15 Apr 2013 20:20:12 -0400
|
61
|
+
------cloudmailinboundry
|
62
|
+
Content-Disposition: form-data; name="headers[From]"
|
63
|
+
|
64
|
+
James McKinney <james@opennorth.ca>
|
65
|
+
------cloudmailinboundry
|
66
|
+
Content-Disposition: form-data; name="headers[To]"
|
67
|
+
|
68
|
+
5dae6f85cd65d30d384a@cloudmailin.net
|
69
|
+
------cloudmailinboundry
|
70
|
+
Content-Disposition: form-data; name="headers[Message-ID]"
|
71
|
+
|
72
|
+
<108F3A29-5C44-428E-999C-2CB6440408D5@opennorth.ca>
|
73
|
+
------cloudmailinboundry
|
74
|
+
Content-Disposition: form-data; name="headers[Subject]"
|
75
|
+
|
76
|
+
Test
|
77
|
+
------cloudmailinboundry
|
78
|
+
Content-Disposition: form-data; name="headers[Mime-Version]"
|
79
|
+
|
80
|
+
1.0
|
81
|
+
------cloudmailinboundry
|
82
|
+
Content-Disposition: form-data; name="headers[X-Google-DKIM-Signature]"
|
83
|
+
|
84
|
+
v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:content-type:subject:date:message-id:to :mime-version:x-mailer:x-gm-message-state; bh=BiKzbIOkKcOY/hTNuM9q0HddkHAQcaz3glGr3etUW4w=; b=Ub1zuyL6VBLnkcvUD4VB3JaC+twnc2Nb8qweMk8LNgiO2I/E9c9EsnEDQevHhrVcZG IClaweSN3f8IwzSk1xGO0ZtXTTuduZGlWu0CN3za+3apnksOurg3wJms56FaYvLd/wYd GBm18IIPH8YImgM81/KGobbHHT0lCLolCLeRPxq2nRbwqzeJBdtKzZ4Aqs80suw0Ujv3 91ASHlw89M/VLutQdMCcE+xQihEzu6NYlBGrnZvs0sKA5umIere8fwrZ+YwUx7txVAbL SjhxV/q+3harEfsKJwv0f63rQXahs8RQmI7CCrZed40yUmNg90davgTwZWdga/5/ymEB 9Agg==
|
85
|
+
------cloudmailinboundry
|
86
|
+
Content-Disposition: form-data; name="headers[X-Received]"
|
87
|
+
|
88
|
+
by 10.50.66.133 with SMTP id f5mr6726478igt.38.1366073863595; Mon, 15 Apr 2013 17:57:43 -0700 (PDT)
|
89
|
+
------cloudmailinboundry
|
90
|
+
Content-Disposition: form-data; name="headers[X-Mailer]"
|
91
|
+
|
92
|
+
Apple Mail (2.1283)
|
93
|
+
------cloudmailinboundry
|
94
|
+
Content-Disposition: form-data; name="headers[X-Gm-Message-State]"
|
95
|
+
|
96
|
+
ALoCoQm7DE53hxsQyXVPB5Jezuk49j/ND6jwZ/brXrhccwCDVgBjGVYlsY0qvS7Q+jzQSZSFtjms
|
97
|
+
------cloudmailinboundry
|
98
|
+
Content-Disposition: form-data; name="envelope[to]"
|
99
|
+
|
100
|
+
5dae6f85cd65d30d384a@cloudmailin.net
|
101
|
+
------cloudmailinboundry
|
102
|
+
Content-Disposition: form-data; name="envelope[recipients][0]"
|
103
|
+
|
104
|
+
5dae6f85cd65d30d384a@cloudmailin.net
|
105
|
+
------cloudmailinboundry
|
106
|
+
Content-Disposition: form-data; name="envelope[from]"
|
107
|
+
|
108
|
+
james@opennorth.ca
|
109
|
+
------cloudmailinboundry
|
110
|
+
Content-Disposition: form-data; name="envelope[helo_domain]"
|
111
|
+
|
112
|
+
mail-ie0-f177.google.com
|
113
|
+
------cloudmailinboundry
|
114
|
+
Content-Disposition: form-data; name="envelope[remote_ip]"
|
115
|
+
|
116
|
+
209.85.223.177
|
117
|
+
------cloudmailinboundry
|
118
|
+
Content-Disposition: form-data; name="envelope[spf][result]"
|
119
|
+
|
120
|
+
fail
|
121
|
+
------cloudmailinboundry
|
122
|
+
Content-Disposition: form-data; name="envelope[spf][domain]"
|
123
|
+
|
124
|
+
opennorth.ca
|
125
|
+
------cloudmailinboundry
|
126
|
+
Content-Disposition: form-data; name="attachments[0]"; filename="foo.txt"
|
127
|
+
Content-Type: text/plain
|
128
|
+
|
129
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
130
|
+
------cloudmailinboundry
|
131
|
+
Content-Disposition: form-data; name="attachments[1]"; filename="bar.txt"
|
132
|
+
Content-Type: text/plain
|
133
|
+
|
134
|
+
Nam accumsan euismod eros et rhoncus.
|
135
|
+
------cloudmailinboundry--
|
@@ -0,0 +1,135 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
User-Agent: CloudMailin Server
|
3
|
+
Host: requestb.in
|
4
|
+
Content-Type: multipart/form-data; boundary=----cloudmailinboundry
|
5
|
+
Content-Length: 4157
|
6
|
+
Connection: close
|
7
|
+
|
8
|
+
------cloudmailinboundry
|
9
|
+
Content-Disposition: form-data; name="plain"
|
10
|
+
|
11
|
+
bold text
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
some more bold text
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
some italic text
|
20
|
+
|
21
|
+
> multiline
|
22
|
+
> quoted
|
23
|
+
> text
|
24
|
+
|
25
|
+
|
26
|
+
--
|
27
|
+
Signature block
|
28
|
+
------cloudmailinboundry
|
29
|
+
Content-Disposition: form-data; name="html"
|
30
|
+
|
31
|
+
<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html>
|
32
|
+
------cloudmailinboundry
|
33
|
+
Content-Disposition: form-data; name="reply_plain"
|
34
|
+
|
35
|
+
bold text
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
some more bold text
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
some italic text
|
44
|
+
|
45
|
+
------cloudmailinboundry
|
46
|
+
Content-Disposition: form-data; name="headers[Return-Path]"
|
47
|
+
|
48
|
+
james@opennorth.ca
|
49
|
+
------cloudmailinboundry
|
50
|
+
Content-Disposition: form-data; name="headers[Received][0]"
|
51
|
+
|
52
|
+
by mail-ie0-f177.google.com with SMTP id 9so6080549iec.8 for <5dae6f85cd65d30d384a@cloudmailin.net>; Mon, 15 Apr 2013 17:57:43 -0700
|
53
|
+
------cloudmailinboundry
|
54
|
+
Content-Disposition: form-data; name="headers[Received][1]"
|
55
|
+
|
56
|
+
from [192.168.0.110] ([69.165.215.199]) by mx.google.com with ESMTPS id in10sm13631125igc.1.2013.04.15.17.57.41 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 15 Apr 2013 17:57:42 -0700
|
57
|
+
------cloudmailinboundry
|
58
|
+
Content-Disposition: form-data; name="headers[Date]"
|
59
|
+
|
60
|
+
Mon, 15 Apr 2013 20:20:12 -0400
|
61
|
+
------cloudmailinboundry
|
62
|
+
Content-Disposition: form-data; name="headers[From]"
|
63
|
+
|
64
|
+
James McKinney <james@opennorth.ca>
|
65
|
+
------cloudmailinboundry
|
66
|
+
Content-Disposition: form-data; name="headers[To]"
|
67
|
+
|
68
|
+
5dae6f85cd65d30d384a@cloudmailin.net
|
69
|
+
------cloudmailinboundry
|
70
|
+
Content-Disposition: form-data; name="headers[Message-ID]"
|
71
|
+
|
72
|
+
<108F3A29-5C44-428E-999C-2CB6440408D5@opennorth.ca>
|
73
|
+
------cloudmailinboundry
|
74
|
+
Content-Disposition: form-data; name="headers[Subject]"
|
75
|
+
|
76
|
+
Test
|
77
|
+
------cloudmailinboundry
|
78
|
+
Content-Disposition: form-data; name="headers[Mime-Version]"
|
79
|
+
|
80
|
+
1.0
|
81
|
+
------cloudmailinboundry
|
82
|
+
Content-Disposition: form-data; name="headers[X-Google-DKIM-Signature]"
|
83
|
+
|
84
|
+
v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:content-type:subject:date:message-id:to :mime-version:x-mailer:x-gm-message-state; bh=BiKzbIOkKcOY/hTNuM9q0HddkHAQcaz3glGr3etUW4w=; b=Ub1zuyL6VBLnkcvUD4VB3JaC+twnc2Nb8qweMk8LNgiO2I/E9c9EsnEDQevHhrVcZG IClaweSN3f8IwzSk1xGO0ZtXTTuduZGlWu0CN3za+3apnksOurg3wJms56FaYvLd/wYd GBm18IIPH8YImgM81/KGobbHHT0lCLolCLeRPxq2nRbwqzeJBdtKzZ4Aqs80suw0Ujv3 91ASHlw89M/VLutQdMCcE+xQihEzu6NYlBGrnZvs0sKA5umIere8fwrZ+YwUx7txVAbL SjhxV/q+3harEfsKJwv0f63rQXahs8RQmI7CCrZed40yUmNg90davgTwZWdga/5/ymEB 9Agg==
|
85
|
+
------cloudmailinboundry
|
86
|
+
Content-Disposition: form-data; name="headers[X-Received]"
|
87
|
+
|
88
|
+
by 10.50.66.133 with SMTP id f5mr6726478igt.38.1366073863595; Mon, 15 Apr 2013 17:57:43 -0700 (PDT)
|
89
|
+
------cloudmailinboundry
|
90
|
+
Content-Disposition: form-data; name="headers[X-Mailer]"
|
91
|
+
|
92
|
+
Apple Mail (2.1283)
|
93
|
+
------cloudmailinboundry
|
94
|
+
Content-Disposition: form-data; name="headers[X-Gm-Message-State]"
|
95
|
+
|
96
|
+
ALoCoQm7DE53hxsQyXVPB5Jezuk49j/ND6jwZ/brXrhccwCDVgBjGVYlsY0qvS7Q+jzQSZSFtjms
|
97
|
+
------cloudmailinboundry
|
98
|
+
Content-Disposition: form-data; name="envelope[to]"
|
99
|
+
|
100
|
+
5dae6f85cd65d30d384a@cloudmailin.net
|
101
|
+
------cloudmailinboundry
|
102
|
+
Content-Disposition: form-data; name="envelope[recipients][0]"
|
103
|
+
|
104
|
+
5dae6f85cd65d30d384a@cloudmailin.net
|
105
|
+
------cloudmailinboundry
|
106
|
+
Content-Disposition: form-data; name="envelope[from]"
|
107
|
+
|
108
|
+
james@opennorth.ca
|
109
|
+
------cloudmailinboundry
|
110
|
+
Content-Disposition: form-data; name="envelope[helo_domain]"
|
111
|
+
|
112
|
+
mail-ie0-f177.google.com
|
113
|
+
------cloudmailinboundry
|
114
|
+
Content-Disposition: form-data; name="envelope[remote_ip]"
|
115
|
+
|
116
|
+
209.85.223.177
|
117
|
+
------cloudmailinboundry
|
118
|
+
Content-Disposition: form-data; name="envelope[spf][result]"
|
119
|
+
|
120
|
+
pass
|
121
|
+
------cloudmailinboundry
|
122
|
+
Content-Disposition: form-data; name="envelope[spf][domain]"
|
123
|
+
|
124
|
+
opennorth.ca
|
125
|
+
------cloudmailinboundry
|
126
|
+
Content-Disposition: form-data; name="attachments[0]"; filename="foo.txt"
|
127
|
+
Content-Type: text/plain
|
128
|
+
|
129
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
130
|
+
------cloudmailinboundry
|
131
|
+
Content-Disposition: form-data; name="attachments[1]"; filename="bar.txt"
|
132
|
+
Content-Type: text/plain
|
133
|
+
|
134
|
+
Nam accumsan euismod eros et rhoncus.
|
135
|
+
------cloudmailinboundry--
|