zenwave 0.7.1

Ergonomic HTTP client framework.
Documentation
# Zenwave

Async HTTP client library for Rust. Single crate, multiple backends
(Hyper, libcurl, Apple URLSession, browser Fetch), same API surface.

## Build and test

Requires nightly Rust (edition 2024).

```sh
# Default backend (hyper + rustls)
cargo check
cargo test

# Specific backend / TLS engine
cargo test --no-default-features --features curl-backend
cargo test --no-default-features --features hyper-backend,rustls,ws
cargo test --no-default-features --features hyper-backend,native-tls,ws
cargo test --no-default-features --features apple-backend  # macOS only

# Clippy (treat warnings as errors, matches CI)
cargo clippy --all-targets --all-features -- -D warnings

# WASM build check
cargo build --target wasm32-unknown-unknown
```

## Project layout

```
src/
  lib.rs          — public API, re-exports, compile-time feature checks
  client.rs       — Client trait, RequestBuilder, middleware composition
  client/
    download.rs   — resumable file downloads (native only)
  backend/
    mod.rs        — DefaultBackend type alias based on features
    hyper/
      mod.rs      — Hyper + async-net backend; ALPN picks h1 or h2 per connection
      rt.rs       — hyper::rt::Executor/Timer over the backend spawner + async-io
      h3.rs       — HTTP/3 connection over QUIC (h3 + h3-quinn; http3 feature)
      alt_svc.rs  — RFC 7838 Alt-Svc parsing and the per-origin h3 advertisement
      test_support.rs — shared test fixtures: throwaway CA, TLS and h3 servers
    curl.rs       — libcurl backend
    apple.rs      — URLSession backend (Apple platforms)
    web.rs        — Fetch API backend (wasm32)
  transport/
    mod.rs        — Transport / TransportBuilder (proxy rules + trusted roots; all targets)
    proxy.rs      — Proxy / ProxyBuilder over hyper-util's matcher (env + OS settings)
    tls.rs        — TLS engine: rustls + rustls-platform-verifier, or native-tls (one config per ALPN offer)
    native_tls_stream.rs — in-tree futures-io adapter for native-tls (ALPN access)
    stream.rs     — Stream (TCP / TLS / TLS-in-TLS)
    hyper_io.rs   — futures-io → hyper::rt adapter (also included by the hyper test server)
    connect.rs    — connect(transport, target): direct, HTTP proxy, CONNECT tunnel, SOCKS5
    tunnel.rs     — HTTP CONNECT through hyper's upgrade machinery
    socks5.rs     — SOCKS5 CONNECT client (RFC 1928/1929)
    happy_eyeballs.rs — RFC 8305 TCP connection racing
    pool.rs       — per-origin connection pool for the hyper backend (h1 leases, shared h2, dial coalescing)
    dns.rs        — HTTPS/SVCB record lookup for HTTP/3 discovery (RFC 9460)
    dns/runtime.rs — hickory RuntimeProvider on async-io/async-net
    dns/android.rs — android.net.DnsResolver.rawQuery over JNI
    quic.rs       — quinn::Runtime on async-io, shared QUIC endpoint (http3 feature)
    android.rs    — hands the JVM from ndk-context to the platform verifier
  ext.rs          — ResponseExt trait (into_json, into_string, etc.)
  cache.rs        — HTTP caching middleware (Cache-Control, ETag)
  cookie.rs       — cookie jar middleware (in-memory and persistent)
  oauth2.rs       — OAuth2 client credentials middleware
  auth.rs         — Bearer and Basic auth middleware
  redirect.rs     — redirect-following middleware (on by default)
  retry.rs        — retry middleware
  timeout.rs      — per-request timeout middleware
  websocket.rs    — cross-platform WebSocket client
  multipart.rs    — multipart/form-data
  error.rs        — error types
tests/
  common/
    fixture.rs    — local httpbin fixture: hyper server, thread-per-connection,
                    CORS on every response; shared by the native suites and the
                    standalone binary (kept free of `crate::` paths)
  fixture-server/ — zenwave-test-fixture: standalone binary serving the fixture
                    for the wasm and workerd lanes (own workspace, not a member)
```

## Architecture

Everything is middleware. `Client` is a trait extending `http_kit::Endpoint`.
Each middleware wraps the inner client and transforms requests/responses.
`zenwave::client()` returns a `DefaultClient` which is just the platform
backend over `Transport::system()` wrapped in `FollowRedirect`;
`zenwave::client_with(transport)` does the same over an explicit `Transport`. Backends are constructed from a
`Transport` (trusted roots, TLS engine); `Transport::system()` is built once
per process. The hyper backend's connections are pooled per origin on the
`Transport` (`transport/pool.rs`), so clients sharing one transport reuse
them. `cfg` aliases (`native`, `tls_rustls`, `tls_native`,
`tls_engine`, `connector`, `android_verifier`) come from `build.rs`.

The `http-kit` crate (separate dependency) defines `Endpoint`, `Middleware`,
`Request`, `Response`, `Body`, and SSE types.

## Branching

- `main` — release branch, release-plz creates PRs into it
- `dev` — development branch, PRs go here

## Release

Automated via release-plz. Do not hand-edit version numbers or CHANGELOG.md.
Write conventional commits (`feat:`, `fix:`, `feat!:` for breaking) and
release-plz computes the bump and opens a PR to main.

## CI

Runs on every push and PR (`.github/workflows/ci.yml` + `test.yml`):
- `cargo fmt --check`
- Features: clippy over every valid feature combination (`scripts/check-features.sh`,
  cargo-hack powerset) on Linux, Windows and macOS, one slice per TLS engine
- WASM build check; mobile cross-compilation (iOS device/simulator, Android
  arm64/x86_64/armv7) with tests
- Tests: hyper (rustls and native-tls) and curl on Linux/Windows/macOS,
  apple-backend on macOS, the suite on an iOS simulator (`scripts/test-ios.sh`,
  `simctl spawn`), wasm-pack in Chrome/Firefox/Safari, workerd
- Android runs on a physical device, not in CI: `scripts/test-android.sh`
  over adb (never an emulator); TLS on Android needs the JVM and is covered by
  the instrumented app under `tests/android`