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