Store message headers in message metadata

This commit is contained in:
mdecimus 2024-03-02 16:45:41 +01:00
parent 875b1fa744
commit 62a4f70ac8
4 changed files with 33 additions and 49 deletions

View file

@ -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 {

View file

@ -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(),

View file

@ -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,

View file

@ -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)]