emersion / emersion/go-message

Support multipart/related for inline attachments

Open
#179 4 comments 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
458
Forks
129
PR merge metrics
No merged PRs in 30d

Description

## Feature request: Support Content-Type "multipart/related" to allow inline attachments

An inline attachment (or embedded attachment) is e.g. an image attached to the mail, which is referenced and inlined directly into the HTML part of the mail. The difference to normal attachments is that an inline attachment will not be listed in the attachment list of the mail (if the client supports it).

To support inline attachments, the content-type "multipart/related" is required, which will contain the inline parts (either a single one or via multipart/alternative), as well as the embedded attachments using "content-disposition: inline".

There are two use cases which have to be accounted for:

### Use case 1: Only inline attachments

When only using inline attachments, the top-level content-type is "multipart/related". The MIME message will have the following structure:

```
From:
To:
Subject: Example with inline attachment.
Date: Mon, 10 Mar 2008 14:36:46 -0700
MIME-Version: 1.0
Content-Type: multipart/related; boundary="simple boundary"

--simple boundary
Content-Type: text/html;

...Text with reference...

--simple boundary
Content-Type: image/png; name="inline.PNG"
Content-Transfer-Encoding: base64
Content-ID: <6583CF49B56F42FEA6A4A118F46F96FB@example.com>
Content-Disposition: inline; filename=" inline.png"

...Attachment data encoded with base64...
--simple boundary--
```
Source: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcmail/92ce322f-efa1-48c5-828a-543063fa9db8

### Use case 2: Inline attachments and non-inline attachments

When mixing inline attachments with non-inline ones, the top-level content-type is "multipart/mixed", and one of its parts will be "multipart/related". The MIME message will have the following structure:

```
From:
To:
Subject: Example with inline and non-inline attachments.
Date: Mon, 10 Mar 2008 14:36:46 -0700
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="simple boundary 1"

--simple boundary 1
Content-Type: multipart/related; boundary="simple boundary 2"

--simple boundary 2
Content-Type: multipart/alternative; boundary="simple boundary 3"

--simple boundary 3
Content-Type: text/plain

...Text without inline reference...
--simple boundary 3
Content-Type: text/html

...Text with inline reference...
--simple boundary 3--
--simple boundary 2
Content-Type: image/png; name="inline.PNG"
Content-Transfer-Encoding: base64
Content-ID: <6583CF49B56F42FEA6A4A118F46F96FB@example.com>
Content-Disposition: inline; filename="Inline.png"

...Attachment data encoded with base64...
--simple boundary 2--

--simple boundary 1
Content-Type: image/png; name=" Attachment "
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Attachment.png"

...Attachment data encoded with base64...
--simple boundary 1--
```
Source: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcmail/7a08211a-760a-41af-8cab-0acf462c4094

### Proposal

To cover these use cases, I propose the following changes within the mail package. (I will also attempt to implement this myself and open a pull request in the next days.)

* Add new type `RelatedWriter` similar to the existing `Writer`, with the methods CreateInline(), CreateSingleInline() and CreateInlineAttachment() to build up the parts of "multipart/related".
* Add new function `func CreateRelatedWriter(w io.Writer, header Header) (*RelatedWriter, error)` to create a writer covering use-case 1, where the top-level content-type is "multipart/related".
* Add a new method `func (w *Writer) CreateRelated() (*RelatedWriter, error)` to the existing `Writer` to support use-case 2 with mixed the attachments.

Any comments are welcome, especially whether the naming of "RelatedWriter" is good enough for this.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.