server: set filename when downloading attachment.

This commit is contained in:
Bill Thiede 2021-11-09 20:39:09 -08:00
parent b57e4d9df2
commit 56df23065c

View File

@ -1,16 +1,18 @@
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
use std::{error::Error, process::Command, str::FromStr}; use std::{error::Error, io::Cursor, str::FromStr};
use rocket::{ use rocket::{
response::{content::Plain, Debug}, http::{ContentType, Header},
request::Request,
response::{content::Plain, Debug, Responder},
serde::json::Json, serde::json::Json,
State, Response, State,
}; };
use rocket_cors::{AllowedHeaders, AllowedOrigins}; use rocket_cors::{AllowedHeaders, AllowedOrigins};
use notmuch::{MessageId, Notmuch, NotmuchError, SearchSummary, ThreadSet}; use notmuch::{Notmuch, NotmuchError, SearchSummary, ThreadSet};
#[get("/")] #[get("/")]
fn hello() -> &'static str { fn hello() -> &'static str {
@ -32,19 +34,44 @@ async fn show(nm: &State<Notmuch>, query: &str) -> Result<Json<ThreadSet>, Debug
Ok(Json(res)) Ok(Json(res))
} }
struct PartResponder {
bytes: Vec<u8>,
filename: Option<String>,
}
impl<'r, 'o: 'r> Responder<'r, 'o> for PartResponder {
fn respond_to(self, _: &'r Request<'_>) -> rocket::response::Result<'o> {
let mut resp = Response::build();
if let Some(filename) = self.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))
.ok()
}
}
#[get("/original/<id>/part/<part>")] #[get("/original/<id>/part/<part>")]
async fn original_part( async fn original_part(
nm: &State<Notmuch>, nm: &State<Notmuch>,
id: &str, id: &str,
part: usize, part: usize,
) -> Result<Vec<u8>, Debug<NotmuchError>> { ) -> Result<PartResponder, Debug<NotmuchError>> {
let mid = if id.starts_with("id:") { let mid = if id.starts_with("id:") {
id.to_string() id.to_string()
} else { } else {
format!("id:{}", id) format!("id:{}", id)
}; };
let meta = nm.show_part(&mid, part)?;
let res = nm.show_original_part(&mid, part)?; let res = nm.show_original_part(&mid, part)?;
Ok(res) Ok(PartResponder {
bytes: res,
filename: meta.filename,
})
} }
#[get("/original/<id>")] #[get("/original/<id>")]