mirror of
https://github.com/nodejs/node.git
synced 2025-04-29 22:40:57 +00:00

Expand argument validation through compat API, adjust behaviour of response.end to not throw if stream already closed to match http1, adjust behaviour of writeContinue to not throw if stream already closed and other very small tweaks. Add tests for added and fixed behaviour. Add tests for edge case behaviours of setTimeout, createPushResponse, destroy, end and trailers. PR-URL: https://github.com/nodejs/node/pull/15473 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Minwoo Jung <jmwsoft@gmail.com>
148 lines
4.2 KiB
JavaScript
148 lines
4.2 KiB
JavaScript
// Flags: --expose-http2
|
|
'use strict';
|
|
|
|
const { mustCall, mustNotCall, hasCrypto, skip } = require('../common');
|
|
if (!hasCrypto)
|
|
skip('missing crypto');
|
|
const { strictEqual } = require('assert');
|
|
const {
|
|
createServer,
|
|
connect,
|
|
constants: {
|
|
HTTP2_HEADER_STATUS,
|
|
HTTP_STATUS_OK
|
|
}
|
|
} = require('http2');
|
|
|
|
{
|
|
// Http2ServerResponse.end accepts chunk, encoding, cb as args
|
|
// It may be invoked repeatedly without throwing errors
|
|
// but callback will only be called once
|
|
const server = createServer(mustCall((request, response) => {
|
|
strictEqual(response.closed, false);
|
|
response.end('end', 'utf8', mustCall(() => {
|
|
strictEqual(response.closed, true);
|
|
response.end(mustNotCall());
|
|
process.nextTick(() => {
|
|
response.end(mustNotCall());
|
|
server.close();
|
|
});
|
|
}));
|
|
response.end(mustNotCall());
|
|
}));
|
|
server.listen(0, mustCall(() => {
|
|
let data = '';
|
|
const { port } = server.address();
|
|
const url = `http://localhost:${port}`;
|
|
const client = connect(url, mustCall(() => {
|
|
const headers = {
|
|
':path': '/',
|
|
':method': 'GET',
|
|
':scheme': 'http',
|
|
':authority': `localhost:${port}`
|
|
};
|
|
const request = client.request(headers);
|
|
request.setEncoding('utf8');
|
|
request.on('data', (chunk) => (data += chunk));
|
|
request.on('end', mustCall(() => {
|
|
strictEqual(data, 'end');
|
|
client.destroy();
|
|
}));
|
|
request.end();
|
|
request.resume();
|
|
}));
|
|
}));
|
|
}
|
|
|
|
{
|
|
// Http2ServerResponse.end can omit encoding arg, sets it to utf-8
|
|
const server = createServer(mustCall((request, response) => {
|
|
response.end('test\uD83D\uDE00', mustCall(() => {
|
|
server.close();
|
|
}));
|
|
}));
|
|
server.listen(0, mustCall(() => {
|
|
let data = '';
|
|
const { port } = server.address();
|
|
const url = `http://localhost:${port}`;
|
|
const client = connect(url, mustCall(() => {
|
|
const headers = {
|
|
':path': '/',
|
|
':method': 'GET',
|
|
':scheme': 'http',
|
|
':authority': `localhost:${port}`
|
|
};
|
|
const request = client.request(headers);
|
|
request.setEncoding('utf8');
|
|
request.on('data', (chunk) => (data += chunk));
|
|
request.on('end', mustCall(() => {
|
|
strictEqual(data, 'test\uD83D\uDE00');
|
|
client.destroy();
|
|
}));
|
|
request.end();
|
|
request.resume();
|
|
}));
|
|
}));
|
|
}
|
|
|
|
{
|
|
// Http2ServerResponse.end can omit chunk & encoding args
|
|
const server = createServer(mustCall((request, response) => {
|
|
response.end(mustCall(() => {
|
|
server.close();
|
|
}));
|
|
}));
|
|
server.listen(0, mustCall(() => {
|
|
const { port } = server.address();
|
|
const url = `http://localhost:${port}`;
|
|
const client = connect(url, mustCall(() => {
|
|
const headers = {
|
|
':path': '/',
|
|
':method': 'GET',
|
|
':scheme': 'http',
|
|
':authority': `localhost:${port}`
|
|
};
|
|
const request = client.request(headers);
|
|
request.on('data', mustNotCall());
|
|
request.on('end', mustCall(() => client.destroy()));
|
|
request.end();
|
|
request.resume();
|
|
}));
|
|
}));
|
|
}
|
|
|
|
{
|
|
// Http2ServerResponse.end is not necessary on HEAD requests since the stream
|
|
// is already closed. Headers, however, can still be sent to the client.
|
|
const server = createServer(mustCall((request, response) => {
|
|
strictEqual(response.finished, true);
|
|
response.writeHead(HTTP_STATUS_OK, { foo: 'bar' });
|
|
response.end(mustNotCall());
|
|
}));
|
|
server.listen(0, mustCall(() => {
|
|
const { port } = server.address();
|
|
const url = `http://localhost:${port}`;
|
|
const client = connect(url, mustCall(() => {
|
|
const headers = {
|
|
':path': '/',
|
|
':method': 'HEAD',
|
|
':scheme': 'http',
|
|
':authority': `localhost:${port}`
|
|
};
|
|
const request = client.request(headers);
|
|
request.on('response', mustCall((headers, flags) => {
|
|
strictEqual(headers[HTTP2_HEADER_STATUS], HTTP_STATUS_OK);
|
|
strictEqual(flags, 5); // the end of stream flag is set
|
|
strictEqual(headers.foo, 'bar');
|
|
}));
|
|
request.on('data', mustNotCall());
|
|
request.on('end', mustCall(() => {
|
|
client.destroy();
|
|
server.close();
|
|
}));
|
|
request.end();
|
|
request.resume();
|
|
}));
|
|
}));
|
|
}
|