mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
b474901438
Without this, the session is destroyed with the following error ``` Error [ERR_HTTP2_ERROR]: Protocol error at Http2Session.onSessionInternalError (internal/http2/core.js:756:26) Emitted 'error' event on ClientHttp2Session instance at: at emitClose (internal/http2/core.js:1010:10) at internal/http2/core.js:1048:7 at finish (internal/streams/writable.js:731:5) at processTicksAndRejections (internal/process/task_queues.js:80:21) { code: 'ERR_HTTP2_ERROR', errno: -505 } ``` The test then calls `session.close()` which tries to write to a destroyed socket. As a result, an unhandled `ECONNRESET` error is emitted in the v12 release line. PR-URL: https://github.com/nodejs/node/pull/35482 Refs: https://github.com/nodejs/node/pull/34859 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
167 lines
4.2 KiB
JavaScript
167 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
mustCall,
|
|
hasCrypto,
|
|
hasIPv6,
|
|
skip,
|
|
expectsError
|
|
} = require('../common');
|
|
if (!hasCrypto)
|
|
skip('missing crypto');
|
|
const fixtures = require('../common/fixtures');
|
|
const assert = require('assert');
|
|
const { createServer, createSecureServer, connect } = require('http2');
|
|
const { connect: netConnect } = require('net');
|
|
const { connect: tlsConnect } = require('tls');
|
|
|
|
// Check for session connect callback and event
|
|
{
|
|
const server = createServer();
|
|
server.listen(0, mustCall(() => {
|
|
const authority = `http://localhost:${server.address().port}`;
|
|
const options = {};
|
|
const listener = () => mustCall();
|
|
|
|
const clients = new Set();
|
|
// Should not throw.
|
|
clients.add(connect(authority));
|
|
clients.add(connect(authority, options));
|
|
clients.add(connect(authority, options, listener()));
|
|
clients.add(connect(authority, listener()));
|
|
|
|
for (const client of clients) {
|
|
client.once('connect', mustCall((headers) => {
|
|
client.close();
|
|
clients.delete(client);
|
|
if (clients.size === 0) {
|
|
server.close();
|
|
}
|
|
}));
|
|
}
|
|
}));
|
|
}
|
|
|
|
// Check for session connect callback on already connected socket
|
|
{
|
|
const server = createServer();
|
|
server.listen(0, mustCall(() => {
|
|
const { port } = server.address();
|
|
|
|
const onSocketConnect = () => {
|
|
const authority = `http://localhost:${port}`;
|
|
const createConnection = mustCall(() => socket);
|
|
const options = { createConnection };
|
|
connect(authority, options, mustCall(onSessionConnect));
|
|
};
|
|
|
|
const onSessionConnect = (session) => {
|
|
session.close();
|
|
server.close();
|
|
};
|
|
|
|
const socket = netConnect(port, mustCall(onSocketConnect));
|
|
}));
|
|
}
|
|
|
|
// Check for https as protocol
|
|
{
|
|
const authority = 'https://localhost';
|
|
// A socket error may or may not be reported, keep this as a non-op
|
|
// instead of a mustCall or mustNotCall
|
|
connect(authority).on('error', () => {});
|
|
}
|
|
|
|
// Check for session connect callback on already connected TLS socket
|
|
{
|
|
const serverOptions = {
|
|
key: fixtures.readKey('agent1-key.pem'),
|
|
cert: fixtures.readKey('agent1-cert.pem')
|
|
};
|
|
const server = createSecureServer(serverOptions);
|
|
server.listen(0, mustCall(() => {
|
|
const { port } = server.address();
|
|
|
|
const onSocketConnect = () => {
|
|
const authority = `https://localhost:${port}`;
|
|
const createConnection = mustCall(() => socket);
|
|
const options = { createConnection };
|
|
connect(authority, options, mustCall(onSessionConnect));
|
|
};
|
|
|
|
const onSessionConnect = (session) => {
|
|
session.close();
|
|
server.close();
|
|
};
|
|
|
|
const clientOptions = {
|
|
ALPNProtocols: ['h2'],
|
|
port,
|
|
rejectUnauthorized: false
|
|
};
|
|
const socket = tlsConnect(clientOptions, mustCall(onSocketConnect));
|
|
}));
|
|
}
|
|
|
|
// Check for error for init settings error
|
|
{
|
|
createServer(function() {
|
|
connect(`http://localhost:${this.address().port}`, {
|
|
settings: {
|
|
maxFrameSize: 1 // An incorrect settings
|
|
}
|
|
}).on('error', expectsError({
|
|
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
name: 'RangeError'
|
|
}));
|
|
});
|
|
}
|
|
|
|
// Check for error for an invalid protocol (not http or https)
|
|
{
|
|
const authority = 'ssh://localhost';
|
|
assert.throws(() => {
|
|
connect(authority);
|
|
}, {
|
|
code: 'ERR_HTTP2_UNSUPPORTED_PROTOCOL',
|
|
name: 'Error'
|
|
});
|
|
}
|
|
|
|
// Check for literal IPv6 addresses in URL's
|
|
if (hasIPv6) {
|
|
const server = createServer();
|
|
server.listen(0, '::1', mustCall(() => {
|
|
const { port } = server.address();
|
|
const clients = new Set();
|
|
|
|
clients.add(connect(`http://[::1]:${port}`));
|
|
clients.add(connect(new URL(`http://[::1]:${port}`)));
|
|
|
|
for (const client of clients) {
|
|
client.once('connect', mustCall(() => {
|
|
client.close();
|
|
clients.delete(client);
|
|
if (clients.size === 0) {
|
|
server.close();
|
|
}
|
|
}));
|
|
}
|
|
}));
|
|
}
|
|
|
|
// Check that `options.host` and `options.port` take precedence over
|
|
// `authority.host` and `authority.port`.
|
|
{
|
|
const server = createServer();
|
|
server.listen(0, mustCall(() => {
|
|
connect('http://foo.bar', {
|
|
host: 'localhost',
|
|
port: server.address().port
|
|
}, mustCall((session) => {
|
|
session.close();
|
|
server.close();
|
|
}));
|
|
}));
|
|
}
|