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 ++++++++++++++++++++----- internals/src/lib.rs | 1 - template/src/lib.rs | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) 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; diff --git a/internals/src/lib.rs b/internals/src/lib.rs index 753f090..9026b46 100644 --- a/internals/src/lib.rs +++ b/internals/src/lib.rs @@ -1,6 +1,5 @@ //! Provides some internal functionality for the `mail` crate. #![recursion_limit="256"] -#[macro_use] extern crate failure; #[macro_use] extern crate nom; diff --git a/template/src/lib.rs b/template/src/lib.rs index 26e70cb..7a96b06 100644 --- a/template/src/lib.rs +++ b/template/src/lib.rs @@ -24,7 +24,7 @@ use serde::{ Serialize, Deserialize }; -use failure::{Fail, Error}; +use failure::Error; use futures::{ Future, Poll, Async, try_ready, -- cgit v1.2.3