[feat] address comments for optimize writeBinaryFile
This commit is contained in:
@@ -27,6 +27,7 @@ actix-web = "4.0"
|
|||||||
actix-cors = "0.6"
|
actix-cors = "0.6"
|
||||||
actix-rt = "2.5"
|
actix-rt = "2.5"
|
||||||
url = "2.2"
|
url = "2.2"
|
||||||
|
uuid = { version = "1.9.1", features = [ "v4" ] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||||
|
|||||||
@@ -7,11 +7,15 @@ fn greet(name: &str) -> String {
|
|||||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use actix_web::dev::Server;
|
||||||
|
use actix_web::http::header;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
|
use tauri::State;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::sync::Mutex;
|
||||||
use std::{time::Duration, path::Path};
|
use std::{time::Duration, path::Path};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -19,6 +23,8 @@ use actix_cors::Cors;
|
|||||||
use tauri::api::path::app_data_dir;
|
use tauri::api::path::app_data_dir;
|
||||||
use actix_web::{web, HttpRequest, HttpResponse, HttpServer, Responder, App, post, get};
|
use actix_web::{web, HttpRequest, HttpResponse, HttpServer, Responder, App, post, get};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
struct HttpSecret(Mutex<String>);
|
||||||
|
struct HttpPort(Mutex<u16>);
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn native_request(url: String, body: String, header: String, method:String) -> String {
|
async fn native_request(url: String, body: String, header: String, method:String) -> String {
|
||||||
@@ -379,10 +385,8 @@ fn run_server_local(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn streamed_fetch(id:String, url:String, headers: String, body: String, handle: tauri::AppHandle) -> String {
|
async fn streamed_fetch(id:String, url:String, headers: String, body: String, handle: tauri::AppHandle) -> String {
|
||||||
|
|
||||||
//parse headers
|
//parse headers
|
||||||
let headers_json: Value = match serde_json::from_str(&headers) {
|
let headers_json: Value = match serde_json::from_str(&headers) {
|
||||||
Ok(h) => h,
|
Ok(h) => h,
|
||||||
@@ -452,9 +456,24 @@ async fn streamed_fetch(id:String, url:String, headers: String, body: String, ha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_http_secret(secret_state: State<HttpSecret>) -> String {
|
||||||
|
secret_state.0.lock().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_http_port(port_state: State<HttpPort>) -> u16 {
|
||||||
|
port_state.0.lock().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/")]
|
#[post("/")]
|
||||||
async fn write_binary_file_to_appdata(req: HttpRequest, body: web::Bytes, app_handle: web::Data<tauri::AppHandle>) -> impl Responder {
|
async fn write_binary_file_to_appdata(req: HttpRequest, body: web::Bytes, app_handle: web::Data<tauri::AppHandle>, secret: web::Data<String>) -> impl Responder {
|
||||||
let query = req.query_string();
|
let query = req.query_string();
|
||||||
|
let headers = req.headers();
|
||||||
|
let req_secret = headers.get("x-tauri-secret").unwrap().to_str().unwrap();
|
||||||
|
if req_secret != *secret.as_ref() {
|
||||||
|
return HttpResponse::Unauthorized().body("Unauthorized");
|
||||||
|
}
|
||||||
let params: std::collections::HashMap<_, _> = url::form_urlencoded::parse(query.as_bytes()).into_owned().collect();
|
let params: std::collections::HashMap<_, _> = url::form_urlencoded::parse(query.as_bytes()).into_owned().collect();
|
||||||
let app_data_dir = app_data_dir(&app_handle.config()).expect("App dir must be returned by tauri");
|
let app_data_dir = app_data_dir(&app_handle.config()).expect("App dir must be returned by tauri");
|
||||||
if let Some(file_path) = params.get("path") {
|
if let Some(file_path) = params.get("path") {
|
||||||
@@ -479,8 +498,41 @@ async fn write_binary_file_to_appdata(req: HttpRequest, body: web::Bytes, app_ha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn run_http_server(handle: tauri::AppHandle, secret: String) {
|
||||||
|
for port in 5354..65535 {
|
||||||
|
let handle_copy = handle.clone();
|
||||||
|
let secret_copy = secret.clone();
|
||||||
|
let res = HttpServer::new(move || {
|
||||||
|
App::new()
|
||||||
|
.wrap(
|
||||||
|
Cors::default()
|
||||||
|
.allow_any_origin()
|
||||||
|
.allow_any_method()
|
||||||
|
.allow_any_header()
|
||||||
|
.max_age(3600)
|
||||||
|
)
|
||||||
|
.app_data(web::PayloadConfig::new(1024 * 1024 * 1024)) // 1 GB
|
||||||
|
.app_data(web::Data::new(handle_copy.clone()))
|
||||||
|
.app_data(web::Data::new(secret_copy.clone()))
|
||||||
|
.service(write_binary_file_to_appdata)
|
||||||
|
})
|
||||||
|
.bind(("127.0.0.1", port));
|
||||||
|
match res {
|
||||||
|
Ok(server) => {
|
||||||
|
handle.manage(HttpPort(Mutex::new(port)));
|
||||||
|
server.run().await;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to bind to port {}: {}", port, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.manage(HttpSecret(uuid::Uuid::new_v4().to_string().into()))
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
greet,
|
greet,
|
||||||
native_request,
|
native_request,
|
||||||
@@ -492,28 +544,17 @@ fn main() {
|
|||||||
post_py_install,
|
post_py_install,
|
||||||
run_py_server,
|
run_py_server,
|
||||||
install_py_dependencies,
|
install_py_dependencies,
|
||||||
streamed_fetch
|
streamed_fetch,
|
||||||
|
get_http_secret,
|
||||||
|
get_http_port
|
||||||
])
|
])
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
let handle = app.handle().clone();
|
let handle = app.handle().clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
let secret_state: State<HttpSecret> = app.state();
|
||||||
HttpServer::new(move || {
|
let secret = secret_state.0.lock().unwrap().clone();
|
||||||
App::new()
|
std::thread::spawn(move || {
|
||||||
.wrap(
|
let rt = actix_rt::Runtime::new().unwrap();
|
||||||
Cors::default()
|
rt.block_on(run_http_server(handle.clone(), secret.clone()));
|
||||||
.allow_any_origin()
|
|
||||||
.allow_any_method()
|
|
||||||
.allow_any_header()
|
|
||||||
.max_age(3600)
|
|
||||||
)
|
|
||||||
.app_data(web::PayloadConfig::new(1024 * 1024 * 1024)) // 1 GB
|
|
||||||
.app_data(web::Data::new(handle.clone()))
|
|
||||||
.service(write_binary_file_to_appdata)
|
|
||||||
})
|
|
||||||
.bind(("127.0.0.1", 5354))
|
|
||||||
.expect("Failed to bind to port 5354")
|
|
||||||
.run()
|
|
||||||
.await;
|
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { writeBinaryFile,BaseDirectory, readBinaryFile, exists, createDir, readDir, removeFile } from "@tauri-apps/api/fs"
|
import { writeBinaryFile,BaseDirectory, readBinaryFile, exists, createDir, readDir, removeFile } from "@tauri-apps/api/fs"
|
||||||
|
|
||||||
import { changeFullscreen, checkNullish, findCharacterbyId, sleep } from "../util"
|
import { changeFullscreen, checkNullish, findCharacterbyId, sleep } from "../util"
|
||||||
import { convertFileSrc, invoke } from "@tauri-apps/api/tauri"
|
import { convertFileSrc, invoke } from "@tauri-apps/api/tauri"
|
||||||
import { v4 as uuidv4, v4 } from 'uuid';
|
import { v4 as uuidv4, v4 } from 'uuid';
|
||||||
@@ -56,12 +57,16 @@ interface fetchLog{
|
|||||||
let fetchLog:fetchLog[] = []
|
let fetchLog:fetchLog[] = []
|
||||||
|
|
||||||
async function writeBinaryFileFast(appPath: string, data: Uint8Array) {
|
async function writeBinaryFileFast(appPath: string, data: Uint8Array) {
|
||||||
const apiUrl = `http://127.0.0.1:5354/?path=${encodeURIComponent(appPath)}`;
|
const secret = await invoke('get_http_secret') as string;
|
||||||
|
const port = await invoke('get_http_port') as number;
|
||||||
|
|
||||||
|
const apiUrl = `http://127.0.0.1:${port}/?path=${encodeURIComponent(appPath)}`;
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
const response = await fetch(apiUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/octet-stream'
|
'Content-Type': 'application/octet-stream',
|
||||||
|
'x-tauri-secret': secret
|
||||||
},
|
},
|
||||||
body: new Blob([data])
|
body: new Blob([data])
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const magicCompressedHeader = new Uint8Array([0, 82, 73, 83, 85, 83, 65, 86, 69,
|
|||||||
|
|
||||||
export function encodeRisuSave(data:any, compression:'noCompression'|'compression' = 'noCompression'){
|
export function encodeRisuSave(data:any, compression:'noCompression'|'compression' = 'noCompression'){
|
||||||
let encoded:Uint8Array = packr.encode(data)
|
let encoded:Uint8Array = packr.encode(data)
|
||||||
if(isTauri || compression === 'compression'){
|
if(compression === 'compression'){
|
||||||
encoded = fflate.compressSync(encoded)
|
encoded = fflate.compressSync(encoded)
|
||||||
const result = new Uint8Array(encoded.length + magicCompressedHeader.length);
|
const result = new Uint8Array(encoded.length + magicCompressedHeader.length);
|
||||||
result.set(magicCompressedHeader, 0)
|
result.set(magicCompressedHeader, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user