use serde_json::Value;
use arc_swap::ArcSwap;
use crate::proxy::{RewriteConfig, rewrite_response};
const MARKERS: &[&[u8]] = &[
b"connect_domains",
b"resource_domains",
b"frame_domains",
b"connectDomains",
b"resourceDomains",
b"frameDomains",
b"openai/widgetCSP",
b"ui.csp",
b"openai/widgetDomain",
];
#[must_use]
pub fn has_markers(body: &[u8]) -> bool {
MARKERS.iter().any(|m| contains_slice(body, m))
}
fn contains_slice(haystack: &[u8], needle: &[u8]) -> bool {
if needle.is_empty() || haystack.len() < needle.len() {
return needle.is_empty();
}
haystack.windows(needle.len()).any(|win| win == needle)
}
#[must_use]
pub fn rewrite_in_place(config: &ArcSwap<RewriteConfig>, method: &str, parsed: &mut Value) -> bool {
let cfg = config.load();
rewrite_response(method, parsed, &cfg)
}
#[cfg(test)]
#[allow(non_snake_case)]
mod tests {
use super::*;
#[test]
fn has_markers__finds_snake_case_array_key() {
let body = br#"{"result":{"connect_domains":["http://a"]}}"#;
assert!(has_markers(body));
}
#[test]
fn has_markers__finds_camel_case_array_key() {
let body = br#"{"result":{"connectDomains":["http://a"]}}"#;
assert!(has_markers(body));
}
#[test]
fn has_markers__finds_openai_shape() {
let body = br#"{"meta":{"openai/widgetCSP":{}}}"#;
assert!(has_markers(body));
}
#[test]
fn has_markers__plain_tool_call_no_markers() {
let body =
br#"{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"hi"}]}}"#;
assert!(!has_markers(body));
}
#[test]
fn has_markers__empty_body() {
assert!(!has_markers(b""));
}
}