saddle-boundary 0.3.34

Saddle 0.3 ProfuseContract unary boundary transport
//! Fixed-storage recognition before business deserialization. The raw payload
//! remains a range in the original buffer; this module never constructs Value
//! or invokes a business Deserialize implementation. Serde's temporary scratch
//! is a disclosed third-party buffer, not a managed allocation guarantee.
use super::*;
use serde::de::{Deserializer, Visitor};
use serde_json::value::RawValue;
use std::{fmt, ops::Range};

#[derive(Debug)]
struct Text {
    bytes: [u8; MAX_ID_BYTES],
    len: usize,
    oversized: bool,
}
impl Default for Text {
    fn default() -> Self {
        Self {
            bytes: [0; MAX_ID_BYTES],
            len: 0,
            oversized: false,
        }
    }
}
impl Text {
    fn get(&self) -> &str {
        std::str::from_utf8(&self.bytes[..self.len]).expect("copied whole UTF-8")
    }
    fn identity(&self) -> Result<(), CodecError> {
        validate_id(self.get())
    }
    fn trace(&self) -> Result<(), CodecError> {
        if self.oversized {
            return Err(error(400, "INVALID_TRACE_ID"));
        }
        if self.len == 0 {
            Ok(())
        } else {
            validate_trace_id(self.get())
        }
    }
}
impl<'de> Deserialize<'de> for Text {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        struct FixedText;
        impl<'de> Visitor<'de> for FixedText {
            type Value = Text;
            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                f.write_str("a string")
            }
            fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Text, E> {
                let mut text = Text::default();
                if value.len() > MAX_ID_BYTES {
                    text.oversized = true;
                } else {
                    text.bytes[..value.len()].copy_from_slice(value.as_bytes());
                    text.len = value.len();
                }
                Ok(text)
            }
        }
        deserializer.deserialize_str(FixedText)
    }
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct Target {
    app: Text,
    #[serde(rename = "interfaceId")]
    interface_id: Text,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct User {
    #[serde(rename = "userId")]
    user_id: Text,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Trace {
    #[serde(default)]
    trace_id: Text,
    rpc_id: Text,
}
#[derive(Debug, Deserialize)]
struct Ldc {
    zone: Text,
    idc: Text,
    env: Text,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct Context {
    #[serde(rename = "userInfo")]
    user: User,
    #[serde(rename = "traceInfo")]
    trace: Trace,
    #[serde(rename = "ldcInfo")]
    ldc: Ldc,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct RawContext<'a> {
    #[serde(rename = "userInfo")]
    user: User,
    #[serde(borrow, rename = "traceInfo")]
    trace: &'a RawValue,
    #[serde(borrow, rename = "ldcInfo")]
    ldc: &'a RawValue,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Envelope<'a> {
    target: Target,
    #[serde(borrow, rename = "profuseGwContext")]
    context: RawContext<'a>,
    #[serde(borrow, rename = "requestData")]
    request_data: &'a RawValue,
    #[serde(default, borrow, rename = "profuseContext", deserialize_with = "super::json::present_raw")]
    profuse: Option<&'a RawValue>,
}

/// Bounded, listener-validated metadata. The range refers to the original body;
/// callers must retain that exact buffer through promotion. No business input
/// has been constructed. Its inline layout must be included in entry storage.
#[derive(Debug)]
pub struct IngressFacts {
    target: Target,
    context: Context,
    request_data: Range<usize>,
    trace_json: Range<usize>,
    ldc_json: Range<usize>,
    profuse_json: Option<Range<usize>>,
    rpc_value: Range<usize>,
    trace_value: Option<Range<usize>>,
}
impl IngressFacts {
    pub fn interface_id(&self) -> &str {
        self.target.interface_id.get()
    }
    pub fn user_id(&self) -> &str {
        self.context.user.user_id.get()
    }
    pub fn trace_id(&self) -> &str {
        self.context.trace.trace_id.get()
    }
    pub fn rpc_id(&self) -> &str {
        self.context.trace.rpc_id.get()
    }
    pub fn zone(&self) -> &str {
        self.context.ldc.zone.get()
    }
    pub fn idc(&self) -> &str {
        self.context.ldc.idc.get()
    }
    pub fn env(&self) -> &str {
        self.context.ldc.env.get()
    }
    pub fn request_data_range(&self) -> Range<usize> {
        self.request_data.clone()
    }
}
impl IngressFacts {
    pub(super) fn owned_context_json(&self, body: &[u8]) -> IngressContextJson {
        let text = |range: Range<usize>| std::str::from_utf8(&body[range]).expect("validated source").to_owned();
        IngressContextJson { trace_info: text(self.trace_json.clone()), rpc_value: self.rpc_value.clone(), trace_value: self.trace_value.clone(), ldc_info: text(self.ldc_json.clone()), profuse_context: self.profuse_json.clone().map(text) }
    }
}
pub(super) fn recognize_body(body: &[u8], parser_error: impl FnOnce(&serde_json::Error)) -> Result<IngressFacts, CodecError> {
    let mut parser_error = Some(parser_error);
    let mut parse_error = |original: serde_json::Error| {
        if let Some(observer) = parser_error.take() { observer(&original); }
        error(400, "INVALID_JSON_ENVELOPE")
    };
    let envelope: Envelope<'_> = serde_json::from_slice(body).map_err(&mut parse_error)?;
    let Envelope { target, context, request_data, profuse } = envelope;
    if context.trace.get().len() + context.ldc.get().len() + profuse.map_or(0, |raw| raw.get().len()) > crate::grouped_context::LIMIT {
        return Err(error(413, "CONTEXT_TOO_LARGE"));
    }
    let trace_fields = super::json::object(context.trace.get()).map_err(&mut parse_error)?;
    super::json::object(context.ldc.get()).map_err(&mut parse_error)?;
    if let Some(raw) = profuse { super::json::object(raw.get()).map_err(&mut parse_error)?; }
    let trace: Trace = serde_json::from_str(context.trace.get()).map_err(&mut parse_error)?;
    let ldc: Ldc = serde_json::from_str(context.ldc.get()).map_err(&mut parse_error)?;
    let range = |raw: &RawValue| {
        let text = raw.get(); let start = text.as_ptr() as usize - body.as_ptr() as usize;
        start..start+text.len()
    };
    let facts = IngressFacts {
        target, trace_json: range(context.trace), ldc_json: range(context.ldc), profuse_json: profuse.map(range),
        rpc_value: trace_fields.rpc.ok_or(error(400, "INVALID_JSON_ENVELOPE"))?, trace_value: trace_fields.trace,
        context: Context { user: context.user, trace, ldc }, request_data: range(request_data),
    };
    facts.target.app.identity()?; facts.target.interface_id.identity()?;
    facts.context.user.user_id.identity()?; facts.context.trace.trace_id.trace()?; facts.context.trace.rpc_id.identity()?;
    facts.context.ldc.zone.identity()?; facts.context.ldc.idc.identity()?; facts.context.ldc.env.identity()?;
    if !request_data.get().starts_with('{') { return Err(error(400, "INVALID_REQUEST_DATA")); }
    Ok(facts)
}
impl ProfuseGwListenerAdapter {
    pub fn recognize_observed(&self, method: &str, path: &str, content_type: &str, body: &[u8], parser_error: impl FnOnce(&serde_json::Error)) -> Result<IngressFacts, CodecError> {
        validate_transport(method, path, content_type, body)?;
        let facts = recognize_body(body, parser_error)?;
        if facts.target.app.get() != self.application.as_str() { return Err(error(404, "APPLICATION_NOT_FOUND")); }
        Ok(facts)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    fn body(payload: &str, target: &str) -> String {
        format!(
            r#"{{"requestData":{payload},"profuseGwContext":{{"userInfo":{{"userId":"用户"}},"traceInfo":{{"rpcId":"0"}},"ldcInfo":{{"zone":"z","idc":"i","env":"test"}}}},"target":{target}}}"#
        )
    }
    #[test]
    fn extensible_objects_preserve_raw_values_and_reject_ambiguous_input() {
        let adapter = ProfuseGwListenerAdapter::new("app").unwrap();
        let target = r#"{"app":"app","interfaceId":"route"}"#;
        let huge = "9".repeat(400);
        let source = body("{}", target).replace(r#""rpcId":"0""#, &format!(r#""rpcId":"0","extra":{{"n":{huge},"a":[null,"中文",true]}}"#))
            .replacen(r#""requestData""#, r#""profuseContext":{},"requestData""#, 1);
        let facts = adapter.recognize_observed(METHOD, PATH, MEDIA_TYPE, source.as_bytes(), |_| panic!("valid extensible object")).unwrap();
        let raw = facts.owned_context_json(source.as_bytes());
        assert!(raw.trace_info.contains(&huge));
        assert_eq!(raw.profuse_context.as_deref(), Some("{}"));
        let accepted = adapter.accept(METHOD, PATH, MEDIA_TYPE, IngressIdentity::new("r", "c", 1).unwrap(), source.as_bytes()).unwrap();
        let held = accepted.shared_context_json().unwrap();
        drop(accepted);
        assert_eq!(held.get().trace_info, raw.trace_info);
        for replacement in ["null", "[]", "false", r#"{"x":1,"x":2}"#, r#"{"a":[{"x":1,"\u0078":2}]}"#] {
            let bad = source.replacen(r#""profuseContext":{}"#, &format!(r#""profuseContext":{replacement}"#), 1);
            assert_eq!(adapter.recognize_observed(METHOD, PATH, MEDIA_TYPE, bad.as_bytes(), |_| {}).unwrap_err().http_status, 400);
            assert_eq!(adapter.accept(METHOD, PATH, MEDIA_TYPE, IngressIdentity::new("r", "c", 1).unwrap(), bad.as_bytes()).unwrap_err().http_status, 400);
        }
        let duplicate = source.replace(r#""n":"#, r#""n":1,"n":"#);
        assert_eq!(adapter.recognize_observed(METHOD, PATH, MEDIA_TYPE, duplicate.as_bytes(), |_| {}).unwrap_err().http_status, 400);
        let too_big = source.replace(&huge, &"9".repeat(4096));
        assert_eq!(adapter.recognize_observed(METHOD, PATH, MEDIA_TYPE, too_big.as_bytes(), |_| {}).unwrap_err().http_status, 413);
        assert!(adapter.accept(METHOD, PATH, MEDIA_TYPE, IngressIdentity::new("r", "c", 1).unwrap(), source.as_bytes()).is_ok());
    }
    #[test]
    fn route_at_tail_and_escaped_metadata_borrow_exact_raw_payload() {
        let source = body(
            r#" { "nested": [1,{"s":"a\\b"}] } "#,
            r#"{"app":"app","interfaceId":"路\u7531"}"#,
        );
        let adapter = ProfuseGwListenerAdapter::new("app").unwrap();
        let facts = adapter
            .recognize_observed(METHOD, PATH, MEDIA_TYPE, source.as_bytes(), |_| {
                panic!("valid JSON")
            })
            .unwrap();
        assert_eq!(facts.interface_id(), "路由");
        assert_eq!(facts.user_id(), "用户");
        let raw = &source.as_bytes()[facts.request_data_range()];
        assert_eq!(raw, br#"{ "nested": [1,{"s":"a\\b"}] }"#);
        assert!(std::mem::size_of::<IngressFacts>() < 4096);
    }
    #[test]
    fn bounded_recognition_preserves_codec_failures_and_original_parse_error() {
        let adapter = ProfuseGwListenerAdapter::new("app").unwrap();
        let target = r#"{"app":"app","interfaceId":"route"}"#;
        for source in [
            body("[]", target),
            body("{}", r#"{"app":"other","interfaceId":"route"}"#),
            body(
                "{}",
                &format!(r#"{{"app":"app","interfaceId":"{}"}}"#, "x".repeat(257)),
            ),
            body("{}", r#"{"app":"app","interfaceId":"r","extra":1}"#),
            body("{}", target).replace(
                "\"requestData\":{}",
                "\"requestData\":{},\"requestData\":{}",
            ),
            body("{", target),
        ] {
            let mut captured = false;
            let new = adapter
                .recognize_observed(METHOD, PATH, MEDIA_TYPE, source.as_bytes(), |_| {
                    captured = true
                })
                .unwrap_err();
            let old = adapter
                .accept(
                    METHOD,
                    PATH,
                    MEDIA_TYPE,
                    IngressIdentity::new("r", "c", 1).unwrap(),
                    source.as_bytes(),
                )
                .unwrap_err();
            assert_eq!(new, old);
            assert_eq!(captured, new.code == "INVALID_JSON_ENVELOPE");
        }
    }
}