fix(receiving): keep attachment Content-ID when forwarding with passthrough

Merged
PC
3d ago
+262-58

Forwarding an inbound email with passthrough breaks inline images.

Cause. In ReceivingSvc::forward with passthrough, the attachment Content-ID was read with MailHeader::get_key(), which returns the header name. Every inline attachment was therefore re-sent with content_id = "Content-ID", and cid: references in the HTML no longer resolved.

Fix. Read the header value with get_value() and strip the surrounding </>. The attachment mapping moved into a small passthrough_attachments(&[u8]) helper so it can be unit tested without the network (behaviour otherwise unchanged). Added a CHANGELOG entry.

Test. receiving::test::passthrough_keeps_attachment_content_id builds a multipart message with Content-ID: <logo@example.test> and asserts the serialized attachment has content_id == "logo@example.test" (red before: "Content-ID").

Reproduction

Raw message: a multipart/mixed part with Content-Disposition: attachment; filename=logo.png and Content-ID: <logo@example.test>; cargo test --lib passthrough.


This PR was prepared with the assistance of an AI tool (Claude Code).


Summary by cubic

Fixes forwarding inbound emails with passthrough so inline images keep working.

The passthrough path read the Content-ID header name instead of its value, so attachments were re-sent with content_id = "Content-ID" and cid: references in the HTML no longer resolved.

  • Reads the header value and strips the surrounding angle brackets.
  • Collects attachments across the whole MIME tree, so nested parts and inline cid: images are kept.
  • Re-sends the original text/HTML body when the caller doesn't supply one.
  • Falls back to the Content-Type name parameter for filenames and allows attachments without a filename.
  • Moved extraction into passthrough_content helpers with unit tests; bumped to 0.35.3 and updated the CHANGELOG.