use anyhow::Result; use axum::{ body::Body, extract::{Path, State}, response::{IntoResponse, Response}, }; use http::{StatusCode, header}; use crate::http::{context::WebContext, errors::WebError}; /// GET /content/{cid} - Handle content requests. /// Gets content from content storage and returns it as a response. pub(crate) async fn handle_content( State(web_context): State, Path(cid): Path, ) -> Result { tracing::info!(?cid, "cid"); let exists = match web_context.content_storage.content_exists(&cid).await { Ok(exists) => exists, Err(_) => return Ok((StatusCode::INTERNAL_SERVER_ERROR).into_response()), }; tracing::info!(?exists, "exists"); if !exists { return Ok((StatusCode::NOT_FOUND).into_response()); } // Read the content data let content_data = match web_context.content_storage.read_content(&cid).await { Ok(data) => data, Err(_) => return Ok((StatusCode::INTERNAL_SERVER_ERROR).into_response()), }; // Detect content type from the original path extension let content_type = if cid.ends_with(".png") { "image/png" } else if cid.ends_with(".jpg") || cid.ends_with(".jpeg") { "image/jpeg" } else { "application/octet-stream" }; // Return the content with appropriate headers Ok(Response::builder() .status(StatusCode::OK) .header(header::CONTENT_TYPE, content_type) .header(header::CACHE_CONTROL, "public, max-age=86400") // Cache for 1 day .body(Body::from(content_data)) .unwrap() .into_response()) }