use database::{DB}; use http::{Response, header::CONTENT_TYPE, response::Builder as ResponseBuilder}; use log::{debug, warn}; use tauri::UriSchemeResponder; use crate::{error::CacheError, utils::DROP_CLIENT_ASYNC}; use super::{ auth::generate_authorization_header, cache::{ObjectCache, cache_object, get_cached_object}, }; pub async fn fetch_object_wrapper(request: http::Request>, responder: UriSchemeResponder) { match fetch_object(request).await { Ok(r) => responder.respond(r), Err(e) => { warn!("Cache error: {e}"); responder.respond( Response::builder() .status(500) .body(Vec::new()) .expect("Failed to build error response"), ); } }; } pub async fn fetch_object( request: http::Request>, ) -> Result>, CacheError> { // Drop leading / let object_id = &request.uri().path()[1..]; let cache_result = get_cached_object::(object_id); if let Ok(cache_result) = &cache_result && !cache_result.has_expired() { return cache_result.try_into(); } let header = generate_authorization_header(); let client = DROP_CLIENT_ASYNC.clone(); let url = format!("{}api/v1/client/object/{object_id}", DB.fetch_base_url()); let response = client.get(url).header("Authorization", header).send().await; match response { Ok(r) => { let resp_builder = ResponseBuilder::new().header( CONTENT_TYPE, r.headers() .get("Content-Type") .expect("Failed get Content-Type header"), ); let data = match r.bytes().await { Ok(data) => Vec::from(data), Err(e) => { warn!("Could not get data from cache object {object_id} with error {e}",); Vec::new() } }; let resp = resp_builder .body(data) .expect("Failed to build object cache response body"); if cache_result.map_or(true, |x| x.has_expired()) { cache_object::(object_id, &resp.clone().try_into()?) .expect("Failed to create cached object"); } Ok(resp) } Err(e) => { debug!("Object fetch failed with error {e}. Attempting to download from cache"); match cache_result { Ok(cache_result) => cache_result.try_into(), Err(e) => { warn!("{e}"); Err(CacheError::Remote(e)) } } } } }