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