feat: udpate container
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use reqwest::Method;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use wasmtime::{Config, Engine, Instance, Linker, Module, Store};
|
use wasmtime::{Config, Engine, Instance, Linker, Module, Store};
|
||||||
|
|
||||||
@@ -13,11 +15,24 @@ struct FetchResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FetchResult {
|
impl FetchResult {
|
||||||
|
fn fail(message: impl Into<String>) -> Self {
|
||||||
|
FetchResult {
|
||||||
|
result: None,
|
||||||
|
error: Some(message.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_json(&self) -> String {
|
fn to_json(&self) -> String {
|
||||||
serde_json::to_string(&self).expect("JSResult to json error")
|
serde_json::to_string(&self).expect("JSResult to json error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<String> for FetchResult {
|
||||||
|
fn into(self) -> String {
|
||||||
|
self.to_json()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
struct JsResult {
|
struct JsResult {
|
||||||
message: String,
|
message: String,
|
||||||
@@ -29,41 +44,85 @@ impl JsResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(url: &str) -> reqwest::Result<reqwest::blocking::Response> {
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
let client = reqwest::blocking::Client::builder()
|
struct FetchOptions {
|
||||||
.timeout(Duration::from_secs(8))
|
method: Option<String>,
|
||||||
.connect_timeout(Duration::from_secs(3))
|
headers: Option<BTreeMap<String, String>>,
|
||||||
// .proxy(reqwest::Proxy::all("http://127.0.0.1:1086").expect("to proxy failed"))
|
body: Option<String>,
|
||||||
.build()?;
|
}
|
||||||
let request_builder = client.get(url);
|
|
||||||
let request_builder = request_builder.header("X-Custom-Header", "Value");
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
request_builder.send()
|
struct FetchParams {
|
||||||
|
url: String,
|
||||||
|
options: Option<FetchOptions>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct MyContainer;
|
pub struct MyContainer;
|
||||||
|
|
||||||
impl container::Container for MyContainer {
|
impl container::Container for MyContainer {
|
||||||
fn fetch(&mut self, s: &str) -> String {
|
fn fetch(&mut self, params: &str) -> String {
|
||||||
println!("fetch arguments: {}", s);
|
let fetch_params: FetchParams = match serde_json::from_str(params) {
|
||||||
let url: String = s.chars().skip(1).take(s.len() - 2).collect();
|
Err(e) => return FetchResult::fail(format!("Fetch param parse error: {}, raw params: {}", e, params)).to_json(),
|
||||||
println!("fetch arguments URL: {}", url);
|
Ok(params) => params,
|
||||||
let r = match get(&url) {
|
};
|
||||||
Err(e) => return FetchResult {
|
if fetch_params.url.is_empty() {
|
||||||
error: Some(JsResult {
|
return FetchResult::fail("Param url cannot be empty").to_json();
|
||||||
message: format!("failed: {}", e)
|
}
|
||||||
}.to_json()),
|
let client = match reqwest::blocking::Client::builder()
|
||||||
result: None,
|
.timeout(Duration::from_secs(8))
|
||||||
}.to_json(),
|
.connect_timeout(Duration::from_secs(3))
|
||||||
Ok(r) => r,
|
// .proxy(reqwest::Proxy::all("http://127.0.0.1:1086").expect("to proxy failed"))
|
||||||
|
.build() {
|
||||||
|
Err(e) => return FetchResult::fail(format!("Create client failed: {}", e)).to_json(),
|
||||||
|
Ok(client) => client,
|
||||||
|
};
|
||||||
|
let method = fetch_params.options.as_ref().map(|options| options.method.as_ref().map(|m| m.to_uppercase())).flatten();
|
||||||
|
let method_str = method.as_ref().map(|m| m.as_str()).unwrap_or_else(|| "GET");
|
||||||
|
let request_method = match method_str {
|
||||||
|
"GET" => Method::GET,
|
||||||
|
"POST" => Method::POST,
|
||||||
|
m => return FetchResult::fail(format!("Unsupported method: {}", m)).to_json(),
|
||||||
|
};
|
||||||
|
let mut request_builder = client.request(request_method.clone(), &fetch_params.url);
|
||||||
|
if let Some(options) = &fetch_params.options {
|
||||||
|
let mut has_user_agent = false;
|
||||||
|
if let Some(headers) = &options.headers {
|
||||||
|
for (k, v) in headers {
|
||||||
|
if k.to_lowercase() == "user-agent" {
|
||||||
|
has_user_agent = true;
|
||||||
|
}
|
||||||
|
request_builder = request_builder.header(k.to_string(), v.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !has_user_agent {
|
||||||
|
request_builder = request_builder.header("User-Agent", "JavaScriptSandboxContainer/0.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(body) = &options.body {
|
||||||
|
if Method::POST == request_method {
|
||||||
|
let body = reqwest::blocking::Body::from(body.to_string());
|
||||||
|
request_builder = request_builder.body(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetch_response = match request_builder.send() {
|
||||||
|
Err(e) => return FetchResult::fail(format!("Send request failed: {}", e)).to_json(),
|
||||||
|
Ok(fetch_response) => fetch_response,
|
||||||
};
|
};
|
||||||
|
|
||||||
FetchResult {
|
let status = fetch_response.status().as_u16();
|
||||||
error: None,
|
let headers = fetch_response.headers();
|
||||||
result: Some(JsResult {
|
let body = fetch_response.bytes();
|
||||||
message: format!("fetched: {:?}", r.text()),
|
|
||||||
}.to_json()),
|
// FetchResult {
|
||||||
}.to_json()
|
// error: None,
|
||||||
|
// result: Some(JsResult {
|
||||||
|
// message: format!("fetched: {:?}", r.text()),
|
||||||
|
// }.to_json()),
|
||||||
|
// }.to_json()
|
||||||
|
"".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user