Repository: inbucket/inbucket (go)

Issue:
Inline Attachments not displayed
Reported to the wrong project. Details at jhillyerd/enmime#287

Summary: Inbucket ignores `Content-Disposition: inline` attachments

Pull request:
message: Include inlines when returning attachments
Closes #357

Signed-off-by: James Hillyerd <james@hillyerd.com>


Patch:
diff --git a/pkg/message/message.go b/pkg/message/message.go
index ea3616d..a6b5f52 100644
--- a/pkg/message/message.go
+++ b/pkg/message/message.go
@@ -28,7 +28,9 @@ func New(m event.MessageMetadata, e *enmime.Envelope) *Message {
 
 // Attachments returns the MIME attachments for the message.
 func (m *Message) Attachments() []*enmime.Part {
-	return m.env.Attachments
+	attachments := append([]*enmime.Part{}, m.env.Inlines...)
+	attachments = append(attachments, m.env.Attachments...)
+	return attachments
 }
 
 // Header returns the header map for this message.


Test patch:
diff --git a/etc/swaks-tests/mime-inline.raw b/etc/swaks-tests/mime-inline.raw
new file mode 100644
index 0000000..911885f
--- /dev/null
+++ b/etc/swaks-tests/mime-inline.raw
@@ -0,0 +1,43 @@
+Subject: Inline attachment
+From: %FROM_ADDRESS%
+To: %TO_ADDRESS%
+Message-ID: <1234@example.com>
+Date: %DATE%
+Content-Type: multipart/mixed; boundary=boundary1
+
+--boundary1
+Content-Type: text/html; charset=utf-8
+Content-Transfer-Encoding: quoted-printable
+
+<!DOCTYPE html>
+<html>
+<head>
+<title>Hello World HTML</title>
+</head>
+<body>
+<h1 style=3D"color:red">Hello World</h1>
+</body>
+</html>
+
+--boundary1
+Content-Type: application/pdf; name=Hello-World.pdf
+Content-Transfer-Encoding: base64
+Content-Disposition: inline; name=Hello-World.pdf;
+ filename=Hello-World.pdf
+
+JVBERi0xLjQKJcK1wrYKCjEgMCBvYmoKPDwvVGl0bGUoSGVsbG8gV29ybGQpL0F1dGhvcihBZHJp
+dW0pPj4KZW5kb2JqCgoyIDAgb2JqCjw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAzIDAgUj4+CmVuZG9i
+agoKMyAwIG9iago8PC9UeXBlL1BhZ2VzL01lZGlhQm94WzAgMCA1OTUgODQyXS9SZXNvdXJjZXM8
+PC9Gb250PDwvRjEgNCAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9LaWRzWzUgMCBSXS9Db3Vu
+dCAxPj4KZW5kb2JqCgo0IDAgb2JqCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1R5cGUxL0Jhc2VGb250
+L0hlbHZldGljYS9FbmNvZGluZy9XaW5BbnNpRW5jb2Rpbmc+PgplbmRvYmoKCjUgMCBvYmoKPDwv
+VHlwZS9QYWdlL1BhcmVudCAzIDAgUi9Db250ZW50cyA2IDAgUj4+CmVuZG9iagoKNiAwIG9iago8
+PC9MZW5ndGggNTEvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnic03czVDCxUAhJ43IK4TI3
+UjA3MVMISeHS8EjNyclXCM8vyknRVAjJ4nIN4QIA3FcKuwplbmRzdHJlYW0KZW5kb2JqCgp4cmVm
+CjAgNwowMDAwMDAwMDAwIDY1NTM2IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDAwMDA3MSAw
+MDAwMCBuIAowMDAwMDAwMTE3IDAwMDAwIG4gCjAwMDAwMDAyNDIgMDAwMDAgbiAKMDAwMDAwMDMz
+MSAwMDAwMCBuIAowMDAwMDAwMzkwIDAwMDAwIG4gCgp0cmFpbGVyCjw8L1NpemUgNy9JbmZvIDEg
+MCBSL1Jvb3QgMiAwIFI+PgpzdGFydHhyZWYKNTA5CiUlRU9GCg==
+
+
+--boundary1--
diff --git a/etc/swaks-tests/run-tests.sh b/etc/swaks-tests/run-tests.sh
index a6f0f61..660b4ef 100755
--- a/etc/swaks-tests/run-tests.sh
+++ b/etc/swaks-tests/run-tests.sh
@@ -63,3 +63,6 @@ swaks $* --data mime-errors.raw
 # IP RCPT domain
 swaks $* --to="swaks@[127.0.0.1]" --h-Subject: "IPv4 RCPT Address" --body text.txt
 swaks $* --to="swaks@[IPv6:2001:db8:aaaa:1::100]" --h-Subject: "IPv6 RCPT Address" --body text.txt
+
+# Inline attachment test
+swaks $* --data mime-inline.raw
diff --git a/pkg/rest/apiv1_controller_test.go b/pkg/rest/apiv1_controller_test.go
index a3bffdf..e7a1fda 100644
--- a/pkg/rest/apiv1_controller_test.go
+++ b/pkg/rest/apiv1_controller_test.go
@@ -201,6 +201,10 @@ func TestRestMessage(t *testing.T) {
 				FileName:    "favicon.png",
 				ContentType: "image/png",
 			}},
+			Inlines: []*enmime.Part{{
+				FileName:    "statement.pdf",
+				ContentType: "application/pdf",
+			}},
 		},
 	)
 	mm.AddMessage("good", msg1)
@@ -236,10 +240,14 @@ func TestRestMessage(t *testing.T) {
 	decodedStringEquals(t, result, "header/To/[0]", "fred@fish.com")
 	decodedStringEquals(t, result, "header/To/[1]", "keyword@nsa.gov")
 	decodedStringEquals(t, result, "header/From/[0]", "noreply@inbucket.org")
-	decodedStringEquals(t, result, "attachments/[0]/filename", "favicon.png")
-	decodedStringEquals(t, result, "attachments/[0]/content-type", "image/png")
-	decodedStringEquals(t, result, "attachments/[0]/download-link", "http://localhost/serve/mailbox/good/0001/attach/0/favicon.png")
-	decodedStringEquals(t, result, "attachments/[0]/view-link", "http://localhost/serve/mailbox/good/0001/attach/0/favicon.png")
+	decodedStringEquals(t, result, "attachments/[0]/filename", "statement.pdf")
+	decodedStringEquals(t, result, "attachments/[0]/content-type", "application/pdf")
+	decodedStringEquals(t, result, "attachments/[0]/download-link", "http://localhost/serve/mailbox/good/0001/attach/0/statement.pdf")
+	decodedStringEquals(t, result, "attachments/[0]/view-link", "http://localhost/serve/mailbox/good/0001/attach/0/statement.pdf")
+	decodedStringEquals(t, result, "attachments/[1]/filename", "favicon.png")
+	decodedStringEquals(t, result, "attachments/[1]/content-type", "image/png")
+	decodedStringEquals(t, result, "attachments/[1]/download-link", "http://localhost/serve/mailbox/good/0001/attach/1/favicon.png")
+	decodedStringEquals(t, result, "attachments/[1]/view-link", "http://localhost/serve/mailbox/good/0001/attach/1/favicon.png")
 
 	if t.Failed() {
 		// Wait for handler to finish logging