Skip to main content

Crate barehttp

Crate barehttp 

Source
Expand description

§barehttp

Blocking HTTP/1.1 client for no_std + alloc. Cleartext HTTP; no async. Design notes: philosophy.md.

MSRV: Rust 1.90 (rust-version in Cargo.toml; const APIs, ruzstd, and gungraun/bincode-next when building benches).

https:// needs config::Config::assume_tls_socket and a BlockingSocket that terminates TLS. OsBlockingSocket is TCP only. Pairing it with assume_tls_socket returns Error::TlsNotConfigured.

fn main() -> Result<(), barehttp::Error> {
    let response = barehttp::get("http://example.com").call()?;
    println!("{} {}", response.status_code(), response.to_text()?);
    Ok(())
}

§Naming

Primary names:

RolePrimaryCompatibility alias
ClientHttpClientAgent (= HttpClient<OsBlockingSocket, OsDnsResolver>)
Request builderClientRequestBuilderRequestBuilder (same OS adapters)
Cookie store (cookie-jar)cookie_jar::CookieStorecookie_jar::CookieJar
Status / bodyResponse::status_code, Response::bodydeprecated Response::status / Response::as_bytes

Agent / RequestBuilder / cookie_jar::CookieJar are documented ureq-like synonyms and are not deprecated. Prefer the primary names in new code. README and examples use primaries only.

agent builds a default-OS HttpClient. Free functions (get, post, …) return a builder; finish with ClientRequestBuilder::call or ClientRequestBuilder::send:

let response = barehttp::get("http://example.com").call()?;
let response = barehttp::post("http://example.com/api").send(b"{}")?;

§Module layout

Hot types live at the crate root (HttpClient, Response, Error, Headers, …). Optional / larger surfaces stay in modules: config, request_builder, and (feature-gated) cookie_jar / gzip. The half-nesting is intentional.

§Intentional limits

  • Buffered response bodies (no streaming Read body API).
  • Blocking I/O only (no async runtime).
  • Public body accessors use &[u8] / Vec<u8> / String only (core / alloc).

§Features

  • Custom BlockingSocket / DnsResolver (connect gets the hostname for SNI)
  • Connection pooling (Config::max_idle_per_host default 3; 0 disables; max_idle_age default 15s)
  • Response body size limit (Config::max_response_body_size, default ~10 MiB)
  • Optional Cargo features: gzip exposes barehttp::gzip (hand-rolled RFC 1951/1952); zstd is Accept-Encoding + decode only; cookie-jar gates the cookie module
  • Runtime deps (always on, kept out of the public API): bytes (internal body / wire buffers), phf (well-known header name map), compact_str (SSO header strings), hashbrown (header side-index / pool). Platform: libc / windows-sys.
  • Request builder: .form / .body then .call(), or .send(bytes); per-request .timeout_read / .timeout_write / .timeout_connect

See CHANGELOG.md for release notes.

§Examples

All examples use cleartext HTTP (http:// only):

cargo run --example basic                    # GET http://example.com
cargo run --example agent                    # shared client, headers + query
cargo run --example custom_adapters          # logging DnsResolver + BlockingSocket over the OS stack
cargo run --example gzip --features gzip     # http://httpbingo.org/gzip
cargo run --example cookies --features cookie-jar        # httpbingo/postman-echo cookie endpoints

§TLS / HTTPS

barehttp does not implement TLS. For https://:

  1. Use a BlockingSocket whose connect / read / write speak TLS (or wrap one that does). connect receives the URI hostname for SNI.
  2. Set assume_tls_socket on config::Config so the client accepts https. Without that flag you get Error::TlsNotConfigured.
use barehttp::config::Config;
use barehttp::HttpClient;

let config = Config::builder()
    .assume_tls_socket(true)
    .build();
// Pair with a TLS-capable BlockingSocket. OsBlockingSocket is cleartext
// and rejects this config.
let client = HttpClient::<MyTlsSocket, _>::with_adapters(my_dns, config);

§Config

use barehttp::config::Config;
use barehttp::HttpClient;
use core::time::Duration;

let config = Config::builder()
    .timeout_read(Some(Duration::from_secs(30)))
    .timeout_write(Some(Duration::from_secs(30)))
    .max_redirects(5)
    .user_agent("my-app/1.0")
    .build();

let client = HttpClient::with_config(config);

§Custom adapters

use barehttp::config::Config;
use barehttp::{HttpClient, OsBlockingSocket};

let client: HttpClient<OsBlockingSocket, _> =
    HttpClient::with_adapters(my_dns, Config::default());

See examples/custom_adapters.rs for logging wrappers around OsDnsResolver / OsBlockingSocket.

§Testing

Use cargo-nextest:

cargo install cargo-nextest --locked
cargo nextest run --all-features

CI runs nextest on push and pull requests. Details in CONTRIBUTING.md; fuzz targets in fuzz/README.md.

§License

MIT OR Apache-2.0. Changes: CHANGELOG.md.

Re-exports§

pub use request_builder::ClientRequestBuilder;

Modules§

config
Client configuration (config::Config, config::ConfigBuilder).
cookie_jar
RFC 10025 cookie store (CookieStore; alias CookieJar).
gzip
Gzip / zlib / raw DEFLATE decompression (RFC 1950–1952). Feature-gated (gzip). Gzip, zlib, and raw DEFLATE decompression (RFC 1950–1952).
request_builder
Request builder (ClientRequestBuilder).

Structs§

Authority
Authority component (host[:port]).
ExtensionMethod
Owned RFC 9110 extension-method token (opaque; not a public CompactString).
HeaderIntoIter
Owning iterator over (name, value) pairs from Headers.
HeaderIter
Iterator over (name, value) pairs in a Headers map.
Headers
Ordered list of (name, value) header fields.
HttpClient
HTTP client. S = socket (BlockingSocketFactory), D = DNS (DnsResolver).
IntoStringError
crate::Response::into_string failed; the full response is preserved for recovery.
OsBlockingSocket
OS blocking TCP socket (BSD sockets).
OsDnsResolver
Operating system DNS resolver (getaddrinfo).
Response
Parsed HTTP response.
Uri
Parsed HTTP URI (absolute-form or origin-form used by the client).
Version
HTTP version (e.g. HTTP/1.1).

Enums§

DecompressError
Errors from gzip/deflate content-coding decompression.
DnsError
DNS lookup failure.
Error
Error from crate::HttpClient and the free get / post / … functions.
Host
Host as an IP literal or registered name.
InvalidRequest
Bad request construction (illegal cookie octets, form fields plus an explicit body, …).
IpAddr
An IP address, either IPv4 or IPv6.
Method
HTTP request method (RFC 9110 method token).
ParseError
HTTP/1.1 message parse failure.
ParseMethodError
Failure from Method::new / Method::from_str / str::parse.
SocketAddr
An internet socket address, either IPv4 or IPv6.
SocketError
Socket I/O failure.
WellKnownHeader
Common header names with a compile-time phf lookup (lowercase keys).

Traits§

BlockingSocket
Blocking byte-stream socket (object-safe).
BlockingSocketFactory
Factory for unbound sockets used by crate::HttpClient.
DnsResolver
Resolve hostnames to IP addresses.

Functions§

agent
Default-OS HttpClient (type alias Agent).
delete
DELETE using a fresh default OS client.
get
GET using a fresh default OS client.
head
HEAD using a fresh default OS client.
patch
PATCH using a fresh default OS client (body via .send()).
post
POST using a fresh default OS client (body via .send()).
put
PUT using a fresh default OS client (body via .send()).
well_known_header
Case-insensitive lookup of a well-known header name (&str).
well_known_header_bytes
Case-insensitive lookup of a well-known header name (raw bytes).

Type Aliases§

Agent
HttpClient with OS adapters (HttpClient<OsBlockingSocket, OsDnsResolver>).
RequestBuilder
ClientRequestBuilder with OS adapters.