View queued message contents API

This commit is contained in:
mdecimus 2024-05-02 10:11:25 +01:00
parent c4a12e235d
commit 17d203c928
2 changed files with 47 additions and 2 deletions

View file

@ -23,6 +23,7 @@
use std::str::FromStr;
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use hyper::Method;
use jmap_proto::error::request::RequestError;
use mail_auth::{
@ -61,6 +62,7 @@ pub struct Message {
pub priority: i16,
#[serde(skip_serializing_if = "Option::is_none")]
pub env_id: Option<String>,
pub blob_hash: String,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
@ -559,6 +561,7 @@ impl From<&queue::Message> for Message {
expires: DateTime::from_timestamp(domain.expires as i64),
})
.collect(),
blob_hash: URL_SAFE_NO_PAD.encode::<&[u8]>(message.blob_hash.as_ref()),
}
}
}

View file

@ -21,19 +21,61 @@
* for more details.
*/
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use common::manager::webadmin::Resource;
use hyper::Method;
use jmap_proto::error::request::RequestError;
use serde_json::json;
use utils::url_params::UrlParams;
use crate::{
api::{http::ToHttpResponse, HttpRequest, HttpResponse, JsonResponse},
JMAP,
};
use super::decode_path_element;
impl JMAP {
pub async fn handle_manage_store(&self, req: &HttpRequest, path: Vec<&str>) -> HttpResponse {
match (path.get(1).copied(), req.method()) {
(Some("maintenance"), &Method::GET) => {
match (path.get(1).copied(), path.get(2).copied(), req.method()) {
(Some("blobs"), Some(blob_hash), &Method::GET) => {
match URL_SAFE_NO_PAD.decode(decode_path_element(blob_hash).as_bytes()) {
Ok(blob_hash) => {
match self
.core
.storage
.blob
.get_blob(&blob_hash, 0..usize::MAX)
.await
{
Ok(Some(contents)) => {
let params = UrlParams::new(req.uri().query());
let offset = params.parse("offset").unwrap_or(0);
let limit = params.parse("limit").unwrap_or(usize::MAX);
let contents = if offset == 0 && limit == usize::MAX {
contents
} else {
contents
.get(offset..std::cmp::min(offset + limit, contents.len()))
.unwrap_or_default()
.to_vec()
};
Resource {
content_type: "application/octet-stream",
contents,
}
.into_http_response()
}
Ok(None) => RequestError::not_found().into_http_response(),
Err(err) => err.into_http_response(),
}
}
Err(_) => RequestError::invalid_parameters().into_http_response(),
}
}
(Some("maintenance"), _, &Method::GET) => {
match self
.core
.storage