Skip to content

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

Merged
AntoniosBarotsis merged 4 commits into
resend:mainfrom
pcbeingused333:fix/forward-passthrough-content-id
Nov 13, 2026
Merged

AntoniosBarotsis merged 4 commits into
resend:mainfrom
pcbeingused333:fix/forward-passthrough-content-id

Conversation

@pcbeingused333

@pcbeingused333 pcbeingused333 commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

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.

Written for commit 8cbc065. Summary will update on new commits.

View guided diff

pcbeingused333 and others added 4 commits November 13, 2026 02:47
… passthrough

The passthrough path read the Content-ID header name (get_key) instead of its
value, so every inline attachment was re-sent with content_id="Content-ID" and
cid: references in the HTML broke. Extract the attachment mapping into a
helper, read the value and strip the angle brackets.
@AntoniosBarotsis

Copy link
Copy Markdown
Collaborator

Thanks! Found a few more edge cases compared to the node implementation so updated those as well, releasing 0.35.3 in a few minutes!

@AntoniosBarotsis
AntoniosBarotsis merged commit fef8b9c into resend:main Nov 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants