refactor(remote): Created separate function to generate requests

This commit is contained in:
quexeky
2025-01-19 15:09:35 +11:00
parent fd30b3e402
commit 9a184a8f35
5 changed files with 53 additions and 47 deletions

View File

@ -5,6 +5,7 @@ use std::{
use serde::Serialize;
#[derive(Debug)]
pub enum UserValue<T, D>
where
T: Serialize,
@ -33,7 +34,6 @@ impl<T: Serialize, D: Display> From<Result<T, D>> for UserValue<T, D> {
}
}
}
impl<T: Serialize, D: Display> Try for UserValue<T, D> {
type Output = T;

View File

@ -13,6 +13,7 @@ use crate::error::application_download_error::ApplicationDownloadError;
use crate::error::remote_access_error::RemoteAccessError;
use crate::games::downloads::manifest::{DropDownloadContext, DropManifest};
use crate::games::library::{on_game_complete, push_game_update, GameUpdateEvent};
use crate::remote::requests::make_request;
use crate::DB;
use log::{debug, error, info};
use rayon::ThreadPoolBuilder;
@ -264,8 +265,6 @@ impl GameDownloadAgent {
let completed_indexes = Arc::new(boxcar::Vec::new());
let completed_indexes_loop_arc = completed_indexes.clone();
let base_url = DB.fetch_base_url();
let contexts = self.contexts.lock().unwrap();
pool.scope(|scope| {
let client = &reqwest::blocking::Client::new();
@ -283,7 +282,18 @@ impl GameDownloadAgent {
let sender = self.sender.clone();
let request = generate_request(&base_url, client, context);
// TODO: Error handling
let request = make_request(&client, &[
"/api/v1/client/chunk"
], &[
("id", &context.game_id),
("version", &context.version),
("name", &context.file_name),
("chunk", &context.index.to_string()),
],
|r| {
r.header("Authorization", generate_authorization_header())
}).unwrap();
scope.spawn(move |_| {
match download_game_chunk(context, &self.control_flag, progress_handle, request)
@ -338,27 +348,6 @@ impl GameDownloadAgent {
}
}
fn generate_request(
base_url: &url::Url,
client: reqwest::blocking::Client,
context: &DropDownloadContext,
) -> reqwest::blocking::RequestBuilder {
let chunk_url = base_url
.join(&format!(
"/api/v1/client/chunk?id={}&version={}&name={}&chunk={}",
// Encode the parts we don't trust
context.game_id,
encode(&context.version),
encode(&context.file_name),
context.index
))
.unwrap();
let header = generate_authorization_header();
client.get(chunk_url).header("Authorization", header)
}
impl Downloadable for GameDownloadAgent {
fn download(&self, app_handle: &AppHandle) -> Result<bool, ApplicationDownloadError> {
*self.status.lock().unwrap() = DownloadStatus::Downloading;

View File

@ -16,6 +16,7 @@ use crate::error::remote_access_error::RemoteAccessError;
use crate::games::state::{GameStatusManager, GameStatusWithTransient};
use crate::process::process_manager::Platform;
use crate::remote::auth::generate_authorization_header;
use crate::remote::requests::make_request;
use crate::{AppState, DB};
#[derive(serde::Serialize)]
@ -66,7 +67,7 @@ pub struct StatsUpdateEvent {
}
// Game version with some fields missing and size information
#[derive(serde::Deserialize, serde::Serialize)]
#[derive(serde::Deserialize, serde::Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GameVersionOption {
version_index: usize,
@ -137,17 +138,10 @@ pub fn fetch_game_logic(
return Ok(data);
}
let base_url = DB.fetch_base_url();
let endpoint = base_url.join(&format!("/api/v1/game/{}", id))?;
let header = generate_authorization_header();
let client = reqwest::blocking::Client::new();
let response = client
.get(endpoint.to_string())
.header("Authorization", header)
.send()?;
let response = make_request(&client, &["/api/v1/game/", &id],&[], |r| {
r.header("Authorization", generate_authorization_header())
})?.send()?;
if response.status() == 404 {
return Err(RemoteAccessError::GameNotFound);
@ -184,25 +178,21 @@ pub fn fetch_game_verion_options_logic(
game_id: String,
state: tauri::State<'_, Mutex<AppState>>,
) -> Result<Vec<GameVersionOption>, RemoteAccessError> {
let base_url = DB.fetch_base_url();
let endpoint =
base_url.join(format!("/api/v1/client/game/versions?id={}", game_id).as_str())?;
let header = generate_authorization_header();
let client = reqwest::blocking::Client::new();
let response = client
.get(endpoint.to_string())
.header("Authorization", header)
.send()?;
let response = make_request(&client, &["/api/v1/client/game/versions"], &[("id", &game_id)], |r| {
r.header("Authorization", generate_authorization_header())
})?.send()?;
if response.status() != 200 {
let err = response.json().unwrap();
warn!("{:?}", err);
return Err(RemoteAccessError::InvalidResponse(err));
}
let text = response.text().unwrap();
println!("JSON Text: {}", text);
let data: Vec<GameVersionOption> = response.json()?;
let data: Vec<GameVersionOption> = serde_json::from_str(&text).unwrap();
let state_lock = state.lock().unwrap();
let process_manager_lock = state_lock.process_manager.lock().unwrap();

View File

@ -1,3 +1,4 @@
pub mod auth;
pub mod commands;
pub mod remote;
pub mod requests;

View File

@ -0,0 +1,26 @@
use std::ops::Deref;
use reqwest::blocking::{Client, RequestBuilder, Response};
use url::{ParseError, Url};
use crate::{database::db::DatabaseImpls, error::remote_access_error::RemoteAccessError, DB};
pub fn make_request<'a, T: AsRef<str>, F: FnOnce(RequestBuilder) -> RequestBuilder>(
client: &Client,
endpoints: &[T],
params: &[(T, T)],
f: F,
) -> Result<RequestBuilder, RemoteAccessError> {
let mut base_url = DB.fetch_base_url();
for endpoint in endpoints {
base_url = base_url.join(endpoint.as_ref())?;
}
{
let mut queries = base_url.query_pairs_mut();
for (param, val) in params {
queries.append_pair(param.as_ref(), val.as_ref());
}
}
let response = client.get(base_url);
Ok(f(response))
}