soma_mcp_client/upstream/
http_client.rs1use serde_json::Value;
2
3use super::{CapScope, ResponseCaps, TransportKind, UpstreamError};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum HttpTransportDecision {
7 Json,
8 Sse,
9 WebSocket,
10}
11
12pub fn decide_http_transport(url: &str) -> HttpTransportDecision {
13 if url.starts_with("ws://") || url.starts_with("wss://") {
14 return HttpTransportDecision::WebSocket;
15 }
16 if url.contains("transport=sse") {
17 return HttpTransportDecision::Sse;
18 }
19 HttpTransportDecision::Json
20}
21
22pub fn transport_kind_for_decision(decision: &HttpTransportDecision) -> TransportKind {
23 match decision {
24 HttpTransportDecision::Json => TransportKind::HttpJson,
25 HttpTransportDecision::Sse => TransportKind::HttpSse,
26 HttpTransportDecision::WebSocket => TransportKind::WebSocket,
27 }
28}
29
30pub fn parse_capped_json(bytes: &[u8], caps: &ResponseCaps) -> Result<Value, UpstreamError> {
31 caps.enforce(CapScope::HttpJson, bytes.len())?;
32 serde_json::from_slice(bytes).map_err(|_| UpstreamError::Unsupported {
33 upstream: "http".to_owned(),
34 capability: "http-json-parse",
35 })
36}
37
38pub fn capped_sse_event<'a>(event: &'a str, caps: &ResponseCaps) -> Result<&'a str, UpstreamError> {
39 caps.enforce(CapScope::HttpSseEvent, event.len())?;
40 Ok(event)
41}
42
43#[cfg(test)]
44#[path = "http_client_tests.rs"]
45mod tests;