# 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.