mod memory;
use memory::{read_string, write_string};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
// Plugin configuration storage
static mut CONFIG: Option<String> = None;
#[no_mangle]
pub extern "C" fn get_name() -> u64 {
write_string("my-rust-wasm-plugin")
}
#[no_mangle]
pub extern "C" fn init(config_ptr: u32, config_len: u32) -> i32 {
let config = read_string(config_ptr, config_len);
unsafe { CONFIG = Some(config); }
0 // Success
}
#[derive(Deserialize)]
struct HTTPInterceptInput {
context: HashMap<String, serde_json::Value>,
request: serde_json::Value,
}
#[derive(Serialize, Default)]
struct HTTPInterceptOutput {
context: HashMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
request: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
response: Option<serde_json::Value>,
has_response: bool,
error: String,
}
#[no_mangle]
pub extern "C" fn http_intercept(input_ptr: u32, input_len: u32) -> u64 {
let input_str = read_string(input_ptr, input_len);
let input: HTTPInterceptInput = match serde_json::from_str(&input_str) {
Ok(i) => i,
Err(e) => {
let output = HTTPInterceptOutput {
error: format!("Parse error: {}", e),
..Default::default()
};
return write_string(&serde_json::to_string(&output).unwrap());
}
};
let mut context = input.context;
context.insert("from-http".to_string(), serde_json::json!("rust-wasm"));
let output = HTTPInterceptOutput {
context,
request: Some(input.request),
has_response: false,
..Default::default()
};
write_string(&serde_json::to_string(&output).unwrap())
}
#[derive(Deserialize)]
struct PreHookInput {
context: HashMap<String, serde_json::Value>,
request: serde_json::Value,
}
#[derive(Serialize, Default)]
struct PreHookOutput {
context: HashMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
request: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
short_circuit: Option<serde_json::Value>,
has_short_circuit: bool,
error: String,
}
#[no_mangle]
pub extern "C" fn pre_hook(input_ptr: u32, input_len: u32) -> u64 {
let input_str = read_string(input_ptr, input_len);
let input: PreHookInput = match serde_json::from_str(&input_str) {
Ok(i) => i,
Err(e) => {
let output = PreHookOutput {
error: format!("Parse error: {}", e),
..Default::default()
};
return write_string(&serde_json::to_string(&output).unwrap());
}
};
let mut context = input.context;
context.insert("from-pre-hook".to_string(), serde_json::json!("rust-wasm"));
let output = PreHookOutput {
context,
request: Some(input.request),
has_short_circuit: false,
..Default::default()
};
write_string(&serde_json::to_string(&output).unwrap())
}
#[derive(Deserialize)]
struct PostHookInput {
context: HashMap<String, serde_json::Value>,
response: serde_json::Value,
error: serde_json::Value,
has_error: bool,
}
#[derive(Serialize, Default)]
struct PostHookOutput {
context: HashMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
response: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
error: Option<serde_json::Value>,
has_error: bool,
hook_error: String,
}
#[no_mangle]
pub extern "C" fn post_hook(input_ptr: u32, input_len: u32) -> u64 {
let input_str = read_string(input_ptr, input_len);
let input: PostHookInput = match serde_json::from_str(&input_str) {
Ok(i) => i,
Err(e) => {
let output = PostHookOutput {
hook_error: format!("Parse error: {}", e),
..Default::default()
};
return write_string(&serde_json::to_string(&output).unwrap());
}
};
let mut context = input.context;
context.insert("from-post-hook".to_string(), serde_json::json!("rust-wasm"));
let output = PostHookOutput {
context,
response: Some(input.response),
error: Some(input.error),
has_error: input.has_error,
hook_error: String::new(),
};
write_string(&serde_json::to_string(&output).unwrap())
}
#[no_mangle]
pub extern "C" fn cleanup() -> i32 {
unsafe { CONFIG = None; }
0 // Success
}