127 lines
4.6 KiB
Rust
127 lines
4.6 KiB
Rust
use std::collections::HashMap;
|
|
use warp::Filter;
|
|
use serde::{ Serialize, Deserialize };
|
|
use rust_util::XResult;
|
|
|
|
include!("lib.rs");
|
|
|
|
pub use qjs::*;
|
|
pub use sig::*;
|
|
pub use rpc::*;
|
|
pub use util::*;
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let get_public_key = warp::path("get_signing_public_key").map(|| {
|
|
match get_signing_public_key() {
|
|
None => "null".to_owned(),
|
|
Some(public_key) => {
|
|
let mut map = HashMap::new();
|
|
map.insert("public_key", hex::encode(&public_key));
|
|
serde_json::to_string_pretty(&map).unwrap_or_else(|e| format!("get public key error: {}", e))
|
|
},
|
|
}
|
|
});
|
|
|
|
let list_js = warp::path("list_js").map(|| {
|
|
let mut jss = vec![];
|
|
if let Ok(read_dir) = std::fs::read_dir("js") {
|
|
for entry in read_dir {
|
|
if let Ok(dir_entry) = entry {
|
|
if let Ok(file_name) = dir_entry.file_name().into_string() {
|
|
if file_name.ends_with(".js") {
|
|
let chars = file_name.chars();
|
|
jss.push(chars.take(file_name.chars().count() - 3).collect::<String>());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
serde_json::to_string_pretty(&jss).unwrap()
|
|
});
|
|
|
|
let get_js = warp::path!("get_js" / String).map(|js_hex| {
|
|
let js_fn = format!("js/{}.js", js_hex);
|
|
let js_sig_fn = format!("js/{}.sig.json", js_hex);
|
|
let js = read_file(&js_fn).unwrap();
|
|
let js_sig = read_file(&js_sig_fn).unwrap();
|
|
|
|
let signed_message: SignedMessage = serde_json::from_str(&js_sig).unwrap();
|
|
|
|
let mut result = HashMap::new();
|
|
result.insert("js", js);
|
|
result.insert("sig", js_sig);
|
|
result.insert("verify", signed_message.verify(&load_signing_key_pair().unwrap().public_key()).to_string());
|
|
|
|
serde_json::to_string(&result).unwrap()
|
|
});
|
|
|
|
let call_js = warp::post()
|
|
.and(warp::path!("call_js" / String))
|
|
.and(warp::body::json())
|
|
.map(|js_hex, call_js_body: CallJSBody| {
|
|
let the_fn = || -> XResult<String> {
|
|
let js_fn = format!("js/{}.js", js_hex);
|
|
let js_sig_fn = format!("js/{}.sig.json", js_hex);
|
|
let js = read_file(&js_fn)?;
|
|
let js_sig = read_file(&js_sig_fn)?;
|
|
|
|
let signed_message: SignedMessage = serde_json::from_str(&js_sig)?;
|
|
if !signed_message.verify(&load_signing_key_pair()?.public_key()) {
|
|
let mut result = HashMap::new();
|
|
result.insert("status", "400".to_owned());
|
|
result.insert("message", "Script verify failed!".to_owned());
|
|
result.insert("js_hash", format!("{}", js_hex));
|
|
return Ok(serde_json::to_string_pretty(&result)?);
|
|
}
|
|
|
|
let context = QuickJSContext::new()?;
|
|
context.init(&js)?;
|
|
|
|
let r = context.call_fn(&call_js_body.method, &call_js_body.params.unwrap_or_else(|| "[]".to_owned()));
|
|
|
|
let mut result = HashMap::new();
|
|
result.insert("js_hash", format!("{}", js_hex));
|
|
match r {
|
|
Err(e) => {
|
|
result.insert("status", "500".to_owned());
|
|
result.insert("message", "Script call failed!".to_owned());
|
|
result.insert("result", format!("{}", e));
|
|
},
|
|
Ok(r) => {
|
|
result.insert("status", "200".to_owned());
|
|
result.insert("message", "Script call successed!".to_owned());
|
|
result.insert("result", r.into_string().unwrap_or_else(|| "null".to_owned()));
|
|
},
|
|
}
|
|
Ok(serde_json::to_string_pretty(&result)?)
|
|
};
|
|
match the_fn() {
|
|
Err(e) => {
|
|
let mut result = HashMap::new();
|
|
result.insert("status", "500".to_owned());
|
|
result.insert("message", "Script call failed!".to_owned());
|
|
result.insert("result", format!("{}", e));
|
|
serde_json::to_string_pretty(&result).unwrap_or_else(|e| format!("JSON ser error: {}", e))
|
|
},
|
|
Ok(r) => r,
|
|
}
|
|
});
|
|
|
|
println!("Listen at 127.0.0.1:8888 ...");
|
|
warp::serve(
|
|
get_public_key.or(list_js)
|
|
.or(get_js)
|
|
.or(call_js)
|
|
)
|
|
.run(([127, 0, 0, 1], 8888))
|
|
.await;
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
struct CallJSBody {
|
|
method: String,
|
|
params: Option<String>,
|
|
}
|
|
|