Repository navigation
v0.5.0 — streaming request body
Highlights
Streaming request body (issue #26, PR #27)
New opt-in API for processing request bodies as they arrive, instead of buffering the whole Content-Length into req->body before dispatch.
New API
TrueAsync\HttpRequest::readBody(int $maxLen = 65536): ?string— pulls one parser-supplied chunk per call (16 KiB H2 DATA frame / 8 KiB H1 socket read),nullat EOF. Parks the coroutine on a per-request trigger event when the queue is empty. Throws\Exceptionon stream error.TrueAsync\HttpServerConfig::setBodyStreamingEnabled(bool): static/isBodyStreamingEnabled(): bool— server-wide flag, defaultfalse.
Impact (h2load, 50 concurrent 20 MiB POSTs, release PHP, WSL2):
| peak RSS | RPS | |
|---|---|---|
| buffered | 1170 MiB | 36 |
| streaming | 197 MiB | 100 |
≈ ×6 RSS reduction, ×2.7 throughput. Buffered handlers (no opt-in) keep byte-for-byte previous behaviour — A/B benchmarks on baseline H1/H2 and buffered upload show no regression beyond WSL2 noise.
Deferred to follow-up PRs (docs/PLAN_STREAMING_INGRESS.md):
- Backpressure:
llhttp_pause+NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATEwith deferrednghttp2_session_consume - HTTP/3 integration (
ngtcp2_conn_extend_max_stream_offset) readBodyChunks()— zero-copy scatter read- Mode trichotomy with
LogicException(currently a single server-wide flag) setMaxBodyQueueBytes()config setter (watermark hardcoded at 256 KiB)
See CHANGELOG.md for the full entry.