From 7ace2b99e93c48244ce0d041af4347f6662f6e9c Mon Sep 17 00:00:00 2001 From: Philipp Korber Date: Mon, 7 Jan 2019 11:50:44 +0100 Subject: fix(core) auto add `Content-Id` headers --- core/src/mail.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'core') diff --git a/core/src/mail.rs b/core/src/mail.rs index 4c2e130..0ceeba8 100644 --- a/core/src/mail.rs +++ b/core/src/mail.rs @@ -28,7 +28,8 @@ use headers::{ ContentType, _From, ContentTransferEncoding, Date, MessageId, - ContentDisposition + ContentDisposition, + ContentId }, header_components::{ DateTime, @@ -529,9 +530,7 @@ fn top_level_validation(mail: &Mail) -> Result<(), HeaderValidationError> { } } -/// inserts ContentType and ContentTransferEncoding into -/// the headers of any contained `MailBody::SingleBody`, -/// based on the `Resource` representing the body +/// insert auto-generated headers like `Date`, `Message-Id` and `Content-Id` fn auto_gen_headers( mail: &mut Mail, encoded_resources: Vec, @@ -557,6 +556,9 @@ fn auto_gen_headers( let mut boundary_count = 0; recursive_auto_gen_headers(mail, &mut boundary_count, ctx); + + // Make sure no **top-level** body has a content-id field, as it already has a Message-Id + mail.headers_mut().remove(ContentId); } /// returns the `EncData` from a resource @@ -571,15 +573,28 @@ pub(crate) fn assume_encoded(resource: &Resource) -> &EncData { } } +/// Auto-generates some headers for any body including non top-level mail bodies. +/// +/// For mails which are not multipart mails this does: +/// - set metadata for the `Content-Disposition` header (e.g. `file-name`, `read-date`, ...) +/// - insert a `Content-Id` header +/// - this overwrites any already contained content-id header +/// +/// For multipart mails this does: +/// - create/overwrite the boundary for the `Content-Type` header +/// - call this method for all bodies in the multipart body fn recursive_auto_gen_headers(mail: &mut Mail, boundary_count: &mut usize, ctx: &C) { let &mut Mail { ref mut headers, ref mut body } = mail; match body { &mut MailBody::SingleBody { ref mut body } => { + let data = assume_encoded(body); + if let Some(Ok(disposition)) = headers.get_single_mut(ContentDisposition) { let current_file_meta_mut = disposition.file_meta_mut(); - let data = assume_encoded(body); current_file_meta_mut.replace_empty_fields_with(data.file_meta()) } + + headers.insert(ContentId::body(data.content_id().clone())); }, &mut MailBody::MultipleBodies { ref mut bodies, .. } => { let mut headers: &mut HeaderMap = headers; -- cgit v1.2.3