server: add functioning download attachment handler

This commit is contained in:
2024-03-26 08:25:52 -07:00
parent ff1c3f5791
commit 9a5dc20f83
2 changed files with 28 additions and 47 deletions

View File

@@ -91,23 +91,24 @@ impl<'r, 'o: 'r> Responder<'r, 'o> for InlineAttachmentResponder {
}
}
struct DownloadPartResponder {
bytes: Vec<u8>,
filename: Option<String>,
}
struct DownloadAttachmentResponder(Attachment);
impl<'r, 'o: 'r> Responder<'r, 'o> for DownloadPartResponder {
impl<'r, 'o: 'r> Responder<'r, 'o> for DownloadAttachmentResponder {
fn respond_to(self, _: &'r Request<'_>) -> rocket::response::Result<'o> {
let mut resp = Response::build();
if let Some(filename) = self.filename {
if let Some(filename) = self.0.filename {
info!("filename {:?}", filename);
resp.header(Header::new(
"Content-Disposition",
format!(r#"attachment; filename="{}""#, filename),
))
.header(ContentType::Binary);
));
}
resp.sized_body(self.bytes.len(), Cursor::new(self.bytes))
if let Some(content_type) = self.0.content_type {
if let Some(ct) = ContentType::parse_flexible(&content_type) {
resp.header(ct);
}
}
resp.sized_body(self.0.bytes.len(), Cursor::new(self.0.bytes))
.ok()
}
}
@@ -129,7 +130,6 @@ async fn view_attachment(
.map(|s| s.parse().expect("not a usize"))
.collect();
let attachment = attachment_bytes(nm, &mid, &idx)?;
// TODO: plumb Content-Type, or just create wrappers for serving the Attachment type
Ok(InlineAttachmentResponder(attachment))
}
@@ -138,7 +138,7 @@ async fn download_attachment(
nm: &State<Notmuch>,
id: &str,
idx: &str,
) -> Result<DownloadPartResponder, Debug<ServerError>> {
) -> Result<DownloadAttachmentResponder, Debug<ServerError>> {
let mid = if id.starts_with("id:") {
id.to_string()
} else {
@@ -150,30 +150,7 @@ async fn download_attachment(
.map(|s| s.parse().expect("not a usize"))
.collect();
let attachment = attachment_bytes(nm, &mid, &idx)?;
// TODO(wathiede): use walk_attachments from graphql to fill this out
Ok(DownloadPartResponder {
bytes: attachment.bytes,
filename: attachment.filename,
})
}
#[get("/original/<id>/part/<part>")]
async fn original_part(
nm: &State<Notmuch>,
id: &str,
part: usize,
) -> Result<DownloadPartResponder, Debug<NotmuchError>> {
let mid = if id.starts_with("id:") {
id.to_string()
} else {
format!("id:{}", id)
};
let meta = nm.show_part(&mid, part)?;
let res = nm.show_original_part(&mid, part)?;
Ok(DownloadPartResponder {
bytes: res,
filename: meta.filename,
})
Ok(DownloadAttachmentResponder(attachment))
}
#[get("/original/<id>")]
@@ -240,7 +217,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
.mount(
"/",
routes![
original_part,
original,
refresh,
search_all,