Skip to main content

soma_mcp_client/upstream/
http_client.rs

1use 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;