# Changes
## [2.4.0] - 2026-11-12
* Add `Request::path_ascii`, set when the request target is pure ASCII, so
callers can skip UTF-8 validation of the target
* Add `Request::query`, the position of the first `?` of the request target,
found by the same SIMD scan as the target
## [2.3.0] - 2026-10-20
* Use constant-stride AVX2 loops for request targets, header names and values
* Keep response reason scanning vectorized after early obs-text, optimize
the ASCII-check tail, and avoid SIMD handoffs at scalar-prefix delimiters
* On runtime-dispatched AVX2, scan short header values directly with SWAR
* Empty response reason phrases consistently use `0..0`, including when
spaces follow the status code
* Disable `simdutf8`'s default features and forward the `std` feature so
`no_std` builds do not require the standard library
* The benchmark-only `parse_uri` completes at the delimiter space and
validates UTF-8 even when no bytes follow it; URI benchmarks require a
complete result
## [2.2.0] - 2026-09-28
* Header names longer than 16 bytes are matched with SSE4.2 or AVX2 on x86
* Response reason phrases longer than 8 bytes are matched with SIMD
* `Request::parse_with_state` is fully resumable: every part of the request
line, including the method and leading empty lines, continues where the
previous `Partial` result stopped instead of being rescanned
* Add `Response::parse_with_state`, a resumable status line parser.
`Request::parse` and `Response::parse` are kept for compatibility
* Multiple spaces between the method and the path are accepted for every
method, not only `GET` and `POST`
* A bare CR before the request or status line is rejected when the input is
split right after it
* `parse_chunk_size` rejects control characters other than HTAB in chunk
extensions. Previously any octet was accepted, so a bare LF inside an
extension could be treated as the line end by other parsers (request
smuggling)
* Header parsing resumed after a `Partial` result that ended right after a
`\r` no longer accepts a bare CR (e.g. `X: a\rb\r\n` split after the `\r`
produced the value `"a\rb"`)
* `Request::parse_with_state` no longer fails with `Error::Token` when the
input is split right after the space following the request path
* `parse_chunk_size` rejects a chunk size line without digits (e.g. `\r\n` or
`;ext\r\n`), which was accepted as the last chunk
* `Request::parse_with_state` and `Header::parse_with_state` return an error
for an invalid `State` instead of panicking or returning stale positions
* `Response::parse` no longer skips empty lines between the version and the
status code (e.g. `HTTP/1.1\r\n 200 OK`)
* `HeaderParsed::Eof` holds the position in the buffer, like
`HeaderParsed::Header`, instead of the length of the final empty line. This
only differs when `State` is not reset between headers
* Rewrite API docs and README for the fork's API; hide the benchmark-only
`parse_method` and `parse_uri` from docs