From 1e0273b823b00ef69c28d4c5b3a98a3c3ee0ca34 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Tue, 11 Mar 2025 22:18:28 -0500 Subject: [PATCH] receipts: Set Cache-Control header on photos Some of the receipt photos can be quite large. Since there's no (direct) way to change receipt photos, we can tell the browser to cache them for a long time to avoid having to download them every time the list page is shown. --- src/routes/receipts.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/routes/receipts.rs b/src/routes/receipts.rs index 3350013..000564d 100644 --- a/src/routes/receipts.rs +++ b/src/routes/receipts.rs @@ -1,5 +1,5 @@ use rocket::form::Form; -use rocket::http::{ContentType, MediaType, Status}; +use rocket::http::{ContentType, Header, MediaType, Status}; use rocket::serde::json::Json; use rocket::{Route, State}; use rocket_db_pools::Connection as DatabaseConnection; @@ -118,11 +118,25 @@ pub async fn get_receipt( } } +#[derive(rocket::response::Responder)] +pub struct PhotoResponse { + content: Vec, + content_type: ContentType, + cache_control: Header<'static>, +} + +impl PhotoResponse { + fn new(content: Vec, content_type: ContentType) -> Self { + let cache_control = Header::new("Cache-Control", "max-age=604800"); + Self { content, content_type, cache_control } + } +} + #[rocket::get("//view/<_>")] pub async fn view_receipt_photo( id: i32, db: DatabaseConnection, -) -> Option<(ContentType, Vec)> { +) -> Option { let mut repo = ReceiptsRepository::new(db); match repo.get_receipt_photo(id).await { Ok((filename, image)) => { @@ -130,7 +144,7 @@ pub async fn view_receipt_photo( .rsplit_once('.') .and_then(|(_, ext)| MediaType::from_extension(ext)) .unwrap_or(MediaType::Binary); - Some((ContentType(mt), image)) + Some(PhotoResponse::new(image, ContentType(mt))) }, Err(e) => { error!("Error fetching receipt image: {}", e);