|
3 | 3 | const assert = require('node:assert') |
4 | 4 | const { tspl } = require('@matteo.collina/tspl') |
5 | 5 | const { test, after } = require('node:test') |
6 | | -const { createSecureServer } = require('node:http2') |
| 6 | +const { createSecureServer, constants } = require('node:http2') |
7 | 7 | const { createReadStream, readFileSync } = require('node:fs') |
8 | 8 | const { once } = require('node:events') |
| 9 | +const { Readable } = require('node:stream') |
9 | 10 |
|
10 | 11 | const pem = require('@metcoder95/https-pem') |
11 | 12 |
|
@@ -114,6 +115,60 @@ test('Should send content-length: 0 for empty h2 requests with payload-expecting |
114 | 115 | await assert.completed |
115 | 116 | }) |
116 | 117 |
|
| 118 | +test('Should end h2 zero-length request bodies with headers', async t => { |
| 119 | + const server = createSecureServer(await pem.generate({ opts: { keySize: 2048 } })) |
| 120 | + const requests = new Map() |
| 121 | + |
| 122 | + server.on('stream', (stream, headers, flags) => { |
| 123 | + requests.set(headers[':path'], { headers, flags }) |
| 124 | + stream.respond({ ':status': 200 }) |
| 125 | + stream.end() |
| 126 | + }) |
| 127 | + |
| 128 | + after(() => server.close()) |
| 129 | + await once(server.listen(0), 'listening') |
| 130 | + |
| 131 | + const client = new Client(`https://localhost:${server.address().port}`, { |
| 132 | + connect: { rejectUnauthorized: false } |
| 133 | + }) |
| 134 | + after(() => client.close()) |
| 135 | + |
| 136 | + const cases = [ |
| 137 | + { |
| 138 | + path: '/buffer', |
| 139 | + body: Buffer.alloc(0), |
| 140 | + headers: { 'content-length': '0' } |
| 141 | + }, |
| 142 | + { |
| 143 | + path: '/blob', |
| 144 | + body: new Blob([]) |
| 145 | + }, |
| 146 | + { |
| 147 | + path: '/stream', |
| 148 | + body: Readable.from([]), |
| 149 | + headers: { 'content-length': '0' } |
| 150 | + } |
| 151 | + ] |
| 152 | + |
| 153 | + for (const { path, body, headers } of cases) { |
| 154 | + const response = await client.request({ |
| 155 | + path, |
| 156 | + method: 'POST', |
| 157 | + headers, |
| 158 | + body |
| 159 | + }) |
| 160 | + |
| 161 | + await response.body.text() |
| 162 | + } |
| 163 | + |
| 164 | + for (const { path } of cases) { |
| 165 | + const request = requests.get(path) |
| 166 | + assert.ok(request, `received ${path}`) |
| 167 | + assert.strictEqual(request.headers['content-length'], '0') |
| 168 | + assert.ok(request.flags & constants.NGHTTP2_FLAG_END_STREAM) |
| 169 | + } |
| 170 | +}) |
| 171 | + |
117 | 172 | test('Should handle h2 request with body (string or buffer) - dispatch', async t => { |
118 | 173 | t = tspl(t, { plan: 7 }) |
119 | 174 |
|
|
0 commit comments