xocomil 0.1.0

A lightweight, zero-allocation HTTP/1.1 request parser and response writer
Documentation
# xocomil

A lightweight, zero-allocation HTTP/1.1 request parser and response writer for Rust.

Xocomil parses requests by borrowing directly from the caller's read buffer and
serializes response headers to a stack buffer -- no heap allocations on the hot
path. Designed for use in embedded servers, proxies, and anywhere allocation
discipline matters.

## Features

- **Zero-copy parsing** -- request method, path, and headers borrow from your buffer
- **Zero heap allocations** -- parsing and response writing stay on the stack
- **O(1) header lookup** -- known headers (Host, Content-Type, etc.) use a compile-time slot table
- **SIMD-accelerated validation** -- SSE2/AVX2 character class checks where available, with scalar fallback
- **Streaming body support** -- pipe chunked or content-length bodies from a `BufRead` to any `Write`
- **In-place chunked decoding** -- decode Transfer-Encoding: chunked without extra buffers
- **Compile-time tuning** -- const generics control max headers, body limits, and buffer sizes
- **Hardened** -- rejects request smuggling vectors (duplicate Content-Length, conflicting TE+CL, CRLF injection)

## Quick start

```rust
use xocomil::request::Request;
use xocomil::headers::RequestHeader;

let raw = b"GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n";
let req = Request::<32>::parse(raw).unwrap();

assert_eq!(req.path(), b"/index.html");
assert_eq!(req.header(RequestHeader::Host), Some(&b"example.com"[..]));
```

## Writing responses

```rust
use xocomil::headers::{StatusCode, ResponseHeader};
use xocomil::response::Response;

let mut output = Vec::new();

Response::<16>::new(StatusCode::Ok)
    .header(ResponseHeader::ContentType, b"text/plain").unwrap()
    .write(&mut output, b"hello")
    .unwrap();
```

## Reading from a stream

```rust
use xocomil::request::Request;

let raw = b"POST / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 5\r\n\r\nhello";
let mut buf = [0u8; 1024];
let rr = Request::<32>::read(&mut &raw[..], &mut buf).unwrap();

let mut body = Vec::new();
rr.stream_body_to(&mut &b""[..], &mut body).unwrap();
assert_eq!(body, b"hello");
```

## Unsupported methods

CONNECT and TRACE are intentionally omitted:

- **TRACE** enables cross-site tracing (XST) attacks
- **CONNECT** changes connection semantics (proxy tunneling) and is out of scope for a request parser

## Minimum Supported Rust Version

Rust 1.85 (edition 2024).

## License

MIT -- see [LICENSE](LICENSE) for details.