use actix_files::NamedFile;
use actix_web::{web, HttpRequest, HttpResponse};
use atomic_lib::{urls, Resource, Storelike};
use crate::{appstate::AppState, errors::AtomicServerResult, helpers::get_client_agent};
#[tracing::instrument(skip(appstate, req))]
pub async fn handle_download(
path: Option<web::Path<String>>,
appstate: web::Data<AppState>,
req: actix_web::HttpRequest,
) -> AtomicServerResult<HttpResponse> {
let headers = req.headers();
let server_url = &appstate.config.server_url;
let store = &appstate.store;
let subject = if let Some(pth) = path {
let subject = format!("{}/{}", server_url, pth);
subject
} else {
return Err("Put `/download` in front of an File URL to download it.".into());
};
let for_agent = get_client_agent(headers, &appstate, subject.clone())?;
tracing::info!("handle_download: {}", subject);
let resource = store.get_resource_extended(&subject, false, &for_agent)?;
download_file_handler_partial(&resource, &req, &appstate)
}
pub fn download_file_handler_partial(
resource: &Resource,
req: &HttpRequest,
appstate: &AppState,
) -> AtomicServerResult<HttpResponse> {
let file_name = resource
.get(urls::INTERNAL_ID)
.map_err(|e| format!("Internal ID of file could not be resolved. {}", e))?;
let mut file_path = appstate.config.uploads_path.clone();
file_path.push(file_name.to_string());
let file = NamedFile::open(file_path)?;
Ok(file.into_response(req))
}