netune-http1 0.0.1

HTTP/1.1 codec: owned request/response framing, differential-tested against hyper
Documentation
# netune

An owned, observable, and *intervention-capable* network stack in Rust.

netune owns every layer from DNS to the HTTP/1.1 message — no third-party HTTP
implementation in the production dependency graph — and makes the transport
itself an object you can inspect, fingerprint, and change:

| Crate | What it is |
|---|---|
| [`netune-trace`] | The trace model and pure derivations. Every timing a surface shows is a pure function of a recorded trace. Also: TLS ClientHello parsing and JA3/JA4 fingerprints. |
| [`netune-http1`] | The HTTP/1.1 codec. Differential-tested against hyper (dev-dependency only) over recorded byte streams. |
| [`netune-http2`] | HTTP/2 wire protocol placeholder and design reservation (ADR-0003). Reserved at 0.0.1; no I/O implementation. |
| [`netune-ws`] | Pure RFC 6455 WebSocket codec: role-enforced masking, fragmented-message reassembly, SHA-1 handshake keys. No I/O runtime. |
| [`netune`] | The transport: DNS, TCP, TLS (rustls), the syscall tap (`TimedIo`), connection pool (`Pool`), TLS fingerprint presets and routing (`TlsProfile`, `Preset`), proxies (HTTP CONNECT & SOCKS5), redirects, decompression, client WebSocket upgrade (`connect_ws`), stale-socket absorption — and `FaultIo`, the chaos twin that injects delays, splits, truncations, and resets. |
| [`netune-probe`] | The L2 probe: pure Ethernet/IPv4/TCP parse **and build** (forge) plus an opt-in `inject` feature for frame transmission. |

## Capability surface

**Observe** — a three-level tap with graceful degradation:

- **L0** protocol events, portable, always on
- **L1** syscall boundaries (`TimedIo`) + `TCP_INFO` sampling (RTT, retransmits, cwnd)
- **L2** per-segment capture (Linux, `CAP_NET_RAW`, opt-in)

**Fingerprint** — inspect and configure TLS identity:

- Pure wire parser: `netune-trace::ja4` parses ClientHello bytes and computes the JA4 fingerprint, cross-tool anchored against FoxIO's published test vectors.
- Profile presets: named presets (`netune-default`, `codex-reqwest`, `codex-network-proxy`) configure ALPN, protocol versions, ciphers, and key-exchange groups.
- Per-request selection: `Target::with_tls_profile` picks the identity at request time; unknown profile names fail loudly.
- Pool isolation: connection pool keys on `authority#profile`, preventing connection reuse across disparate TLS identities.

**Intervene** — change behaviour at two privilege levels:

- **In-process, zero privileges** (`netune::FaultIo`): script delays, split reads, truncations, and connection resets against any stream to test retry policies and streaming pipelines hermetically.
- **On the wire, feature-gated** (`netune-probe` with `--features inject`): build arbitrary TCP frames (forged seq/ack, RSTs, window games) with pure, fully tested functions; transmit them only when the feature is compiled in *and* `CAP_NET_RAW` is held. The default build has no transmit path at all.

**Resilience** — culled keep-alive absorption:

- Shortened idle pool bound (20 s) prevents handing out connections about to be culled by intermediate gateways.
- Transparent single retry on stale pooled sockets before receiving a response head (`INV-TRANSPORT-01`), eliminating spurious keep-alive failures without request replay hazard.
- Precise error classification (`HttpError::Incomplete`) distinguishing peer socket closure from protocol smuggling or violations.

## The privilege boundary is structural

```
                 default build      --features inject + CAP_NET_RAW
parse/build      ✅ present         ✅ present        (pure, tested)
transmit         ❌ not compiled    ✅ present        (socket)
```

Injection changes the network rather than measuring it; it is never a default
capability of anything long-running.

## Quick Start

### Build and Test

```bash
# Run unit and integration tests across all workspace crates
cargo test

# Run tests with nextest
cargo nextest run
```

### Basic Request & Trace Inspection

```rust
use http::Method;
use netune::{Client, ClientConfig, Pool, RequestHead, Target, TcpConnector};
use netune_trace::{Recorder, derive};
use std::sync::{Arc, Mutex};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(TcpConnector, Pool::default(), ClientConfig::default());
    let target = Target::http("127.0.0.1", 8080);
    let head = RequestHead::new(Method::GET, "/health");
    let recorder = Arc::new(Mutex::new(Recorder::new(1024)));

    let mut response = client.send(target, head, recorder.clone()).await?;
    let body = response.body().read_to_end(64 * 1024).await?;
    println!("Status: {}, Body len: {}", response.status(), body.len());

    // Inspect derived microsecond timings from the recorded trace
    let trace = recorder.lock().unwrap().take();
    let timings = derive(&trace);
    println!("TTFB: {:?} µs", timings.ttfb_us);
    Ok(())
}
```

## Documentation Map

- **Tutorials**: [Getting Started]docs/tutorials/getting-started.md
- **How-To Guides**:
  - [Configure TLS Profiles and Fingerprints]docs/how-to/configure-tls-profiles.md
  - [Simulate Network Chaos with FaultIo]docs/how-to/fault-injection.md
  - [Configure Proxies]docs/how-to/configure-proxies.md
- **Reference**:
  - [Crates Reference]docs/reference/crates.md
  - [System Architecture]docs/reference/architecture.md
  - [WebSocket Client Usage]docs/how-to/websocket-client.md
- **Explanation**:
  - [Structural Privilege Boundaries]docs/explanation/privilege-boundaries.md
- **Architecture Decisions**: [ADR Registry]docs/adr/index.md
- **Contributing**: [Contributor Guide]CONTRIBUTING.md

## Status

Pre-1.0. Every workspace crate is lockstep-versioned at `0.0.1`, except
`netune-http2`, which ships at `0.0.2` because the registry's `0.0.1` slot is
held by its earlier name-reservation stub.

MSRV: 1.95. License: MIT.

[`netune-trace`]: crates/netune-trace
[`netune-http1`]: crates/netune-http1
[`netune-http2`]: crates/netune-http2
[`netune-ws`]: crates/netune-ws
[`netune`]: crates/netune
[`netune-probe`]: crates/netune-probe