stalwartlabs / mail-builder

E-mail builder library for Rust
https://docs.rs/mail-builder/
Apache License 2.0
54 stars 17 forks source link

binary_inline should generate a multipart/related container #9

Closed wez closed 1 year ago

wez commented 1 year ago

Hi! I think this might be two bugs, one here with generation and one in mail-parser in understanding the result.

When using binary_inline to define an inline attachment, the html part and the attachment that is being referenced should belong in the same multipart/related container in order to be referenced correctly. https://stackoverflow.com/a/30424938/149111 has some practical examples.

That container is missing from the built message.

In addition, when parsing the result back with the mail-parser crate, it believes that there are multiple text and html parts.

You can see this if you modify one of the existing test cases:

diff --git a/src/lib.rs b/src/lib.rs
index a7a93e2..eaa9a45 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -613,6 +613,7 @@ mod tests {
             )
             .write_to_vec()
             .unwrap();
-        Message::parse(&output).unwrap();
+        let parsed = Message::parse(&output).unwrap();
+        panic!("{:#?}", parsed);
     }
 }

the top of the struct shows multiple parts for text and html:

---- tests::build_message stdout ----
thread 'tests::build_message' panicked at 'Message {
    html_body: [
        3,
        4,
    ],
    text_body: [
        2,
        4,
    ],
    attachments: [
        4,
        5,
        6,
    ],
    parts: [

it's interesting to see that both the html and text body list 4 as an additional part, which is also listed under attachments; I think that is probably the binary_inline part; it's the first attachment defined in the test and shows up first in the attachments array.

mdecimus commented 1 year ago

Hi,

When using binary_inline to define an inline attachment, the html part and the attachment that is being referenced should belong in the same multipart/related container in order to be referenced correctly. https://stackoverflow.com/a/30424938/149111 has some practical examples.

That needs to be done manually, the library just offers a helper method to create a simple message with a text and/or html part and attachments. If you require a different multipart layout then you'll have to build the MIME structure manually. In your example you have to add a multipart/related part and add the subparts to it.

In addition, when parsing the result back with the mail-parser crate, it believes that there are multiple text and html parts.

This is because html_body, text_body and attachments offer a representation of the message contents according to RFC 8621, Section 4.1.4. If you want to access the actual MIME structure, you need to start with parts[0] and iterate its subparts.

wez commented 1 year ago

I see. Can you share more about the intended purpose of the binary_inline method if it cannot be used to generate the attachment in a multipart/related container?

mdecimus commented 1 year ago

binary_inline is a helper function that adds a Content-ID header and sets theContent-Disposition header to inline. Its main purpose is to add embedded binaries (for example an image) that can be referenced from an HTML part by its Content-ID. I recognize that the name is a bit misleading, it should be called binary_embedded or similar.