(
config: &L7EndpointConfig,
engine: &TunnelPolicyEngine,
client: &mut C,
upstream: &mut U,
ctx: &L7EvalContext,
)
| 1014 | } |
| 1015 | |
| 1016 | async fn relay_jsonrpc<C, U>( |
| 1017 | config: &L7EndpointConfig, |
| 1018 | engine: &TunnelPolicyEngine, |
| 1019 | client: &mut C, |
| 1020 | upstream: &mut U, |
| 1021 | ctx: &L7EvalContext, |
| 1022 | ) -> Result<()> |
| 1023 | where |
| 1024 | C: AsyncRead + AsyncWrite + Unpin + Send, |
| 1025 | U: AsyncRead + AsyncWrite + Unpin + Send, |
| 1026 | { |
| 1027 | loop { |
| 1028 | if close_if_stale(engine.generation_guard(), ctx) { |
| 1029 | return Ok(()); |
| 1030 | } |
| 1031 | |
| 1032 | // Future MCP version-profile request checks should hook here before OPA |
| 1033 | // evaluation. See McpOptions in proto/sandbox.proto for the policy |
| 1034 | // roadmap and source documentation. |
| 1035 | let parsed = match crate::l7::jsonrpc::parse_jsonrpc_http_request( |
| 1036 | client, |
| 1037 | config.json_rpc_max_body_bytes, |
| 1038 | crate::l7::path::CanonicalizeOptions { |
| 1039 | allow_encoded_slash: config.allow_encoded_slash, |
| 1040 | ..Default::default() |
| 1041 | }, |
| 1042 | crate::l7::jsonrpc::JsonRpcInspectionOptions::for_config(config), |
| 1043 | ) |
| 1044 | .await |
| 1045 | { |
| 1046 | Ok(Some(parsed)) => parsed, |
| 1047 | Ok(None) => return Ok(()), |
| 1048 | Err(e) => { |
| 1049 | if is_benign_connection_error(&e) { |
| 1050 | debug!( |
| 1051 | host = %ctx.host, |
| 1052 | port = ctx.port, |
| 1053 | error = %e, |
| 1054 | "JSON-RPC L7 connection closed" |
| 1055 | ); |
| 1056 | } else { |
| 1057 | let detail = |
| 1058 | parse_rejection_detail(&e.to_string(), ParseRejectionMode::L7Endpoint); |
| 1059 | emit_parse_rejection(ctx, &detail, jsonrpc_engine_type(config.protocol)); |
| 1060 | } |
| 1061 | return Ok(()); |
| 1062 | } |
| 1063 | }; |
| 1064 | |
| 1065 | let req = parsed.request; |
| 1066 | let jsonrpc_info = parsed.info; |
| 1067 | |
| 1068 | if close_if_stale(engine.generation_guard(), ctx) { |
| 1069 | return Ok(()); |
| 1070 | } |
| 1071 | |
| 1072 | let redacted_target = req.target.clone(); |
| 1073 |
no test coverage detected