synapse_proxy/transform/
wrap.rs1use async_trait::async_trait;
6use serde_json::Value;
7
8use crate::config::WrapSpec;
9use crate::context::ResolvedContext;
10
11use super::inject::{set_body_path, Inject};
12use super::{ProxyRequest, RequestTransform, TransformError};
13
14pub struct Wrap {
15 under: String,
16 siblings: Vec<Inject>,
17}
18
19impl Wrap {
20 pub fn from_spec(spec: &WrapSpec) -> anyhow::Result<Self> {
21 let siblings = spec
22 .inject
23 .iter()
24 .map(Inject::from_spec)
25 .collect::<anyhow::Result<Vec<_>>>()?;
26 Ok(Self {
27 under: spec.under.clone(),
28 siblings,
29 })
30 }
31}
32
33#[async_trait]
34impl RequestTransform for Wrap {
35 async fn apply(
36 &self,
37 ctx: &ResolvedContext,
38 req: &mut ProxyRequest,
39 ) -> Result<(), TransformError> {
40 let original = req.body_json_mut()?.take(); let mut envelope = Value::Object(Default::default());
43 set_body_path(&mut envelope, &self.under, original);
44 *req.body_json_mut()? = envelope;
45 for inj in &self.siblings {
46 inj.apply(ctx, req).await?;
47 }
48 Ok(())
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::config::InjectSpec;
56 use crate::transform::ProxyRequest;
57 use axum::http::{HeaderMap, Method};
58 use std::collections::HashMap;
59
60 fn ctx() -> ResolvedContext {
61 crate::context::ContextStore::new(HashMap::from([("org".into(), "acme".into())])).resolve()
62 }
63
64 #[tokio::test]
65 async fn wraps_body_and_injects_sibling() {
66 let wrap = Wrap::from_spec(&WrapSpec {
67 under: "request".into(),
68 inject: vec![InjectSpec {
69 header: None,
70 body: Some("org".into()),
71 from_context: Some("org".into()),
72 constant: None,
73 }],
74 })
75 .unwrap();
76 let mut r = ProxyRequest::from_parts(
77 Method::POST,
78 "/x".into(),
79 None,
80 HeaderMap::new(),
81 b"{\"method\":\"GET\",\"path\":\"/p\"}".to_vec(),
82 );
83 wrap.apply(&ctx(), &mut r).await.unwrap();
84 let v: Value = serde_json::from_slice(&r.into_body_bytes()).unwrap();
85 assert_eq!(v["request"]["method"], "GET");
86 assert_eq!(v["request"]["path"], "/p");
87 assert_eq!(v["org"], "acme");
88 }
89}