net-cat 0.2.0

Minimal hand-rolled HTTP/1.1 client over std::net::TcpStream. Plain HTTP in v0; v0.2.0 adds an optional `tls` feature that wires rustls + webpki-roots Mozilla CA bundle so `https://` URLs work via the same `fetch` / `exchange` entry points. No external HTTP crate; framing and parsing are local. No `mut` beyond FFI carve-outs (`TcpStream::read_to_end`, rustls `Stream::new(&mut conn, &mut sock)`). Sixth sub-crate of a Servo-replacement webview runtime targeting Tauri.
# CLAUDE.md -- Rust Project Conventions

## Philosophy

Functional, type-driven, domain-driven.

## Architecture

- Modules by domain context.
- One module per concern (method, headers, url, request, response, transport, fetch).
- Thin lib.rs that exposes `fetch(request)`.

## Types

- Newtypes for `Method`, `StatusCode`.
- Sum types for `HeaderName`, `Error`.
- No public struct fields.
- `#[must_use]` on getters.

## Error Handling

- Single project-wide `Error` enum.
- Display + std::error::Error impls by hand; no thiserror, no anyhow.
- Never panic.

## Style

- Prefer match over if/else, except on bool.
- No `return` keyword.
- No `mut` (exceptions: `TcpStream::read_to_end`, `RootCertStore::extend`, and `rustls::Stream::new(&mut conn, &mut sock)` -- all FFI boundaries with `&mut self`-taking APIs).
- Combinators over loops.
- Never match on Option<_>; use combinators.
- No unwrap()/expect() anywhere.
- No loop or for.
- No scan.
- No Rc/Arc.
- No naked `as` casts.
- Exhaustive matches; no `_` wildcard arm on enums.

## Traits

- No dyn Trait.
- Implement standard traits over ad-hoc methods.

## Linting

```toml
[lints.clippy]
all = { level = "deny", priority = -1 }
pedantic = { level = "warn", priority = -1 }
needless_pass_by_value = "warn"
manual_map = "warn"
```

## Verification

- Always run `RUSTFLAGS="-D warnings" cargo clippy --all-targets`.
- Always run `cargo fmt`.

## Testing

- Tests return `Result<(), Error>` and propagate failures with `?`.
- No assert!, no `assert_eq!`, no panic!, no `unreachable!`, no unwrap, no expect.
- All tests are offline parser / type tests (no network requests in CI).

## Dependencies

- Default build has no runtime dependencies.  All HTTP/1.1 framing is local.
- `tls` feature pulls `rustls = "0.23"` (with `std` + `ring` + `tls12` features only, no C toolchain) and `webpki-roots = "0.26"` (Mozilla CA bundle).
- `proptest` dev-dep.
- No path dependencies.

## Documentation

- `///` doc comments on every public item.
- `# Examples` with runnable code blocks (offline-safe).

## Layer context

This crate is the **network** in the Servo-replacement webview stack:

1. `html-cat`, `css-cat`, `dom-cat`, `layout-cat`, `paint-cat` -- rendering pipeline.
2. **`net-cat`** -- HTTP/1.1 client.
3. `web-api-cat` -- bindings between boa-cat Values and DOM / fetch.
4. `tauri-runtime-servocat` -- meta-crate.

## v0.2 scope (current)

- `Method` (`GET`/`POST`/`PUT`/`DELETE`/`HEAD`/`OPTIONS`/`PATCH`).
- `Url` parser for `http://host[:port]/path?query` and `https://...` (port defaults to 443 on `https`).
- `Headers` (case-insensitive name lookup, ordered list).
- `Request` and `Response` types with status, headers, body bytes.
- `fetch(request)` connects via TCP, writes the request, reads until EOF (`Connection: close` forced), parses the response.
- Automatic `Host`, `User-Agent`, and `Content-Length` headers.
- v0.2.0 adds an optional `tls` feature.  When on, `https://` URLs go through `crate::tls::exchange_https` which:
  - opens a `TcpStream` to `host:port`
  - installs the `ring` crypto provider as rustls' default (idempotent across calls)
  - builds a `ClientConfig` whose root store is the webpki-roots Mozilla CA bundle
  - wraps the socket in `rustls::Stream` and writes/reads via `Write` / `Read`
  - returns a `Tls { message }` error variant on handshake / IO failure
  When off, `https://` URLs continue to return `Error::UnsupportedScheme { scheme: "https" }` for backward compatibility.
- Offline tests cover both branches: `https_without_tls_feature_is_unsupported` (no-feature build) and `tls_client_config_builds_without_panic` + `unknown_scheme_is_unsupported_under_tls` (feature build).  No CI network access required.

## Deferred to v0.3+

- Connection keep-alive / pooling.
- Chunked transfer encoding (we rely on `Connection: close` + read-to-EOF).
- Redirects.
- Cookies.
- Streaming bodies.
- Async (this is a synchronous client).
- Client certificates / mutual TLS.
- SNI overrides + custom roots (the v0.2 path uses webpki-roots + the URL host as SNI).