multi_mail 0.0.1 → 0.0.2

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.
Files changed (59) hide show
  1. data/.travis.yml +4 -0
  2. data/.yardopts +4 -0
  3. data/Gemfile +1 -1
  4. data/README.md +107 -12
  5. data/Rakefile +75 -52
  6. data/lib/multi_mail/cloudmailin/receiver.rb +100 -0
  7. data/lib/multi_mail/mailgun/receiver.rb +74 -36
  8. data/lib/multi_mail/mailgun/sender.rb +14 -0
  9. data/lib/multi_mail/mandrill/receiver.rb +77 -35
  10. data/lib/multi_mail/mandrill/sender.rb +14 -0
  11. data/lib/multi_mail/postmark/receiver.rb +68 -0
  12. data/lib/multi_mail/postmark/sender.rb +14 -0
  13. data/lib/multi_mail/receiver/base.rb +125 -8
  14. data/lib/multi_mail/receiver.rb +10 -4
  15. data/lib/multi_mail/sender/base.rb +7 -0
  16. data/lib/multi_mail/sender.rb +10 -4
  17. data/lib/multi_mail/sendgrid/receiver.rb +42 -0
  18. data/lib/multi_mail/sendgrid/sender.rb +11 -0
  19. data/lib/multi_mail/service.rb +15 -4
  20. data/lib/multi_mail/simple/receiver.rb +15 -0
  21. data/lib/multi_mail/simple/sender.rb +14 -0
  22. data/lib/multi_mail/version.rb +1 -1
  23. data/lib/multi_mail.rb +71 -3
  24. data/multi_mail.gemspec +12 -5
  25. data/spec/cloudmailin/receiver_spec.rb +112 -0
  26. data/spec/fixtures/cloudmailin/json/spam.txt +59 -0
  27. data/spec/fixtures/cloudmailin/json/valid.txt +59 -0
  28. data/spec/fixtures/cloudmailin/multipart/spam.txt +135 -0
  29. data/spec/fixtures/cloudmailin/multipart/valid.txt +135 -0
  30. data/spec/fixtures/cloudmailin/raw/spam.txt +137 -0
  31. data/spec/fixtures/cloudmailin/raw/valid.txt +137 -0
  32. data/spec/fixtures/mailgun/parsed/invalid.txt +8 -0
  33. data/spec/fixtures/mailgun/parsed/missing.txt +8 -0
  34. data/spec/fixtures/mailgun/parsed/spam.txt +8 -0
  35. data/spec/fixtures/mailgun/parsed/valid.txt +187 -0
  36. data/spec/fixtures/mandrill/spam.txt +9 -0
  37. data/spec/fixtures/mandrill/valid.txt +10 -0
  38. data/spec/fixtures/multipart.txt +99 -0
  39. data/spec/fixtures/postmark/spam.txt +83 -0
  40. data/spec/fixtures/postmark/valid.txt +92 -0
  41. data/spec/fixtures/simple/valid.txt +4 -0
  42. data/spec/mailgun/receiver_spec.rb +105 -50
  43. data/spec/mailgun/sender_spec.rb +0 -0
  44. data/spec/mandrill/receiver_spec.rb +35 -35
  45. data/spec/mandrill/sender_spec.rb +0 -0
  46. data/spec/multi_mail_spec.rb +63 -0
  47. data/spec/postmark/receiver_spec.rb +60 -0
  48. data/spec/postmark/sender_spec.rb +0 -0
  49. data/spec/receiver/base_spec.rb +73 -8
  50. data/spec/sender/base_spec.rb +21 -0
  51. data/spec/service_spec.rb +2 -2
  52. data/spec/simple/receiver_spec.rb +36 -0
  53. data/spec/simple/sender_spec.rb +0 -0
  54. data/spec/spec_helper.rb +123 -10
  55. metadata +141 -21
  56. data/spec/fixtures/mailgun/invalid.txt +0 -8
  57. data/spec/fixtures/mailgun/missing.txt +0 -8
  58. data/spec/fixtures/mailgun/spam.txt +0 -8
  59. 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
- autoload :Service, 'multi_mail/service'
14
- autoload :Receiver, 'multi_mail/receiver'
15
- autoload :Sender, 'multi_mail/sender'
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
- $:.push File.expand_path("../lib", __FILE__)
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.4.4' # Rails 3.2.9
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
- s.add_development_dependency 'rest-client', '~> 1.6.7'
27
+
28
+ # For Rake tasks
23
29
  s.add_development_dependency 'mandrill-api', '~> 1.0.12'
24
- s.add_development_dependency 'rake'
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--