mirror of
https://github.com/alibaba/higress.git
synced 2026-05-29 23:27:28 +08:00
Rust wrappers (#1367)
This commit is contained in:
263
plugins/wasm-rust/extensions/demo-wasm/Cargo.lock
generated
Normal file
263
plugins/wasm-rust/extensions/demo-wasm/Cargo.lock
generated
Normal file
@@ -0,0 +1,263 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "demo-wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"higress-wasm-rust",
|
||||
"http",
|
||||
"multimap",
|
||||
"proxy-wasm",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "higress-wasm-rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"http",
|
||||
"lazy_static",
|
||||
"multimap",
|
||||
"proxy-wasm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.157"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "374af5f94e54fa97cf75e945cce8a6b201e88a1a07e688b47dfd2a59c66dbd86"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proxy-wasm"
|
||||
version = "0.2.2"
|
||||
source = "git+https://github.com/higress-group/proxy-wasm-rust-sdk?branch=main#73833051f57d483570cf5aaa9d62bd7402fae63b"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.208"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.208"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
15
plugins/wasm-rust/extensions/demo-wasm/Cargo.toml
Normal file
15
plugins/wasm-rust/extensions/demo-wasm/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "demo-wasm"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
higress-wasm-rust = { path = "../../", version = "0.1.0" }
|
||||
proxy-wasm = { git="https://github.com/higress-group/proxy-wasm-rust-sdk", branch="main", version="0.2.2" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
multimap = "*"
|
||||
http = "*"
|
||||
203
plugins/wasm-rust/extensions/demo-wasm/src/lib.rs
Normal file
203
plugins/wasm-rust/extensions/demo-wasm/src/lib.rs
Normal file
@@ -0,0 +1,203 @@
|
||||
use higress_wasm_rust::cluster_wrapper::DnsCluster;
|
||||
use higress_wasm_rust::log::Log;
|
||||
use higress_wasm_rust::plugin_wrapper::{
|
||||
HttpCallArgStorage, HttpCallbackFn, HttpContextWrapper, RootContextWrapper,
|
||||
};
|
||||
use higress_wasm_rust::rule_matcher::{on_configure, RuleMatcher, SharedRuleMatcher};
|
||||
use http::Method;
|
||||
use multimap::MultiMap;
|
||||
use proxy_wasm::traits::{Context, HttpContext, RootContext};
|
||||
use proxy_wasm::types::{Bytes, ContextType, DataAction, HeaderAction, LogLevel};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::cell::RefCell;
|
||||
use std::ops::DerefMut;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
proxy_wasm::main! {{
|
||||
proxy_wasm::set_log_level(LogLevel::Trace);
|
||||
proxy_wasm::set_root_context(|_|Box::new(DemoWasmRoot::new()));
|
||||
}}
|
||||
|
||||
const PLUGIN_NAME: &str = "demo-wasm";
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Clone)]
|
||||
struct DemoWasmConfig {
|
||||
// 配置文件结构体
|
||||
test: String,
|
||||
}
|
||||
|
||||
fn format_body(body: Option<Vec<u8>>) -> String {
|
||||
if let Some(bd) = &body {
|
||||
if let Ok(b) = std::str::from_utf8(bd) {
|
||||
return b.to_string();
|
||||
}
|
||||
}
|
||||
format!("{:?}", body)
|
||||
}
|
||||
|
||||
fn test_callback(
|
||||
this: &mut DemoWasm,
|
||||
status_code: u16,
|
||||
headers: &MultiMap<String, String>,
|
||||
body: Option<Vec<u8>>,
|
||||
) {
|
||||
this.log.info(&format!(
|
||||
"test_callback status_code:{}, headers: {:?}, body: {}",
|
||||
status_code,
|
||||
headers,
|
||||
format_body(body)
|
||||
));
|
||||
this.reset_http_request();
|
||||
}
|
||||
struct DemoWasm {
|
||||
// 每个请求对应的插件实例
|
||||
log: Log,
|
||||
config: Option<DemoWasmConfig>,
|
||||
|
||||
arg_storage: HttpCallArgStorage<Box<HttpCallbackFn<DemoWasm>>>,
|
||||
}
|
||||
|
||||
impl Context for DemoWasm {}
|
||||
impl HttpContext for DemoWasm {}
|
||||
impl HttpContextWrapper<DemoWasmConfig, Box<HttpCallbackFn<DemoWasm>>> for DemoWasm {
|
||||
fn log(&self) -> &Log {
|
||||
&self.log
|
||||
}
|
||||
fn get_http_call_storage(
|
||||
&mut self,
|
||||
) -> Option<&mut HttpCallArgStorage<Box<HttpCallbackFn<DemoWasm>>>> {
|
||||
Some(&mut self.arg_storage)
|
||||
}
|
||||
fn on_config(&mut self, config: &DemoWasmConfig) {
|
||||
// 获取config
|
||||
self.log.info(&format!("on_config {}", config.test));
|
||||
self.config = Some(config.clone())
|
||||
}
|
||||
fn on_http_request_complete_headers(
|
||||
&mut self,
|
||||
headers: &MultiMap<String, String>,
|
||||
) -> HeaderAction {
|
||||
// 请求header获取完成回调
|
||||
self.log
|
||||
.info(&format!("on_http_request_complete_headers {:?}", headers));
|
||||
HeaderAction::Continue
|
||||
}
|
||||
fn on_http_response_complete_headers(
|
||||
&mut self,
|
||||
headers: &MultiMap<String, String>,
|
||||
) -> HeaderAction {
|
||||
// 返回header获取完成回调
|
||||
self.log
|
||||
.info(&format!("on_http_response_complete_headers {:?}", headers));
|
||||
HeaderAction::Continue
|
||||
}
|
||||
fn cache_request_body(&self) -> bool {
|
||||
// 是否缓存请求body
|
||||
true
|
||||
}
|
||||
fn cache_response_body(&self) -> bool {
|
||||
// 是否缓存返回body
|
||||
true
|
||||
}
|
||||
fn on_http_call_response_detail(
|
||||
&mut self,
|
||||
_token_id: u32,
|
||||
arg: Box<HttpCallbackFn<DemoWasm>>,
|
||||
status_code: u16,
|
||||
headers: &MultiMap<String, String>,
|
||||
body: Option<Vec<u8>>,
|
||||
) {
|
||||
arg(self, status_code, headers, body)
|
||||
}
|
||||
fn on_http_request_complete_body(&mut self, req_body: &Bytes) -> DataAction {
|
||||
// 请求body获取完成回调
|
||||
self.log.info(&format!(
|
||||
"on_http_request_complete_body {}",
|
||||
String::from_utf8(req_body.clone()).unwrap_or("".to_string())
|
||||
));
|
||||
let cluster = DnsCluster::new("httpbin", "httpbin.org", 80);
|
||||
if self
|
||||
.http_call(
|
||||
&cluster,
|
||||
&Method::POST,
|
||||
"http://httpbin.org/post",
|
||||
MultiMap::new(),
|
||||
Some("test_body".as_bytes()),
|
||||
// Box::new(move |this, _status_code, _headers, _body| this.resume_http_request()),
|
||||
Box::new(test_callback),
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
DataAction::StopIterationAndBuffer
|
||||
} else {
|
||||
self.log.info("http_call fail");
|
||||
DataAction::Continue
|
||||
}
|
||||
}
|
||||
fn on_http_response_complete_body(&mut self, res_body: &Bytes) -> DataAction {
|
||||
// 返回body获取完成回调
|
||||
self.log.info(&format!(
|
||||
"on_http_response_complete_body {}",
|
||||
String::from_utf8(res_body.clone()).unwrap_or("".to_string())
|
||||
));
|
||||
DataAction::Continue
|
||||
}
|
||||
}
|
||||
struct DemoWasmRoot {
|
||||
log: Log,
|
||||
rule_matcher: SharedRuleMatcher<DemoWasmConfig>,
|
||||
}
|
||||
impl DemoWasmRoot {
|
||||
fn new() -> Self {
|
||||
let log = Log::new(PLUGIN_NAME.to_string());
|
||||
log.info("DemoWasmRoot::new");
|
||||
DemoWasmRoot {
|
||||
log,
|
||||
rule_matcher: Rc::new(RefCell::new(RuleMatcher::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Context for DemoWasmRoot {}
|
||||
|
||||
impl RootContext for DemoWasmRoot {
|
||||
fn on_configure(&mut self, _plugin_configuration_size: usize) -> bool {
|
||||
self.log.info("DemoWasmRoot::on_configure");
|
||||
on_configure(
|
||||
self,
|
||||
_plugin_configuration_size,
|
||||
self.rule_matcher.borrow_mut().deref_mut(),
|
||||
&self.log,
|
||||
)
|
||||
}
|
||||
fn create_http_context(&self, context_id: u32) -> Option<Box<dyn HttpContext>> {
|
||||
self.log.info(&format!(
|
||||
"DemoWasmRoot::create_http_context({})",
|
||||
context_id
|
||||
));
|
||||
self.create_http_context_use_wrapper(context_id)
|
||||
}
|
||||
fn get_type(&self) -> Option<ContextType> {
|
||||
Some(ContextType::HttpContext)
|
||||
}
|
||||
}
|
||||
|
||||
impl RootContextWrapper<DemoWasmConfig, Box<HttpCallbackFn<DemoWasm>>> for DemoWasmRoot {
|
||||
fn rule_matcher(&self) -> &SharedRuleMatcher<DemoWasmConfig> {
|
||||
&self.rule_matcher
|
||||
}
|
||||
|
||||
fn create_http_context_wrapper(
|
||||
&self,
|
||||
_context_id: u32,
|
||||
) -> Option<Box<dyn HttpContextWrapper<DemoWasmConfig, Box<HttpCallbackFn<DemoWasm>>>>> {
|
||||
Some(Box::new(DemoWasm {
|
||||
config: None,
|
||||
log: Log::new(PLUGIN_NAME.to_string()),
|
||||
arg_storage: HttpCallArgStorage::new(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user