rightkit-http
Shared blocking HTTP client for Right Suite applications. It provides timeouts, bounded bodies, retry and backoff that honours Retry-After (never retrying unsafe methods), streaming responses, WHATWG Server-Sent Events decoding, redacted secrets, and tamper-evident wrapping of untrusted web text before it reaches a model.
Catalog capability: http-client. Published to crates.io (see INDEX.md).
What it owns
Client,ClientConfig,Request,Response,StreamResponse: timeouts, bounded bodies, redirect policy, streaming reads, andget_json.RetryPolicy: retry and backoff. Retries respectRetry-After. Non-idempotent methods are not retried.sse:SseDecoder,SseReader,SseEvent. WHATWG-compliant Server-Sent Events.untrusted:wrap_untrusted_web_textfor external text, with boundary markers and injection-signal reporting.secret: a redactedSecret, and theSecretStoretrait thatrightkit-secretsimplements.MemorySecretStoreis provided for tests.testing(feature): an in-process mock server that records exact requests.
When to use it
- Use it for blocking HTTP calls from Right Suite apps where timeouts, retries and bounded bodies must be consistent.
- Use it for SSE streams and for wrapping web text before model input.
Do not use it for async code. The client is blocking. It is built on ureq with rustls.
Cargo features
| Feature | Default | Pulls in | Enables |
|---|---|---|---|
gzip |
yes | ureq/gzip |
Automatic Accept-Encoding: gzip and transparent decoding for buffered responses and stream readers. Matches ureq's default. |
testing |
no | none | The testing module: MockServer, MockResponse, MockBody, RecordedRequest. |
To opt out of gzip:
= { = "<exact published version from INDEX.md>", = false }
Usage
Client configuration, from the crate README. Every field below exists in ClientConfig:
use Duration;
use ;
let client = new;
Request shape, from tests/e2e.rs: Request::post(url).bearer(token).json(&value)? then client.send(&req)?.
Timeouts
connect_timeoutandresponse_timeoutareOption<Duration>. The defaults areSome(10 s)for connect andSome(60 s)for response headers. UseNoneto disable a per-phase deadline. Disabling phase deadlines does not disable global deadlines.- Buffered calls use
request_timeout(60 s by default). Streams usestream_timeout(Noneby default). recv_body_timeoutdefaults toNone. When set, it limits total body-receive time after headers arrive. Progress does not reset it.- Buffered body timeouts return
HttpError::Timeout. Stream readers keep the underlyingstd::io::Error. Body reads are never retried. - Callers that passed bare durations to
connect_timeoutorresponse_timeoutmust wrap them inSome(...). The change is recorded in CHANGELOG.md.
Redirects
max_redirectsdefaults to 0, so redirects are not followed. With 0, a 3xx response is always returned, whatever the error policy.max_redirects_will_errordefaults totrue, matching ureq. When a nonzero limit is exhausted, the call returnsHttpError::Transport { connect_phase: false, .. }. That error is eligible for idempotent retries under the retry policy.- Set it to
falseto receive the final 3xx throughsend_any.
Platform support
Pure Rust over ureq with rustls. No platform-specific code in the crate. Certificate and TLS behaviour follows rustls.
Tests
tests/e2e.rs: a real local TCP server. Assertions use exact requests seen on the wire and exact bytes received.
Version and changes
Published version: see INDEX.md. Version history: CHANGELOG.md.