From c3ebfa2508f7141abdc537d2975a82e546c541a8 Mon Sep 17 00:00:00 2001 From: "Kamat, Trivikram" <16024985+trivikr@users.noreply.github.com> Date: Sat, 2 May 2026 15:44:13 -0700 Subject: [PATCH] fix: align h2 empty body content-length methods with h1 Assisted-by: openai:gpt-5.5 Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> --- lib/dispatcher/client-h2.js | 5 ++++- test/http2-body.js | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/dispatcher/client-h2.js b/lib/dispatcher/client-h2.js index e71c496b287..d4dc681f94a 100644 --- a/lib/dispatcher/client-h2.js +++ b/lib/dispatcher/client-h2.js @@ -804,7 +804,10 @@ function writeH2 (client, request) { const expectsPayload = ( method === 'PUT' || method === 'POST' || - method === 'PATCH' + method === 'PATCH' || + method === 'QUERY' || + method === 'PROPFIND' || + method === 'PROPPATCH' ) if (body && typeof body.read === 'function') { diff --git a/test/http2-body.js b/test/http2-body.js index 879b3eb71da..ad09706207b 100644 --- a/test/http2-body.js +++ b/test/http2-body.js @@ -70,6 +70,50 @@ test('Should handle h2 request without body', async t => { await t.completed }) +test('Should send content-length: 0 for empty h2 requests with payload-expecting methods', async t => { + const assert = tspl(t, { plan: 18 }) + const methods = ['PUT', 'POST', 'PATCH', 'QUERY', 'PROPFIND', 'PROPPATCH'] + + const server = createSecureServer(await pem.generate({ opts: { keySize: 2048 } })) + + server.on('stream', (stream, headers) => { + assert.strictEqual(headers['content-length'], '0') + assert.ok(methods.includes(headers[':method'])) + + stream.respond({ ':status': 200 }) + stream.end('ok') + }) + + await once(server.listen(0), 'listening') + + const client = new Client(`https://localhost:${server.address().port}`, { + connect: { + rejectUnauthorized: false + }, + allowH2: true + }) + + t.after(async () => { + server.close() + await client.close() + }) + + for (const method of methods) { + const response = await client.request({ + path: '/', + method, + body: '' + }) + + assert.strictEqual(response.statusCode, 200) + + response.body.resume() + await once(response.body, 'end') + } + + await assert.completed +}) + test('Should handle h2 request with body (string or buffer) - dispatch', async t => { t = tspl(t, { plan: 7 })