Skip to content

A Rust Windows HTTP Client, API-compatible with reqwest

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

talagrand/wrest

Repository files navigation

wrest

wrest

Windows-native async HTTP client with a reqwest-compatible API.

CI codecov Crates.io Documentation

wrest is a drop-in replacement for the async API of reqwest that uses the operating system's built-in HTTP stack (WinHTTP) instead of bundling its own and does not depend on the tokio executor. TLS, proxy resolution, authentication, content-encoding, and more are all handled by Windows.

Why

reqwest is a battle-tested cross-platform HTTP client built on top of tokio. wrest takes a different approach: instead of linking a TLS library and driving sockets from user space, it delegates the entire HTTP stack to the OS, acting as a thin ergonomic API surface on top of OS primitives.

reqwest wrest
HTTP stack hyper (user-space) WinHTTP (OS-provided)
TLS User-space or SChannel SChannel -- always the OS certificate store
Proxy Env vars + limited OS proxy settings Env vars + All OS proxy settings
Async runtime Requires tokio Executor-agnostic -- any runtime or block_on
Binary size hyper, h2, ... Thin FFI layer over a system DLL

If your application targets Windows and you want the platform's native networking -- the same stack used by Windows itself -- wrest lets you do that without giving up the ergonomic reqwest API your code already uses.

Quick start

// The API is intentionally identical to reqwest.
use wrest::Client;

let client = Client::builder()
    .timeout(std::time::Duration::from_secs(30))
    .build()?;

let body = client
    .get("https://httpbin.org/get")
    .header("x-custom", "value")
    .send()
    .await?
    .text()
    .await?;

println!("{body}");

Executor-agnostic

wrest returns standard Futures with no hidden dependency on tokio, async-std, or any other runtime. Use it with whichever executor you prefer:

// tokio
tokio::runtime::Runtime::new()?.block_on(do_request());

// futures
futures::executor::block_on(do_request());

// smol
smol::block_on(do_request());

Cross-platform & A/B testing

On non-Windows platforms (Linux, macOS, etc.) wrest is a thin passthrough to reqwest -- every call forwards directly, so the same code compiles everywhere.

To force the reqwest path on Windows -- for example, to A/B test against the native WinHTTP path -- enable the always-reqwest feature:

wrest = { version = "0.5", features = ["always-reqwest"] }

Feature flags like json, gzip, stream, etc. forward to the corresponding reqwest features automatically. Use default-features = false to strip wrest and reqwest to their bare minimum, then re-add only what you need.

Features

Feature Default Description
charset Yes Improved text decoding. Native path has all 39 WHATWG encodings built-in (three rare ones -- ISO-8859-10 (Latin-6 / Nordic), ISO-8859-14 (Latin-8 / Celtic), EUC-JP (Extended Unix Code for Japanese) -- need Windows 10 1903+); forwards to reqwest/charset on the reqwest path
http2 Yes HTTP/2 support. WinHTTP negotiates via ALPN automatically; forwards to reqwest/http2
default-tls Yes TLS via the OS stack (SChannel). Always-on natively; forwards to reqwest/default-tls
native-tls No Explicit OS-native TLS selection. No-op natively (SChannel is always used); forwards to reqwest/native-tls
system-proxy Yes Automatic system proxy detection. WinHTTP uses WPAD/PAC natively; forwards to reqwest/system-proxy
json No RequestBuilder::json() and Response::json() (adds serde, serde_json)
form No RequestBuilder::form() (adds serde, form_urlencoded)
query No RequestBuilder::query() (adds serde, form_urlencoded)
gzip No ClientBuilder::gzip() no-op toggle (WinHTTP always decompresses gzip); forwards to reqwest/gzip
deflate No ClientBuilder::deflate() no-op toggle; forwards to reqwest/deflate
brotli No ClientBuilder::brotli() no-op toggle; forwards to reqwest/brotli
zstd No ClientBuilder::zstd() no-op toggle; forwards to reqwest/zstd
stream No Stream-based body support. Always available natively; forwards to reqwest/stream
tracing No Emit diagnostics via the tracing crate -- request lifecycle, proxy resolution, charset decoding, and more
noop-compat No Enables ~31 no-op reqwest stubs (connection pool, TCP options, HTTP/2 tuning, TLS backend selection, etc.) so reqwest-targeting code compiles without changes. Compression toggles require both this and the respective feature
panicking-compat No Client::new() and impl Default for Client (these panic on failure -- prefer Client::builder().build())
always-reqwest No Forces the reqwest path even on Windows -- see Cross-platform & A/B testing

Bold feature names are unique to wrest (not present in reqwest).

Limitations

wrest covers the core reqwest API surface (~75 methods). A few reqwest features are not available because WinHTTP handles them internally or they haven't been added yet:

  • No blocking API -- async only
  • No cookies, multipart, retry, or WebSocket -- not yet implemented
  • No custom DNS or TLS configuration -- WinHTTP uses SChannel and the OS certificate store (danger_accept_invalid_certs is supported)
  • No SOCKS proxies -- WinHTTP only supports HTTP CONNECT
  • Redirects -- Policy::limited() and Policy::none() only; Policy::custom() is not available
  • Decompression -- gzip/deflate always-on; brotli/zstd not available natively
  • remote_addr() always returns None
  • Charset decoding -- three rare encodings (ISO-8859-10 (Latin-6 / Nordic), ISO-8859-14 (Latin-8 / Celtic), EUC-JP (Extended Unix Code for Japanese)) require Windows 10 1903+ (icu.dll)

~31 additional reqwest builder stubs (pool tuning, TCP options, HTTP/2 knobs, etc.) are available as silent no-ops under the noop-compat feature.

For a full API-by-API comparison, see docs/reqwest-parity.md.

Minimum supported Rust version

Rust 1.90.

License

Licensed under either of Apache License, Version 2.0 or MIT License at your option.

About

A Rust Windows HTTP Client, API-compatible with reqwest

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Languages