From 13aae44163a15bfcbf02c2d2be4865b8cc0a47dc Mon Sep 17 00:00:00 2001 From: Sebastian Hugentobler Date: Sat, 11 May 2024 09:06:08 +0200 Subject: [PATCH] stream covers (chunked encoding) --- little-hesinde/src/handlers/cover.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/little-hesinde/src/handlers/cover.rs b/little-hesinde/src/handlers/cover.rs index 4a0696d..d0d278f 100644 --- a/little-hesinde/src/handlers/cover.rs +++ b/little-hesinde/src/handlers/cover.rs @@ -1,31 +1,32 @@ //! Handle requests for cover images. -use std::{fs::File, io::Read, sync::Arc}; +use std::sync::Arc; use poem::{ error::NotFoundError, handler, - web::{headers::ContentType, Data, Path, WithContentType}, - IntoResponse, + web::{headers::ContentType, Data, Path}, + Body, IntoResponse, Response, }; +use tokio::fs::File; +use tokio_util::io::ReaderStream; use crate::{app_state::AppState, handlers::error::HandlerError}; /// Handle a request for the cover image of book with id `id`. #[handler] -pub async fn handler( - id: Path, - state: Data<&Arc>, -) -> Result>, poem::Error> { +pub async fn handler(id: Path, state: Data<&Arc>) -> Result { let book = state .calibre .scalar_book(*id) .map_err(HandlerError::DataError)?; let cover_path = state.config.library_path.join(book.path).join("cover.jpg"); - let mut cover = File::open(cover_path).map_err(|_| NotFoundError)?; + let mut cover = File::open(cover_path).await.map_err(|_| NotFoundError)?; + let stream = ReaderStream::new(cover); + let body = Body::from_bytes_stream(stream); - let mut data = Vec::new(); - cover.read_to_end(&mut data).map_err(|_| NotFoundError)?; - - Ok(data.with_content_type(ContentType::jpeg().to_string())) + Ok(body + .with_content_type(ContentType::jpeg().to_string()) + .with_header("Content-Disposition", "filename=\"cover.jpg\"") + .into_response()) }