mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-15 01:01:25 +10:00
feat(cache): Caching objects which use the useObject tauri command
This commit is contained in:
@ -41,10 +41,12 @@ use log4rs::Config;
|
|||||||
use process::commands::{kill_game, launch_game};
|
use process::commands::{kill_game, launch_game};
|
||||||
use process::process_manager::ProcessManager;
|
use process::process_manager::ProcessManager;
|
||||||
use remote::auth::{self, generate_authorization_header, recieve_handshake};
|
use remote::auth::{self, generate_authorization_header, recieve_handshake};
|
||||||
|
use remote::cache::{cache_object, fetch_object, fetch_object_offline, get_cached_object, ObjectCache};
|
||||||
use remote::commands::{
|
use remote::commands::{
|
||||||
auth_initiate, fetch_drop_object, gen_drop_url, manual_recieve_handshake, retry_connect, sign_out, use_remote
|
auth_initiate, fetch_drop_object, gen_drop_url, manual_recieve_handshake, retry_connect, sign_out, use_remote
|
||||||
};
|
};
|
||||||
use remote::requests::make_request;
|
use remote::requests::make_request;
|
||||||
|
use reqwest::blocking::Body;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -358,35 +360,9 @@ pub fn run() {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.register_asynchronous_uri_scheme_protocol("object", move |_ctx, request, responder| {
|
.register_asynchronous_uri_scheme_protocol("object", move |ctx, request, responder| {
|
||||||
// Drop leading /
|
let state: tauri::State<'_, Mutex<AppState>> = ctx.app_handle().state();
|
||||||
let object_id = &request.uri().path()[1..];
|
offline!(state, fetch_object, fetch_object_offline, request, responder);
|
||||||
|
|
||||||
let header = generate_authorization_header();
|
|
||||||
let client: reqwest::blocking::Client = reqwest::blocking::Client::new();
|
|
||||||
let response = make_request(&client, &["/api/v1/client/object/", object_id], &[], |f| {
|
|
||||||
f.header("Authorization", header)
|
|
||||||
})
|
|
||||||
.unwrap()
|
|
||||||
.send();
|
|
||||||
if response.is_err() {
|
|
||||||
warn!(
|
|
||||||
"failed to fetch object with error: {}",
|
|
||||||
response.err().unwrap()
|
|
||||||
);
|
|
||||||
responder.respond(Response::builder().status(500).body(Vec::new()).unwrap());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let response = response.unwrap();
|
|
||||||
|
|
||||||
let resp_builder = ResponseBuilder::new().header(
|
|
||||||
CONTENT_TYPE,
|
|
||||||
response.headers().get("Content-Type").unwrap(),
|
|
||||||
);
|
|
||||||
let data = Vec::from(response.bytes().unwrap());
|
|
||||||
let resp = resp_builder.body(data).unwrap();
|
|
||||||
|
|
||||||
responder.respond(resp);
|
|
||||||
})
|
})
|
||||||
.on_window_event(|window, event| {
|
.on_window_event(|window, event| {
|
||||||
if let WindowEvent::CloseRequested { api, .. } = event {
|
if let WindowEvent::CloseRequested { api, .. } = event {
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
use cacache::Integrity;
|
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
|
||||||
|
|
||||||
use crate::{database::db::borrow_db_checked, error::remote_access_error::RemoteAccessError};
|
use crate::{database::db::borrow_db_checked, error::remote_access_error::RemoteAccessError};
|
||||||
|
use cacache::Integrity;
|
||||||
|
use http::{header::CONTENT_TYPE, response::Builder as ResponseBuilder, Response};
|
||||||
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
use tauri::{UriSchemeContext, UriSchemeResponder};
|
||||||
|
|
||||||
|
use super::{auth::generate_authorization_header, requests::make_request};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! offline {
|
macro_rules! offline {
|
||||||
@ -16,12 +18,93 @@ macro_rules! offline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_object<'a, K: AsRef<str>, D: Serialize + DeserializeOwned>(key: K, data: &D) -> Result<Integrity, RemoteAccessError> {
|
pub fn cache_object<'a, K: AsRef<str>, D: Serialize + DeserializeOwned>(
|
||||||
|
key: K,
|
||||||
|
data: &D,
|
||||||
|
) -> Result<Integrity, RemoteAccessError> {
|
||||||
let bytes = serde_json::to_vec(data).unwrap();
|
let bytes = serde_json::to_vec(data).unwrap();
|
||||||
cacache::write_sync(&borrow_db_checked().cache_dir, key, bytes).map_err(|e| RemoteAccessError::Cache(e))
|
cacache::write_sync(&borrow_db_checked().cache_dir, key, bytes)
|
||||||
|
.map_err(|e| RemoteAccessError::Cache(e))
|
||||||
}
|
}
|
||||||
pub fn get_cached_object<'a, K: AsRef<str>, D: Serialize + DeserializeOwned>(key: K) -> Result<D, RemoteAccessError> {
|
pub fn get_cached_object<'a, K: AsRef<str>, D: Serialize + DeserializeOwned>(
|
||||||
let bytes = cacache::read_sync(&borrow_db_checked().cache_dir, key).map_err(|e| RemoteAccessError::Cache(e))?;
|
key: K,
|
||||||
|
) -> Result<D, RemoteAccessError> {
|
||||||
|
let bytes = cacache::read_sync(&borrow_db_checked().cache_dir, key)
|
||||||
|
.map_err(|e| RemoteAccessError::Cache(e))?;
|
||||||
let data = serde_json::from_slice::<D>(&bytes).unwrap();
|
let data = serde_json::from_slice::<D>(&bytes).unwrap();
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fetch_object(
|
||||||
|
request: http::Request<Vec<u8>>,
|
||||||
|
responder: UriSchemeResponder,
|
||||||
|
) {
|
||||||
|
// Drop leading /
|
||||||
|
let object_id = &request.uri().path()[1..];
|
||||||
|
|
||||||
|
let header = generate_authorization_header();
|
||||||
|
let client: reqwest::blocking::Client = reqwest::blocking::Client::new();
|
||||||
|
let response = make_request(&client, &["/api/v1/client/object/", object_id], &[], |f| {
|
||||||
|
f.header("Authorization", header)
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.send();
|
||||||
|
if response.is_err() {
|
||||||
|
let data = get_cached_object::<&str, ObjectCache>(object_id);
|
||||||
|
|
||||||
|
match data {
|
||||||
|
Ok(data) => responder.respond(data.into()),
|
||||||
|
Err(_) => todo!(),
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let response = response.unwrap();
|
||||||
|
|
||||||
|
let resp_builder = ResponseBuilder::new().header(
|
||||||
|
CONTENT_TYPE,
|
||||||
|
response.headers().get("Content-Type").unwrap(),
|
||||||
|
);
|
||||||
|
let data = Vec::from(response.bytes().unwrap());
|
||||||
|
let resp = resp_builder.body(data).unwrap();
|
||||||
|
cache_object::<&str, ObjectCache>(object_id, &resp.clone().into()).unwrap();
|
||||||
|
|
||||||
|
responder.respond(resp);
|
||||||
|
}
|
||||||
|
pub fn fetch_object_offline(
|
||||||
|
request: http::Request<Vec<u8>>,
|
||||||
|
responder: UriSchemeResponder,
|
||||||
|
) {
|
||||||
|
let object_id = &request.uri().path()[1..];
|
||||||
|
let data = get_cached_object::<&str, ObjectCache>(object_id);
|
||||||
|
|
||||||
|
match data {
|
||||||
|
Ok(data) => responder.respond(data.into()),
|
||||||
|
Err(_) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct ObjectCache {
|
||||||
|
content_type: String,
|
||||||
|
body: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Response<Vec<u8>>> for ObjectCache {
|
||||||
|
fn from(value: Response<Vec<u8>>) -> Self {
|
||||||
|
ObjectCache {
|
||||||
|
content_type: value
|
||||||
|
.headers()
|
||||||
|
.get(CONTENT_TYPE)
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_owned(),
|
||||||
|
body: value.body().clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<ObjectCache> for Response<Vec<u8>> {
|
||||||
|
fn from(value: ObjectCache) -> Self {
|
||||||
|
let resp_builder = ResponseBuilder::new().header(CONTENT_TYPE, value.content_type);
|
||||||
|
resp_builder.body(value.body).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user