这是indexloc提供的服务,不要输入任何密码
Skip to content

Support multipart/related for inline attachments #179

@BluePsyduck

Description

@BluePsyduck

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: <john@contoso.com>
 To: <imtiaz@contoso.com>
 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: <john@contoso.com>
 To: <imtiaz@contoso.com>
 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions