diff --git a/backend/spi/spi-plugin/Cargo.toml b/backend/spi/spi-plugin/Cargo.toml index 6d5ad7e16..985933c38 100644 --- a/backend/spi/spi-plugin/Cargo.toml +++ b/backend/spi/spi-plugin/Cargo.toml @@ -25,7 +25,7 @@ tardis = { workspace = true, features = ["reldb-postgres", "web-server"] } bios-basic = { path = "../../basic", features = ["default"] } bios-sdk-invoke = { path = "../../../frontend/sdks/invoke", features = ["default"] } strum = { workspace = true, features = ["derive"] } - +percent-encoding = "2" [dev-dependencies] tardis = { workspace = true, features = ["test", "ws-client"] } bios-basic = { path = "../../basic", features = ["default", "test"] } diff --git a/backend/spi/spi-plugin/src/serv/plugin_exec_serv.rs b/backend/spi/spi-plugin/src/serv/plugin_exec_serv.rs index 24d78e0cc..ae0eacf4b 100644 --- a/backend/spi/spi-plugin/src/serv/plugin_exec_serv.rs +++ b/backend/spi/spi-plugin/src/serv/plugin_exec_serv.rs @@ -76,14 +76,32 @@ impl PluginExecServ { fn build_url(path: &str, query: Option>, body: Option, funs: &TardisFunsInst) -> TardisResult { let mut path = path.to_string(); + fn enc(s: &str) -> percent_encoding::PercentEncode<'_> { + percent_encoding::utf8_percent_encode(s, percent_encoding::NON_ALPHANUMERIC) + } if let Some(query) = query { - let query_str = query.iter().map(|(k, v)| format!("{}={}", k, v)).collect::>().join("&"); + let query_str = query.iter().fold(String::default(), |mut s, (k, v)| { + if k.is_empty() { + return s; + } + if !s.is_empty() { + s.push('&') + } + s.extend(enc(k)); + if !v.is_empty() { + s.push('='); + s.extend(enc(v)); + } + s + }); if path.ends_with('?') { path.push_str(&query_str); } else if path.contains('?') { - path.push_str(&format!("&{}", query_str)); + path.push('&'); + path.push_str(&query_str); } else { - path.push_str(&format!("?{}", query_str)); + path.push('?'); + path.push_str(&query_str); } } if !path.contains(':') { @@ -102,7 +120,7 @@ impl PluginExecServ { match new_r { Value::Bool(v) => return if *v { "true" } else { "false" }.into(), Value::Number(v) => return v.to_string().into(), - Value::String(v) => return v.into(), + Value::String(v) => return enc(v).to_string().into(), // TODO: Support more types: Null, Array, Object _ => return "".into(), }