diff options
Diffstat (limited to 'crates/jmap')
-rw-r--r-- | crates/jmap/src/blob/download.rs | 3 | ||||
-rw-r--r-- | crates/jmap/src/blob/upload.rs | 3 | ||||
-rw-r--r-- | crates/jmap/src/email/copy.rs | 4 | ||||
-rw-r--r-- | crates/jmap/src/email/get.rs | 4 | ||||
-rw-r--r-- | crates/jmap/src/email/index.rs | 7 | ||||
-rw-r--r-- | crates/jmap/src/email/metadata.rs | 2 | ||||
-rw-r--r-- | crates/jmap/src/email/set.rs | 7 | ||||
-rw-r--r-- | crates/jmap/src/email/snippet.rs | 4 | ||||
-rw-r--r-- | crates/jmap/src/lib.rs | 58 | ||||
-rw-r--r-- | crates/jmap/src/services/index.rs | 4 | ||||
-rw-r--r-- | crates/jmap/src/services/ingest.rs | 10 | ||||
-rw-r--r-- | crates/jmap/src/sieve/get.rs | 4 | ||||
-rw-r--r-- | crates/jmap/src/sieve/ingest.rs | 4 | ||||
-rw-r--r-- | crates/jmap/src/submission/get.rs | 38 | ||||
-rw-r--r-- | crates/jmap/src/submission/set.rs | 33 |
15 files changed, 51 insertions, 134 deletions
diff --git a/crates/jmap/src/blob/download.rs b/crates/jmap/src/blob/download.rs index 14ae820d..a01e3f2e 100644 --- a/crates/jmap/src/blob/download.rs +++ b/crates/jmap/src/blob/download.rs @@ -35,7 +35,8 @@ use mail_parser::{ decoders::{base64::base64_decode, quoted_printable::quoted_printable_decode}, Encoding, }; -use store::{BlobClass, BlobHash}; +use store::BlobClass; +use utils::BlobHash; use crate::{auth::AccessToken, JMAP}; diff --git a/crates/jmap/src/blob/upload.rs b/crates/jmap/src/blob/upload.rs index 086e5d9f..8bf493bf 100644 --- a/crates/jmap/src/blob/upload.rs +++ b/crates/jmap/src/blob/upload.rs @@ -33,8 +33,9 @@ use jmap_proto::{ }; use store::{ write::{now, BatchBuilder, BlobOp}, - BlobClass, BlobHash, Serialize, + BlobClass, Serialize, }; +use utils::BlobHash; use crate::{auth::AccessToken, JMAP}; diff --git a/crates/jmap/src/email/copy.rs b/crates/jmap/src/email/copy.rs index 36845853..7c4cb5a6 100644 --- a/crates/jmap/src/email/copy.rs +++ b/crates/jmap/src/email/copy.rs @@ -48,12 +48,12 @@ use jmap_proto::{ }; use mail_parser::{parsers::fields::thread::thread_name, HeaderName, HeaderValue}; use store::{ - write::{BatchBuilder, ValueClass, F_BITMAP, F_VALUE}, + write::{BatchBuilder, Bincode, ValueClass, F_BITMAP, F_VALUE}, BlobClass, }; use utils::map::vec_map::VecMap; -use crate::{auth::AccessToken, mailbox::UidMailbox, services::housekeeper::Event, Bincode, JMAP}; +use crate::{auth::AccessToken, mailbox::UidMailbox, services::housekeeper::Event, JMAP}; use super::{ index::{EmailIndexBuilder, TrimTextValue, VisitValues, MAX_ID_LENGTH, MAX_SORT_FIELD_LENGTH}, diff --git a/crates/jmap/src/email/get.rs b/crates/jmap/src/email/get.rs index fe05fe05..c3e64202 100644 --- a/crates/jmap/src/email/get.rs +++ b/crates/jmap/src/email/get.rs @@ -37,9 +37,9 @@ use jmap_proto::{ }, }; use mail_parser::HeaderName; -use store::BlobClass; +use store::{write::Bincode, BlobClass}; -use crate::{auth::AccessToken, email::headers::HeaderToValue, mailbox::UidMailbox, Bincode, JMAP}; +use crate::{auth::AccessToken, email::headers::HeaderToValue, mailbox::UidMailbox, JMAP}; use super::{ body::{ToBodyPart, TruncateBody}, diff --git a/crates/jmap/src/email/index.rs b/crates/jmap/src/email/index.rs index ee28e9b4..33769c6f 100644 --- a/crates/jmap/src/email/index.rs +++ b/crates/jmap/src/email/index.rs @@ -35,12 +35,13 @@ use store::{ backend::MAX_TOKEN_LENGTH, fts::{index::FtsDocument, Field}, write::{ - BatchBuilder, BlobOp, DirectoryClass, IntoOperations, F_BITMAP, F_CLEAR, F_INDEX, F_VALUE, + BatchBuilder, Bincode, BlobOp, DirectoryClass, IntoOperations, F_BITMAP, F_CLEAR, F_INDEX, + F_VALUE, }, - BlobHash, }; +use utils::BlobHash; -use crate::{mailbox::UidMailbox, Bincode}; +use crate::mailbox::UidMailbox; use super::metadata::MessageMetadata; diff --git a/crates/jmap/src/email/metadata.rs b/crates/jmap/src/email/metadata.rs index e51eec1e..677b34cc 100644 --- a/crates/jmap/src/email/metadata.rs +++ b/crates/jmap/src/email/metadata.rs @@ -32,7 +32,7 @@ use mail_parser::{ MessagePartId, MimeHeaders, PartType, }; use serde::{Deserialize, Serialize}; -use store::BlobHash; +use utils::BlobHash; #[derive(Debug, Serialize, Deserialize)] pub struct MessageMetadata<'x> { diff --git a/crates/jmap/src/email/set.rs b/crates/jmap/src/email/set.rs index 202e7316..779243e8 100644 --- a/crates/jmap/src/email/set.rs +++ b/crates/jmap/src/email/set.rs @@ -53,15 +53,14 @@ use mail_parser::MessageParser; use store::{ ahash::AHashSet, write::{ - assert::HashedValue, log::ChangeLogBuilder, BatchBuilder, DeserializeFrom, SerializeInto, - ToBitmaps, ValueClass, F_BITMAP, F_CLEAR, F_VALUE, + assert::HashedValue, log::ChangeLogBuilder, BatchBuilder, Bincode, DeserializeFrom, + SerializeInto, ToBitmaps, ValueClass, F_BITMAP, F_CLEAR, F_VALUE, }, Serialize, }; use crate::{ - auth::AccessToken, mailbox::UidMailbox, services::housekeeper::Event, Bincode, IngestError, - JMAP, + auth::AccessToken, mailbox::UidMailbox, services::housekeeper::Event, IngestError, JMAP, }; use super::{ diff --git a/crates/jmap/src/email/snippet.rs b/crates/jmap/src/email/snippet.rs index 0e5b4ede..4f55dca1 100644 --- a/crates/jmap/src/email/snippet.rs +++ b/crates/jmap/src/email/snippet.rs @@ -31,9 +31,9 @@ use jmap_proto::{ }; use mail_parser::{decoders::html::html_to_text, GetHeader, HeaderName, PartType}; use nlp::language::{search_snippet::generate_snippet, stemmer::Stemmer, Language}; -use store::backend::MAX_TOKEN_LENGTH; +use store::{backend::MAX_TOKEN_LENGTH, write::Bincode}; -use crate::{auth::AccessToken, Bincode, JMAP}; +use crate::{auth::AccessToken, JMAP}; use super::metadata::{MessageMetadata, MetadataPartType}; diff --git a/crates/jmap/src/lib.rs b/crates/jmap/src/lib.rs index 79ce7b89..8ee26c50 100644 --- a/crates/jmap/src/lib.rs +++ b/crates/jmap/src/lib.rs @@ -54,8 +54,8 @@ use store::{ fts::FtsFilter, query::{sort::Pagination, Comparator, Filter, ResultSet, SortedResultSet}, roaring::RoaringBitmap, - write::{BatchBuilder, BitmapClass, DirectoryClass, TagValue, ToBitmaps, ValueClass}, - BitmapKey, BlobStore, Deserialize, FtsStore, Serialize, Store, Stores, ValueKey, + write::{BatchBuilder, BitmapClass, DirectoryClass, TagValue, ValueClass}, + BitmapKey, BlobStore, Deserialize, FtsStore, Store, Stores, ValueKey, }; use tokio::sync::mpsc; use utils::{ @@ -171,10 +171,6 @@ pub struct Config { pub capabilities: BaseCapabilities, } -pub struct Bincode<T: serde::Serialize + serde::de::DeserializeOwned> { - pub inner: T, -} - #[derive(Debug)] pub enum IngestError { Temporary, @@ -759,56 +755,6 @@ impl JMAP { } } -impl<T: serde::Serialize + serde::de::DeserializeOwned> Bincode<T> { - pub fn new(inner: T) -> Self { - Self { inner } - } -} - -impl<T: serde::Serialize + serde::de::DeserializeOwned> Serialize for &Bincode<T> { - fn serialize(self) -> Vec<u8> { - lz4_flex::compress_prepend_size(&bincode::serialize(&self.inner).unwrap_or_default()) - } -} - -impl<T: serde::Serialize + serde::de::DeserializeOwned> Serialize for Bincode<T> { - fn serialize(self) -> Vec<u8> { - lz4_flex::compress_prepend_size(&bincode::serialize(&self.inner).unwrap_or_default()) - } -} - -impl<T: serde::Serialize + serde::de::DeserializeOwned + Sized + Sync + Send> Deserialize - for Bincode<T> -{ - fn deserialize(bytes: &[u8]) -> store::Result<Self> { - lz4_flex::decompress_size_prepended(bytes) - .map_err(|err| { - store::Error::InternalError(format!("Bincode decompression failed: {err:?}")) - }) - .and_then(|result| { - bincode::deserialize(&result).map_err(|err| { - store::Error::InternalError(format!( - "Bincode deserialization failed (len {}): {err:?}", - result.len() - )) - }) - }) - .map(|inner| Self { inner }) - } -} - -impl<T: serde::Serialize + serde::de::DeserializeOwned> ToBitmaps for Bincode<T> { - fn to_bitmaps(&self, _ops: &mut Vec<store::write::Operation>, _field: u8, _set: bool) { - unreachable!() - } -} - -impl<T: serde::Serialize + serde::de::DeserializeOwned> ToBitmaps for &Bincode<T> { - fn to_bitmaps(&self, _ops: &mut Vec<store::write::Operation>, _field: u8, _set: bool) { - unreachable!() - } -} - trait UpdateResults: Sized { fn update_results(&mut self, sorted_results: SortedResultSet) -> Result<(), MethodError>; } diff --git a/crates/jmap/src/services/index.rs b/crates/jmap/src/services/index.rs index 51bbd9d2..1192055f 100644 --- a/crates/jmap/src/services/index.rs +++ b/crates/jmap/src/services/index.rs @@ -24,13 +24,13 @@ use jmap_proto::types::{collection::Collection, property::Property}; use store::{ fts::index::FtsDocument, - write::{key::DeserializeBigEndian, BatchBuilder, ValueClass}, + write::{key::DeserializeBigEndian, BatchBuilder, Bincode, ValueClass}, Deserialize, IterateParams, ValueKey, U32_LEN, U64_LEN, }; use crate::{ email::{index::IndexMessageText, metadata::MessageMetadata}, - Bincode, JMAP, + JMAP, }; use super::housekeeper::Event; diff --git a/crates/jmap/src/services/ingest.rs b/crates/jmap/src/services/ingest.rs index 6e2aa61f..cf2e56ed 100644 --- a/crates/jmap/src/services/ingest.rs +++ b/crates/jmap/src/services/ingest.rs @@ -32,9 +32,13 @@ use crate::{email::ingest::IngestEmail, mailbox::INBOX_ID, IngestError, JMAP}; impl JMAP { pub async fn deliver_message(&self, message: IngestMessage) -> Vec<DeliveryResult> { // Read message - let raw_message = match message.read_message().await { - Ok(raw_message) => raw_message, - Err(_) => { + let raw_message = match self + .blob_store + .get_blob(message.message_blob.as_slice(), 0..u32::MAX) + .await + { + Ok(Some(raw_message)) => raw_message, + _ => { return (0..message.recipients.len()) .map(|_| DeliveryResult::TemporaryFailure { reason: "Temporary I/O error.".into(), diff --git a/crates/jmap/src/sieve/get.rs b/crates/jmap/src/sieve/get.rs index c6cc7466..4b4d05f0 100644 --- a/crates/jmap/src/sieve/get.rs +++ b/crates/jmap/src/sieve/get.rs @@ -32,11 +32,11 @@ use jmap_proto::{ use sieve::Sieve; use store::{ query::Filter, - write::{assert::HashedValue, BatchBuilder, BlobOp}, + write::{assert::HashedValue, BatchBuilder, Bincode, BlobOp}, Deserialize, Serialize, }; -use crate::{sieve::SeenIds, Bincode, JMAP}; +use crate::{sieve::SeenIds, JMAP}; use super::ActiveScript; diff --git a/crates/jmap/src/sieve/ingest.rs b/crates/jmap/src/sieve/ingest.rs index 03b84178..9f87ff36 100644 --- a/crates/jmap/src/sieve/ingest.rs +++ b/crates/jmap/src/sieve/ingest.rs @@ -30,7 +30,7 @@ use sieve::{Envelope, Event, Input, Mailbox, Recipient}; use smtp::core::{Session, SessionAddress}; use store::{ ahash::AHashSet, - write::{now, BatchBuilder, F_VALUE}, + write::{now, BatchBuilder, Bincode, F_VALUE}, }; use utils::listener::stream::NullIo; @@ -38,7 +38,7 @@ use crate::{ email::ingest::{IngestEmail, IngestedEmail}, mailbox::{INBOX_ID, TRASH_ID}, sieve::SeenIdHash, - Bincode, IngestError, JMAP, + IngestError, JMAP, }; use super::ActiveScript; diff --git a/crates/jmap/src/submission/get.rs b/crates/jmap/src/submission/get.rs index 5cca5b29..b8b9e384 100644 --- a/crates/jmap/src/submission/get.rs +++ b/crates/jmap/src/submission/get.rs @@ -27,8 +27,7 @@ use jmap_proto::{ object::Object, types::{collection::Collection, property::Property, value::Value}, }; -use smtp::{core::management::QueueRequest, queue}; -use tokio::sync::oneshot; +use smtp::queue; use crate::JMAP; @@ -97,25 +96,10 @@ impl JMAP { }; // Obtain queueId - let mut queued_message = None; - let (result_tx, result_rx) = oneshot::channel(); - if self + let queued_message = self .smtp - .queue - .tx - .send(queue::Event::Manage(QueueRequest::Status { - queue_ids: vec![push.get(&Property::MessageId).as_uint().unwrap_or(u64::MAX)], - result_tx, - })) - .await - .is_ok() - { - queued_message = result_rx - .await - .ok() - .and_then(|mut result| result.pop()) - .flatten(); - } + .read_message(push.get(&Property::MessageId).as_uint().unwrap_or(u64::MAX)) + .await; let mut result = Object::with_capacity(properties.len()); for property in &properties { @@ -124,11 +108,7 @@ impl JMAP { Property::DeliveryStatus => { match (queued_message.as_ref(), push.remove(property)) { (Some(message), Value::Object(mut status)) => { - for rcpt in message - .domains - .iter() - .flat_map(|rcpts| rcpts.recipients.iter()) - { + for rcpt in &message.recipients { status.set( Property::_T(rcpt.address.clone()), Object::with_capacity(3) @@ -146,10 +126,12 @@ impl JMAP { .with_property( Property::SmtpReply, match &rcpt.status { - queue::Status::Completed(reply) - | queue::Status::TemporaryFailure(reply) + queue::Status::Completed(reply) => { + reply.response.message() + } + queue::Status::TemporaryFailure(reply) | queue::Status::PermanentFailure(reply) => { - reply.as_str() + reply.response.message() } queue::Status::Scheduled => "250 2.1.5 Queued", } diff --git a/crates/jmap/src/submission/set.rs b/crates/jmap/src/submission/set.rs index 1a27b51d..cf4998f0 100644 --- a/crates/jmap/src/submission/set.rs +++ b/crates/jmap/src/submission/set.rs @@ -48,19 +48,15 @@ use jmap_proto::{ }, }; use mail_parser::{HeaderName, HeaderValue}; -use smtp::{ - core::{management::QueueRequest, Session, SessionData, State}, - queue, -}; +use smtp::core::{Session, SessionData, State}; use smtp_proto::{request::parser::Rfc5321Parser, MailFrom, RcptTo}; -use store::write::{assert::HashedValue, log::ChangeLogBuilder, now, BatchBuilder}; -use tokio::sync::oneshot; +use store::write::{assert::HashedValue, log::ChangeLogBuilder, now, BatchBuilder, Bincode}; use utils::{ listener::{stream::NullIo, ServerInstance}, map::vec_map::VecMap, }; -use crate::{email::metadata::MessageMetadata, identity::set::sanitize_email, Bincode, JMAP}; +use crate::{email::metadata::MessageMetadata, identity::set::sanitize_email, JMAP}; pub static SCHEMA: &[IndexProperty] = &[ IndexProperty::new(Property::UndoStatus).index_as(IndexAs::Text { @@ -176,24 +172,11 @@ impl JMAP { match undo_status { Some(undo_status) if undo_status == "canceled" => { - let (result_tx, result_rx) = oneshot::channel(); - if self - .smtp - .queue - .tx - .send(queue::Event::Manage(QueueRequest::Cancel { - queue_ids: vec![queue_id], - item: None, - result_tx, - })) - .await - .is_ok() - && result_rx - .await - .ok() - .and_then(|mut r| r.pop()) - .unwrap_or(false) - { + if let Some(queue_message) = self.smtp.read_message(queue_id).await { + // Delete message from queue + let message_due = queue_message.next_event().unwrap_or_default(); + queue_message.remove(&self.smtp, message_due).await; + // Update record let mut batch = BatchBuilder::new(); batch |