Expand description
The HTTP transport seam of allama’s HTTP provider crates.
Provider crates (allama-anthropic, allama-gemini,
allama-openai-compat, allama-openai, allama-systemone) build an
HttpRequest, send it through an HttpTransport, and decode the HttpResponse. Their
request mapping, error classification and decoding never touch an HTTP
client directly, so the transport can be swapped:
ReqwestTransport(featurereqwest, default) is what providers use unless told otherwise.ReplayTransportserves canned responses in memory and records the requests: transport-level fixtures that exercise the whole adapter without a server, on any target.- Custom transports cover other HTTP stacks, proxies, or recording.
This is a seam for provider crates, not middleware for applications: it
carries bytes, and the portable allama types stay above it. Beside the
seam, it holds the helpers every provider shares, first-party or not,
starting with the HTTP error helpers:
status_erroris what an error status means on its own, the fallback every provider refines from its error codes and body, so one status means the same on every provider.error_contextreads an error response’s status and headers (request id, retry hint, server retry directive) into anErrorContext.error_envelopereads the common JSON error envelopes and keeps the provider’s text out of the redactedErrorLog(seeErrorEnvelope::apply);error_envelope_valuereads one already parsed.malformed_responseis the error for a success response whose body cannot be decoded.Headers::retry_afterreads retry hints.TransportError::into_errormaps a request that got no response, andTransportError::into_stream_errora streamed response whose body could not be read to the end.
And the streaming helpers of every streaming adapter. A framer turns a
response body into frames, in linear time and under a size cap (the
provider builder’s max_stream_event_size):
SseStream into SSE events, in sse, and
NdjsonStream into NDJSON lines, in ndjson.
Whatever the framing, FramedChatStream
drives an adapter’s ChatFrameDecoder over
the frames (SseChatStream is its SSE form), and
VendorFrames surfaces the frames an adapter
does not model, in framing.
It also defines the caller’s per-request transport options,
HttpRequestOptions (headers and Credentials, under the shared
OPTIONS_NAMESPACE), which every adapter applies with
HttpRequest::apply_options and its own CredentialSlot: a
credential is addressed to a credential scope, and only the adapter with
that scope sends it.
§Trace context propagation
allama-http sends no trace context of its own, and depends on no
OpenTelemetry crate. To continue the application’s trace in a gateway
that joins distributed traces (LiteLLM proxy, vLLM, an instrumented
internal gateway), wrap the transport in an HttpTransport that
injects the current span’s W3C traceparent into
HttpRequest::headers before it sends, with the application’s own
OpenTelemetry version. Adapters call HttpRequest::apply_options
before send, so the wrapper sees the final
headers and can keep a traceparent the caller set. The
observability guide
has the recipe, for provider builders and for the provider registry.
§Timeouts
Every layer bounds a different phase, and each one can be turned off:
| Bound | Where | Default | Disable |
|---|---|---|---|
| Connect (TCP + TLS) | ReqwestTransport::new | DEFAULT_CONNECT_TIMEOUT (not on wasm32) | pass your own client to ReqwestTransport::from_client |
| Whole non-streaming exchange | HttpRequest::timeout, set by the provider | DEFAULT_REQUEST_TIMEOUT in the bundled crates | the provider builder’s timeout |
| Stream headers, gap between stream chunks | StreamTimeouts, applied by the provider | StreamTimeouts::default | the provider builder’s stream_timeouts |
allama::wrappers::TimeoutProvider sits above all of them and bounds
decoded calls and stream events, with the same Error::Timeout shape.
Whichever bound is shorter fires first, so use TimeoutProvider for
tight, workload-specific limits and leave these defaults as the
dead-connection safety net.
§Secrets
The Debug output of Headers (and so of HttpRequest and
HttpResponse) redacts credential headers (see
is_sensitive_header) and every credential
HttpRequest::apply_options placed. Transport errors drop the URL’s
user info, query and fragment, and the bundled providers’ Debug
output shows base URLs through config::redact_url.
§Network defaults
What a broken or hostile endpoint (a tenant-configured gateway, a compromised proxy) can do to the caller is bounded:
- No redirects.
ReqwestTransport::newnever follows one, and the bundled providers report a3xxas anUnexpectedResponsenaming the target host (redirect_error): following it would send the key and the prompt to a host the application never configured. A client you pass toReqwestTransport::from_clientkeeps its own redirect policy; onwasm32, the hostfetch’s applies. - Bounded bodies. Success bodies are read with
HttpResponse::bytes_limitedunder the builder’smax_response_size(DEFAULT_MAX_RESPONSE_SIZE), error bodies withHttpResponse::map_error(at mostMAX_ERROR_BODY_SIZE, withinERROR_BODY_TIMEOUT), and stream events undermax_stream_event_size. A whole stream has no byte cap: its length is the answer’s, which the request bounds withmax_output_tokens, and its duration is bounded by the stream timeouts (StreamTimeouts, andTimeoutProvider::stream_totalin allama). A byte cap would cut off a long answer that is legitimate, mid-stream. To bound what one call may cost, count its usage, or its bytes, in a wrapper around the stream. - Checked configuration.
configrefuses malformed base URLs, keys no header can carry, and credential headers among a builder’s static headers, atbuild().
§Versioning
allama-http names these third-party crates in its public API, so
moving any of them to a new major (minor, before 1.0) version is a
breaking release of allama-http:
bytes1:Bytes, re-exported, carries request and response bodies;futures-core0.3: theBodystream and the framers’ stream bounds;serdeandserde_json1:HttpRequestOptions’ JSON form,ReplayResponse::json_valueand the JSON the error and framing helpers read;reqwest0.13 (featurereqwest):ReqwestTransport::from_client;reqwest-middleware0.5 (featurereqwest-middleware):ReqwestTransport::from_middleware.
The provider crates take a client only as an HttpTransport
(http_transport(ReqwestTransport::from_client(..))), so reqwest
appears in no other public signature.
The allama crates are released together, at one version, for now. So a
breaking release of allama-http is today a breaking release of every
allama crate. That is how 0.1 is released, not a promise about every
later release. The reason is HttpRequestOptions: options are found
by their type, so with allama-http at two versions over one allama,
an adapter built on one version reads a different type than the one
attached with the other. The call fails with
Error::InvalidRequest, naming the
allama-http namespace and both types, instead of sending the
configured key without the tenant’s credential and headers; with one
version for every crate, the same mix is a compile error.
use allama_http::{HttpRequest, HttpTransport, ReplayResponse, ReplayTransport};
let transport = ReplayTransport::new([ReplayResponse::json(200, r#"{"ok":true}"#)]);
let response = transport
.send(HttpRequest::post("https://api.example.com/v1/chat", "{}"))
.await?;
assert_eq!(response.status, 200);
assert_eq!(transport.requests()[0].url, "https://api.example.com/v1/chat");Modules§
- config
- Checking a provider builder’s configuration: base URLs, secrets, and
the headers a provider sends with every request, and how a URL shows in
Debugoutput. - framing
- Streaming for any wire framing: the chat stream driver and vendor frames.
- ndjson
- Newline-delimited JSON (NDJSON) for streaming adapters.
- sse
- Server-sent events (SSE) for streaming adapters.
Structs§
- Bytes
- A cheaply cloneable and sliceable chunk of contiguous memory.
- Credential
- A credential for one request: a typed, redacted secret.
- Credential
Slot - Where an adapter takes its per-request credential from, and where it
puts it: the adapter’s side of a
Credential. - Error
Envelope - The fields of a recognised JSON error envelope (see
error_envelope). - Headers
- HTTP headers, matched case-insensitively and kept in order.
- Http
Request - An HTTP request built by a provider.
- Http
Request Options - Transport options for one request: HTTP headers and credentials to send with it.
- Http
Response - An HTTP response: status and headers, then a streamed body.
- Replay
Response - A canned response served by
ReplayTransport. - Replay
Transport - An
HttpTransportthat serves canned responses in order and records every request. - Reqwest
Transport reqwest - An
HttpTransportbacked byreqwest. - Stream
Timeouts - Time bounds for a streaming request, enforced above the transport.
- Transport
Error - Why a request got no (complete) response.
Enums§
- Credential
Kind - The kind of a
Credential. - Credential
Placement - Where an adapter puts its scope’s
Credential::api_key. - Method
- HTTP method.
- Transport
Error Kind - Kinds of
TransportError.
Constants§
- DEFAULT_
CONNECT_ TIMEOUT reqwest - The connect timeout (TCP and TLS handshake) of
ReqwestTransport::new: 10 s. - DEFAULT_
MAX_ RESPONSE_ SIZE - The default limit on a success response’s body that the bundled
providers read whole (every non-streaming call): 256 MiB. Change it with
the provider builder’s
max_response_size. - DEFAULT_
REQUEST_ TIMEOUT - The bound on a whole non-streaming call that the bundled providers set
on every unary request (
HttpRequest::timeout) unless the builder’stimeoutis set: 120 s, whatever the transport. Onlytimeout(None)removes it. - DEFAULT_
USER_ AGENT - The
User-Agentthe bundled providers send unless the builder’sheader("user-agent", ..)replaces it:allama/<version>. - ERROR_
BODY_ TIMEOUT - How long
HttpResponse::map_errorreads an error response’s body: 30 s. A streaming request has no total deadline, only bounds on the wait for each chunk, so a body that keeps trickling would otherwise hold the call forever. - MAX_
ERROR_ BODY_ SIZE - The most of an error response’s body
HttpResponse::map_errorreads: 64 KiB. An error keeps onlyErrorContext::MAX_BODY_BYTESof it. - OPTIONS_
NAMESPACE - The options namespace of
HttpRequestOptions:"allama-http".
Traits§
- Http
Transport - Sends HTTP requests for a provider.
Functions§
- error_
context - The diagnostic context of an HTTP error response, read from its status and headers:
- error_
envelope - Recognise a JSON error envelope in an error response body or an in-band error event.
- error_
envelope_ value error_envelopeof a body already parsed as JSON, for a caller that parsed it to tell an error from its other frames (an NDJSON line, an SSE event’s data). It recognises the same shapes, listed onerror_envelope.- is_
credential_ header - Returns
truewhennameis a header that carries a credential by definition, so a plain header with that name is refused (seeHttpRequest::apply_options). - is_
sensitive_ header - Returns
truewhen a header namednamelikely carries a credential, so its value must not be logged. - malformed_
response - The error for a success response whose body could not be decoded: an HTML page from a proxy, a truncated body, or JSON of another shape.
- parse_
retry_ after - Parse a retry-after hint from header values.
- redirect_
error - The error for a redirect (
3xx) response, which the bundled providers never follow: anallama::Error::UnexpectedResponsewith the status, the response’serror_context, and an authored message naming the host theLocationheader points to (never its path or query, which may carry tokens). It is not retryable: the server answers the same way again. - status_
error - The error an HTTP error status indicates on its own, before the body is read.
Type Aliases§
- Body
- A response body: a stream of byte chunks.
- Send
Future - A boxed future returned by
HttpTransport::send.