mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2024-09-20 07:16:18 +08:00
Store message headers in message metadata
This commit is contained in:
parent
875b1fa744
commit
62a4f70ac8
|
@ -222,11 +222,11 @@ impl<T: SessionStream> SessionData<T> {
|
|||
|
||||
for attribute in &arguments.attributes {
|
||||
match attribute {
|
||||
Attribute::Envelope
|
||||
| Attribute::Rfc822Header
|
||||
| Attribute::Body
|
||||
| Attribute::BodyStructure
|
||||
| Attribute::BinarySize { .. } => {
|
||||
Attribute::BodySection { sections, .. }
|
||||
if sections.first().map_or(false, |s| {
|
||||
matches!(s, Section::Header | Section::HeaderFields { .. })
|
||||
}) => {}
|
||||
Attribute::Body | Attribute::BodyStructure | Attribute::BinarySize { .. } => {
|
||||
/*
|
||||
Note that this did not result in \Seen being set, because
|
||||
RFC822.HEADER response data occurs as a result of a FETCH
|
||||
|
@ -319,7 +319,7 @@ impl<T: SessionStream> SessionData<T> {
|
|||
let raw_message = if needs_blobs {
|
||||
// Retrieve raw message if needed
|
||||
match self.jmap.get_blob(&email.blob_hash, 0..u32::MAX).await {
|
||||
Ok(Some(raw_message)) => raw_message.into(),
|
||||
Ok(Some(raw_message)) => raw_message,
|
||||
Ok(None) => {
|
||||
tracing::warn!(event = "not-found",
|
||||
account_id = account_id,
|
||||
|
@ -334,11 +334,9 @@ impl<T: SessionStream> SessionData<T> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
email.raw_headers
|
||||
};
|
||||
let message = email
|
||||
.contents
|
||||
.into_message(raw_message.as_deref().unwrap_or_default());
|
||||
let message = email.contents.into_message(&raw_message);
|
||||
|
||||
// Build response
|
||||
let mut items = Vec::with_capacity(arguments.attributes.len());
|
||||
|
@ -403,15 +401,13 @@ impl<T: SessionStream> SessionData<T> {
|
|||
}
|
||||
Attribute::Rfc822 => {
|
||||
items.push(DataItem::Rfc822 {
|
||||
contents: raw_message.as_ref().unwrap().into(),
|
||||
contents: raw_message.as_slice().into(),
|
||||
});
|
||||
}
|
||||
Attribute::Rfc822Header => {
|
||||
let message = message.root_part();
|
||||
if let Some(header) = raw_message
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(message.offset_header..message.offset_body)
|
||||
if let Some(header) =
|
||||
raw_message.get(message.offset_header..message.offset_body)
|
||||
{
|
||||
items.push(DataItem::Rfc822Header {
|
||||
contents: header.into(),
|
||||
|
@ -419,16 +415,9 @@ impl<T: SessionStream> SessionData<T> {
|
|||
}
|
||||
}
|
||||
Attribute::Rfc822Text => {
|
||||
let message = message.root_part();
|
||||
if let Some(text) = raw_message
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(message.offset_body..message.offset_end)
|
||||
{
|
||||
items.push(DataItem::Rfc822Text {
|
||||
contents: text.into(),
|
||||
});
|
||||
}
|
||||
items.push(DataItem::Rfc822Text {
|
||||
contents: raw_message.as_slice().into(),
|
||||
});
|
||||
}
|
||||
Attribute::Body => {
|
||||
items.push(DataItem::Body {
|
||||
|
|
|
@ -130,24 +130,17 @@ impl JMAP {
|
|||
};
|
||||
|
||||
// Check if we need to fetch the raw headers or body
|
||||
let mut needs_headers = false;
|
||||
let mut needs_body = false;
|
||||
for property in &properties {
|
||||
match property {
|
||||
Property::Header(_) | Property::Headers => {
|
||||
needs_headers = true;
|
||||
}
|
||||
if matches!(
|
||||
property,
|
||||
Property::BodyValues
|
||||
| Property::TextBody
|
||||
| Property::HtmlBody
|
||||
| Property::Attachments
|
||||
| Property::BodyStructure => {
|
||||
needs_body = true;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if needs_body {
|
||||
| Property::TextBody
|
||||
| Property::HtmlBody
|
||||
| Property::Attachments
|
||||
| Property::BodyStructure
|
||||
) {
|
||||
needs_body = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -175,14 +168,8 @@ impl JMAP {
|
|||
};
|
||||
|
||||
// Retrieve raw message if needed
|
||||
let raw_message = if needs_body || needs_headers {
|
||||
let offset = if !needs_body {
|
||||
metadata.contents.parts[0].offset_body as u32
|
||||
} else {
|
||||
u32::MAX
|
||||
};
|
||||
|
||||
if let Some(raw_message) = self.get_blob(&metadata.blob_hash, 0..offset).await? {
|
||||
let raw_message = if needs_body {
|
||||
if let Some(raw_message) = self.get_blob(&metadata.blob_hash, 0..u32::MAX).await? {
|
||||
raw_message
|
||||
} else {
|
||||
tracing::warn!(event = "not-found",
|
||||
|
@ -195,7 +182,7 @@ impl JMAP {
|
|||
continue;
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
metadata.raw_headers
|
||||
};
|
||||
let blob_id = BlobId {
|
||||
hash: metadata.blob_hash.clone(),
|
||||
|
|
|
@ -161,11 +161,18 @@ impl IndexMessage for BatchBuilder {
|
|||
);
|
||||
|
||||
// Store message metadata
|
||||
let root_part = message.root_part();
|
||||
self.value(
|
||||
Property::BodyStructure,
|
||||
Bincode::new(MessageMetadata {
|
||||
preview: preview.unwrap_or_default().into_owned(),
|
||||
size: message.raw_message.len(),
|
||||
raw_headers: message
|
||||
.raw_message
|
||||
.as_ref()
|
||||
.get(root_part.offset_header..root_part.offset_body)
|
||||
.unwrap_or_default()
|
||||
.to_vec(),
|
||||
contents: message.into(),
|
||||
received_at,
|
||||
has_attachments,
|
||||
|
|
|
@ -42,6 +42,7 @@ pub struct MessageMetadata<'x> {
|
|||
pub received_at: u64,
|
||||
pub preview: String,
|
||||
pub has_attachments: bool,
|
||||
pub raw_headers: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
|
Loading…
Reference in a new issue