http2: compat support for array headers

PR-URL: https://github.com/nodejs/node/pull/42901
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ricky Zhou <0x19951125@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
This commit is contained in:
OneNail
2022-05-03 01:48:13 +08:00
committed by GitHub
parent acffd3d9e6
commit 916a13a8a3
3 changed files with 98 additions and 36 deletions

View File

@@ -3985,7 +3985,7 @@ changes:
* `statusCode` {number}
* `statusMessage` {string}
* `headers` {Object}
* `headers` {Object|Array}
* Returns: {http2.Http2ServerResponse}
Sends a response header to the request. The status code is a 3-digit HTTP

View File

@@ -682,9 +682,19 @@ class Http2ServerResponse extends Stream {
let i;
if (ArrayIsArray(headers)) {
for (i = 0; i < headers.length; i++) {
const header = headers[i];
this[kSetHeader](header[0], header[1]);
if (headers.length && ArrayIsArray(headers[0])) {
for (i = 0; i < headers.length; i++) {
const header = headers[i];
this[kSetHeader](header[0], header[1]);
}
} else {
if (headers.length % 2 !== 0) {
throw new ERR_INVALID_ARG_VALUE('headers', headers);
}
for (i = 0; i < headers.length; i += 2) {
this[kSetHeader](headers[i], headers[i + 1]);
}
}
} else if (typeof headers === 'object') {
const keys = ObjectKeys(headers);

View File

@@ -4,40 +4,92 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const h2 = require('http2');
const http2 = require('http2');
// Http2ServerResponse.writeHead should support nested arrays
// Http2ServerResponse.writeHead should support arrays and nested arrays
const server = h2.createServer();
server.listen(0, common.mustCall(() => {
const port = server.address().port;
server.once('request', common.mustCall((request, response) => {
const returnVal = response.writeHead(200, [
['foo', 'bar'],
['ABC', 123],
]);
assert.strictEqual(returnVal, response);
response.end(common.mustCall(() => { server.close(); }));
}));
{
const server = http2.createServer();
server.listen(0, common.mustCall(() => {
const port = server.address().port;
const url = `http://localhost:${port}`;
const client = h2.connect(url, common.mustCall(() => {
const headers = {
':path': '/',
':method': 'GET',
':scheme': 'http',
':authority': `localhost:${port}`
};
const request = client.request(headers);
request.on('response', common.mustCall((headers) => {
assert.strictEqual(headers.foo, 'bar');
assert.strictEqual(headers.abc, '123');
assert.strictEqual(headers[':status'], 200);
}, 1));
request.on('end', common.mustCall(() => {
client.close();
server.once('request', common.mustCall((request, response) => {
const returnVal = response.writeHead(200, [
['foo', 'bar'],
['ABC', 123],
]);
assert.strictEqual(returnVal, response);
response.end(common.mustCall(() => { server.close(); }));
}));
const client = http2.connect(`http://localhost:${port}`, common.mustCall(() => {
const request = client.request();
request.on('response', common.mustCall((headers) => {
assert.strictEqual(headers.foo, 'bar');
assert.strictEqual(headers.abc, '123');
assert.strictEqual(headers[':status'], 200);
}, 1));
request.on('end', common.mustCall(() => {
client.close();
}));
request.end();
request.resume();
}));
request.end();
request.resume();
}));
}));
}
{
const server = http2.createServer();
server.listen(0, common.mustCall(() => {
const port = server.address().port;
server.once('request', common.mustCall((request, response) => {
const returnVal = response.writeHead(200, ['foo', 'bar', 'ABC', 123]);
assert.strictEqual(returnVal, response);
response.end(common.mustCall(() => { server.close(); }));
}));
const client = http2.connect(`http://localhost:${port}`, common.mustCall(() => {
const request = client.request();
request.on('response', common.mustCall((headers) => {
assert.strictEqual(headers.foo, 'bar');
assert.strictEqual(headers.abc, '123');
assert.strictEqual(headers[':status'], 200);
}, 1));
request.on('end', common.mustCall(() => {
client.close();
}));
request.end();
request.resume();
}));
}));
}
{
const server = http2.createServer();
server.listen(0, common.mustCall(() => {
const port = server.address().port;
server.once('request', common.mustCall((request, response) => {
try {
response.writeHead(200, ['foo', 'bar', 'ABC', 123, 'extra']);
} catch (err) {
assert.strictEqual(err.code, 'ERR_INVALID_ARG_VALUE');
}
response.end(common.mustCall(() => { server.close(); }));
}));
const client = http2.connect(`http://localhost:${port}`, common.mustCall(() => {
const request = client.request();
request.on('end', common.mustCall(() => {
client.close();
}));
request.end();
request.resume();
}));
}));
}