fix(ext/node): enable HTTP parser consume fast path (#33354)
In our llhttp wiring we had a fast path to avoid the JS readable stream and let the parser read straight from the underlying uv stream. Several bugs blocked the parser.consume path for anything other than bare TCPWrap: - try_unwrap_cppgc_object returns None for any subclass of LibUvStreamWrap (TCPWrap, TLSWrap, PipeWrap), so the consume fast path silently no-op'd. Use try_unwrap_cppgc_base_object to match via the base class. - The C callback invoked kOnExecute with the raw nread=0 sentinel (EAGAIN/WouldBlock via libuv's alloc+nread=0 idiom), firing a spurious v8 scope + function-call round trip per request. Match Node's node_http_parser.cc:OnStreamRead — skip empty reads. - Parse errors on the consume fast path invoked kOnExecute with a raw -1. The JS .execute() wrapper (http_parser.ts) converts negative returns into an Error object with code/reason/bytesParsed before onParserExecuteCommon runs its `ret instanceof Error` branch. The consume path bypassed the wrapper, so protocol errors (chunked-smuggling etc.) silently wedged the connection. Build the same Error shape in Rust. - Casting `&mut ContextScope<HandleScope>` directly to `*mut PinScope` is UB — ContextScope has a different layout. Coerce via Deref first so ExecuteContext sees a real PinScope pointer. - On the consume path the read interceptor borrows buf.base during its callback but doesn't take ownership, so the caller must free it — we weren't, leaking 64KB per read once interceptors were actually exercised. Increases throughput by about 6% on hello world
N
Nathan Whitaker committed
ea1be680ad5ad2c33deea715cc8554a232557cd5
Parent: b3568ec
Committed by GitHub <noreply@github.com>
on 4/22/2026, 8:19:26 AM