From a5c1faa917645a4e892ae28c2529f918a13078b6 Mon Sep 17 00:00:00 2001 From: "Kamat, Trivikram" <16024985+trivikr@users.noreply.github.com> Date: Sat, 25 Apr 2026 07:32:04 -0700 Subject: [PATCH 1/2] client: cache llhttp wasm buffer view Assisted-by: openai:gpt-5.5 Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> --- lib/dispatcher/client-h1.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/dispatcher/client-h1.js b/lib/dispatcher/client-h1.js index ea2ec316574..cf8f75a60f4 100644 --- a/lib/dispatcher/client-h1.js +++ b/lib/dispatcher/client-h1.js @@ -188,6 +188,7 @@ let currentBufferRef = null */ let currentBufferSize = 0 let currentBufferPtr = null +let currentBuffer = null const USE_NATIVE_TIMER = 0 const USE_FAST_TIMER = 1 @@ -322,7 +323,11 @@ class Parser { currentBufferPtr = llhttp.malloc(currentBufferSize) } - new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(chunk) + if (currentBuffer === null || currentBuffer.buffer !== llhttp.memory.buffer) { + currentBuffer = new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize) + } + + currentBuffer.set(chunk) // Call `execute` on the wasm parser. // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, From 27e470c7d643dfbd1f9c0b3ed41f259366b33c9a Mon Sep 17 00:00:00 2001 From: "Kamat, Trivikram" <16024985+trivikr@users.noreply.github.com> Date: Sat, 25 Apr 2026 07:46:11 -0700 Subject: [PATCH 2/2] fix: refresh wasm parser input view after realloc --- lib/dispatcher/client-h1.js | 7 +++- test/parser-issues.js | 66 +++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/lib/dispatcher/client-h1.js b/lib/dispatcher/client-h1.js index cf8f75a60f4..a0c19abc403 100644 --- a/lib/dispatcher/client-h1.js +++ b/lib/dispatcher/client-h1.js @@ -323,7 +323,12 @@ class Parser { currentBufferPtr = llhttp.malloc(currentBufferSize) } - if (currentBuffer === null || currentBuffer.buffer !== llhttp.memory.buffer) { + if ( + currentBuffer === null || + currentBuffer.buffer !== llhttp.memory.buffer || + currentBuffer.byteOffset !== currentBufferPtr || + currentBuffer.byteLength !== currentBufferSize + ) { currentBuffer = new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize) } diff --git a/test/parser-issues.js b/test/parser-issues.js index 859a5f096cb..5c71c5d4167 100644 --- a/test/parser-issues.js +++ b/test/parser-issues.js @@ -129,3 +129,69 @@ test('split header value', async (t) => { await t.completed }) + +test('refreshes wasm input view after reallocating parser buffer', async (t) => { + t = tspl(t, { plan: 4 }) + + const smallBody = Buffer.from('ok') + const largeBody = Buffer.alloc(8192, 'a') + const responses = [ + Buffer.concat([ + Buffer.from(`HTTP/1.1 200 OK\r\nContent-Length: ${smallBody.length}\r\n\r\n`), + smallBody + ]), + Buffer.concat([ + Buffer.from(`HTTP/1.1 200 OK\r\nContent-Length: ${largeBody.length}\r\n\r\n`), + largeBody + ]) + ] + + const server = net.createServer(socket => { + let responsesSent = 0 + + socket.on('data', () => { + socket.write(responses[responsesSent++]) + }) + }) + after(() => server.close()) + + await new Promise(resolve => server.listen(0, resolve)) + + const client = new Client(`http://localhost:${server.address().port}`) + after(() => client.destroy()) + + function request () { + return new Promise((resolve, reject) => { + client.request({ + method: 'GET', + path: '/' + }, (err, { statusCode, body } = {}) => { + if (err) { + reject(err) + return + } + + const bufs = [] + + body.on('data', buf => { + bufs.push(buf) + }) + body.on('end', () => { + resolve({ + statusCode, + body: Buffer.concat(bufs) + }) + }) + body.on('error', reject) + }) + }) + } + + const smallResponse = await request() + t.strictEqual(smallResponse.statusCode, 200) + t.strictEqual(smallResponse.body.toString(), smallBody.toString()) + + const largeResponse = await request() + t.strictEqual(largeResponse.statusCode, 200) + t.strictEqual(largeResponse.body.toString(), largeBody.toString()) +})