Expand description
A minimal blocking HTTP/1.1 client over any Read + Write. RFC 0006.
This is the single highest-leverage minimalism decision (RFC 0002): one
~250-line module replaces the ureq/url→IDNA→ICU dependency tax. It
carries the intelligence wire over TCP, TLS, unix sockets, and vsock
alike — the transport is just the stream.
Two request paths: send buffers the whole response (the LLM/intelligence
path), and send_streaming returns the status + headers plus a live reader
so the caller can either buffer it (application/json) or pump it as an SSE
stream (SseReader) — the MCP Streamable HTTP transport, where a response may
be a single JSON body or a text/event-stream, and a long-lived GET carries
server→client notifications.
connect_tcp is intentionally unguarded: agentd’s HTTP client only ever
dials the operator-configured intelligence endpoint, which the model
cannot influence. The SSRF classifier (net::ssrf) exists for any future
model/agent-supplied URL surface and is composed at the call site that
needs it.
Structs§
- Response
- A parsed HTTP response.
- SseEvent
- One parsed SSE event (RFC 6455-style
text/event-stream). For MCP,datais a JSON-RPC message;event/idare the optional SSE field lines. - SseReader
- A blocking, line-based SSE reader.
next_eventaccumulatesfield: valuelines and emits oneSseEventper blank-line separator (multipledata:lines join with\n), returningOk(None)at end of stream. Bounded per event byMAX_RESPONSEso a hostile stream cannot exhaust memory. - Streaming
Response - A streamed response: status + headers, plus the reader positioned at the body.
The caller decides how to drain it — [
into_body] to buffer (application/json) or [sse] to pump it as an SSE event stream (text/event-stream). Owns the underlying stream, matching the MCP client’s per-request connection model. - Url
- A parsed absolute URL (the subset we need: scheme/host/port/path).
Constants§
- MAX_
RESPONSE - Response body cap. LLM responses can be large; 8 MiB is generous without being an unbounded allocation from a hostile peer.
Traits§
- Stream
- Any bidirectional byte stream the HTTP client can run over.
Box<dyn Stream>is itselfRead + Write(via std’simpl<R: Read + ?Sized> Read for Box<R>), so an OWNED boxed stream can be handed tosend_streamingby value — used by the long-lived MCP notification SSE reader.
Functions§
- connect_
tcp - Connect a plain TCP stream with connect + read/write timeouts. Intentionally
unguarded — the only caller dials the operator-configured endpoint; the SSRF
classifier (
net::ssrf) is composed at any model/agent-supplied URL surface. - is_
loopback_ host - Whether
hostnames the local loopback — the dev/test carve-out for plaintexthttp://(production transports are TLS-only). Accepts the IPv4 loopback block (127.0.0.0/8), the IPv6 loopback (::1, bare or bracketed), and the literal namelocalhost. A resolvable-but-unresolved name is NOT loopback — this classifies the written form, without DNS. - send
- Issue one request over
streamand read the full response. AddsHost,Connection: close, andContent-Length; the caller supplies any other headers (e.g.Authorization,Content-Type). - send_
streaming - Issue one request over an OWNED
streamand return the status + headers + body reader WITHOUT draining the body (unlikesend). AddsHost,Connection: close, andContent-Length; the caller supplies the rest (Accept,Authorization,Content-Type,Mcp-Session-Id, …).