chore: Remove unwraps from fetch_object and server_proto

Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
quexeky
2025-09-09 09:58:59 +10:00
parent be5500d29f
commit ddde547c08
9 changed files with 85 additions and 48 deletions

View File

@ -21,6 +21,7 @@ use crate::process::commands::open_process_logs;
use crate::process::process_handlers::UMU_LAUNCHER_EXECUTABLE;
use crate::remote::commands::auth_initiate_code;
use crate::remote::fetch_object::fetch_object_wrapper;
use crate::remote::server_proto::handle_server_proto_wrapper;
use crate::{database::db::DatabaseImpls, games::downloads::commands::resume_download};
use bitcode::{Decode, Encode};
use client::commands::fetch_state;
@ -61,7 +62,7 @@ use remote::commands::{
auth_initiate, fetch_drop_object, gen_drop_url, manual_recieve_handshake, retry_connect,
sign_out, use_remote,
};
use remote::server_proto::{handle_server_proto, handle_server_proto_offline};
use remote::server_proto::handle_server_proto_offline_wrapper;
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::Write;
@ -164,7 +165,7 @@ async fn setup(handle: AppHandle) -> AppState<'static> {
log4rs::init_config(config).expect("Failed to initialise log4rs");
let games = HashMap::new();
let download_manager = Arc::new(DownloadManagerBuilder::build(handle.clone()));
let download_manager = Arc::new(DownloadManagerBuilder::build(handle.clone()));
let process_manager = Arc::new(Mutex::new(ProcessManager::new(handle.clone())));
let compat_info = create_new_compat_info();
@ -473,8 +474,8 @@ pub fn run() {
offline!(
state,
handle_server_proto,
handle_server_proto_offline,
handle_server_proto_wrapper,
handle_server_proto_offline_wrapper,
request,
responder
)

View File

@ -9,7 +9,7 @@ use tauri::{AppHandle, Emitter, Manager};
use url::Url;
use crate::{
database::{
app_emit, database::{
db::{borrow_db_checked, borrow_db_mut_checked},
models::data::DatabaseAuth,
}, error::{drop_server_error::DropServerError, remote_access_error::RemoteAccessError}, remote::{requests::make_authenticated_get, utils::{DROP_CLIENT_ASYNC, DROP_CLIENT_SYNC}}, AppState, AppStatus, User
@ -83,7 +83,7 @@ pub async fn fetch_user() -> Result<User, RemoteAccessError> {
async fn recieve_handshake_logic(app: &AppHandle, path: String) -> Result<(), RemoteAccessError> {
let path_chunks: Vec<&str> = path.split('/').collect();
if path_chunks.len() != 3 {
app.emit("auth/failed", ()).unwrap();
app_emit!(app, "auth/failed", ());
return Err(RemoteAccessError::HandshakeFailed(
"failed to parse token".to_string(),
));
@ -141,12 +141,12 @@ async fn recieve_handshake_logic(app: &AppHandle, path: String) -> Result<(), Re
pub async fn recieve_handshake(app: AppHandle, path: String) {
// Tell the app we're processing
app.emit("auth/processing", ()).unwrap();
app_emit!(app, "auth/processing", ());
let handshake_result = recieve_handshake_logic(&app, path).await;
if let Err(e) = handshake_result {
warn!("error with authentication: {e}");
app.emit("auth/failed", e.to_string()).unwrap();
app_emit!(app, "auth/failed", e.to_string());
return;
}
@ -161,7 +161,7 @@ pub async fn recieve_handshake(app: AppHandle, path: String) {
drop(state_lock);
app.emit("auth/finished", ()).unwrap();
app_emit!(app, "auth/finished", ());
}
pub fn auth_initiate_logic(mode: String) -> Result<String, RemoteAccessError> {

View File

@ -10,7 +10,7 @@ use crate::{
error::{cache_error::CacheError, remote_access_error::RemoteAccessError},
};
use bitcode::{Decode, DecodeOwned, Encode};
use http::{header::{ToStrError, CONTENT_TYPE}, response::Builder as ResponseBuilder, Response};
use http::{header::{CONTENT_TYPE}, response::Builder as ResponseBuilder, Response};
#[macro_export]
macro_rules! offline {

View File

@ -8,14 +8,11 @@ use tauri::{AppHandle, Emitter, Manager};
use url::Url;
use crate::{
AppState, AppStatus,
database::db::{borrow_db_checked, borrow_db_mut_checked},
error::remote_access_error::RemoteAccessError,
remote::{
app_emit, database::db::{borrow_db_checked, borrow_db_mut_checked}, error::remote_access_error::RemoteAccessError, remote::{
auth::generate_authorization_header,
requests::generate_url,
utils::{DROP_CLIENT_SYNC, DROP_CLIENT_WS_CLIENT},
},
}, AppState, AppStatus
};
use super::{
@ -83,7 +80,7 @@ pub fn sign_out(app: AppHandle) {
}
// Emit event for frontend
app.emit("auth/signedout", ()).unwrap();
app_emit!(app, "auth/signedout", ());
}
#[tauri::command]
@ -167,7 +164,7 @@ pub fn auth_initiate_code(app: AppHandle) -> Result<String, RemoteAccessError> {
let result = load().await;
if let Err(err) = result {
warn!("{err}");
app.emit("auth/failed", err.to_string()).unwrap();
app_emit!(app, "auth/failed", err.to_string());
}
});

View File

@ -13,8 +13,8 @@ pub async fn fetch_object_wrapper(request: http::Request<Vec<u8>>, responder: Ur
match fetch_object(request).await {
Ok(r) => responder.respond(r),
Err(e) => {
warn!("Cache error: {}", e);
responder.respond(Response::new(Vec::new()));
warn!("Cache error: {e}");
responder.respond(Response::builder().status(500).body(Vec::new()).expect("Failed to build error response"));
}
};
}
@ -36,7 +36,7 @@ pub async fn fetch_object(request: http::Request<Vec<u8>>) -> Result<Response<Ve
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 {
return match response {
Ok(r) => {
let resp_builder = ResponseBuilder::new().header(
CONTENT_TYPE,
@ -48,8 +48,7 @@ pub async fn fetch_object(request: http::Request<Vec<u8>>) -> Result<Response<Ve
Ok(data) => Vec::from(data),
Err(e) => {
warn!(
"Could not get data from cache object {} with error {}",
object_id, e
"Could not get data from cache object {object_id} with error {e}",
);
Vec::new()
}
@ -60,11 +59,11 @@ pub async fn fetch_object(request: http::Request<Vec<u8>>) -> Result<Response<Ve
.expect("Failed to create cached object");
}
return Ok(resp.into());
Ok(resp.into())
}
Err(e) => {
debug!("Object fetch failed with error {}. Attempting to download from cache", e);
return match cache_result {
match cache_result {
Ok(cache_result) => Ok(cache_result.into()),
Err(e) => {
warn!("{e}");

View File

@ -1,57 +1,88 @@
use std::str::FromStr;
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
use log::warn;
use tauri::UriSchemeResponder;
use crate::{database::db::borrow_db_checked, remote::utils::DROP_CLIENT_SYNC};
pub async fn handle_server_proto_offline(_request: Request<Vec<u8>>, responder: UriSchemeResponder) {
let four_oh_four = Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Vec::new())
.unwrap();
responder.respond(four_oh_four);
pub async fn handle_server_proto_offline_wrapper(request: Request<Vec<u8>>, responder: UriSchemeResponder) {
responder.respond(match handle_server_proto_offline(request).await {
Ok(res) => res,
Err(e) => unreachable!()
});
}
pub async fn handle_server_proto(request: Request<Vec<u8>>, responder: UriSchemeResponder) {
pub async fn handle_server_proto_offline(_request: Request<Vec<u8>>) -> Result<Response<Vec<u8>>, StatusCode>{
Ok(Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Vec::new())
.expect("Failed to build error response for proto offline"))
}
pub async fn handle_server_proto_wrapper(request: Request<Vec<u8>>, responder: UriSchemeResponder) {
match handle_server_proto(request).await {
Ok(r) => responder.respond(r),
Err(e) => {
warn!("Cache error: {e}");
responder.respond(Response::builder().status(e).body(Vec::new()).expect("Failed to build error response"));
}
}
}
async fn handle_server_proto(request: Request<Vec<u8>>) -> Result<Response<Vec<u8>>, StatusCode> {
let db_handle = borrow_db_checked();
let web_token = match &db_handle.auth.as_ref().unwrap().web_token {
Some(e) => e,
None => return,
None => return Err(StatusCode::BAD_REQUEST),
};
let remote_uri = db_handle.base_url.parse::<Uri>().unwrap();
let remote_uri = db_handle.base_url.parse::<Uri>().expect("Failed to parse base url");
let path = request.uri().path();
let mut new_uri = request.uri().clone().into_parts();
new_uri.path_and_query =
Some(PathAndQuery::from_str(&format!("{path}?noWrapper=true")).unwrap());
Some(PathAndQuery::from_str(&format!("{path}?noWrapper=true")).expect("Failed to parse request path in proto"));
new_uri.authority = remote_uri.authority().cloned();
new_uri.scheme = remote_uri.scheme().cloned();
let new_uri = Uri::from_parts(new_uri).unwrap();
let new_uri = Uri::from_parts(new_uri).expect(&format!("Failed to build new uri from parts"));
let whitelist_prefix = ["/store", "/api", "/_", "/fonts"];
if whitelist_prefix.iter().all(|f| !path.starts_with(f)) {
webbrowser::open(&new_uri.to_string()).unwrap();
return;
return match webbrowser::open(&new_uri.to_string()) {
Ok(_) => Ok(Response::new(Vec::new())),
Err(e) => {
warn!("Could not open web browser to link {new_uri} with error {e}");
Ok(Response::new(Vec::new()))
}
}
}
let client = DROP_CLIENT_SYNC.clone();
let response = client
let response = match client
.request(request.method().clone(), new_uri.to_string())
.header("Authorization", format!("Bearer {web_token}"))
.headers(request.headers().clone())
.send()
.unwrap();
.send() {
Ok(response) => response,
Err(e) => {
warn!("Could not send response. Got {e} when sending");
return Err(e.status().unwrap_or(StatusCode::BAD_REQUEST))
},
};
let response_status = response.status();
let response_body = response.bytes().unwrap();
let response_body = match response.bytes() {
Ok(bytes) => bytes,
Err(e) => return Err(e.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)),
};
let http_response = Response::builder()
.status(response_status)
.body(response_body.to_vec())
.unwrap();
.expect("Failed to build server proto response");
responder.respond(http_response);
Ok(http_response)
}

View File

@ -11,10 +11,7 @@ use serde::Deserialize;
use url::Url;
use crate::{
AppState, AppStatus,
database::db::{DATA_ROOT_DIR, borrow_db_mut_checked},
error::remote_access_error::RemoteAccessError,
state_lock,
database::db::{borrow_db_mut_checked, DATA_ROOT_DIR}, error::remote_access_error::RemoteAccessError, state_lock, AppState, AppStatus
};
#[derive(Deserialize)]

View File

@ -0,0 +1,11 @@
#[macro_export]
macro_rules! app_emit {
($app:expr, $event:expr, $p:expr) => {
match $app.emit($event, $p) {
Ok(_) => (),
Err(e) => {
log::error!("Failed to emit event {} with error {}", $event, e);
}
};
};
}

View File

@ -1 +1,2 @@
pub mod state_lock;
mod app_emit;
mod state_lock;