Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upHttp2: Cannot read property 'finishWrite' of null #35695
Comments
|
This is a collection of various minor issues all linked to the edge case of the underlying stream of the TLS listener being null after being indirectly removed by the |
|
The segfault does not occur with the new crypto_tls code, it occurs only on v14.x |
|
@mmomtchev |
|
I was able to compress it down to this unit test: 'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const h2 = require('http2');
const net = require('net');
const fixtures = require('../common/fixtures');
const { Duplex } = require('stream');
const server = h2.createSecureServer({
key: fixtures.readKey('agent1-key.pem'),
cert: fixtures.readKey('agent1-cert.pem')
});
class JSSocket extends Duplex {
constructor(socket) {
super();
socket.on('close', () => this.destroy());
socket.on('data', (data) => this.push(data));
this.socket = socket;
}
_write(data, encoding, callback) {
this.socket.write(data, encoding, callback);
}
_read(size) {
}
}
server.listen(0, common.mustCall(function() {
const socket = net.connect({
host: 'localhost',
port: this.address().port
}, () => {
const client = h2.connect(`https://localhost:${this.address().port}`, {
rejectUnauthorized: false,
socket: new JSSocket(socket)
});
const req = client.request();
setTimeout(() => socket.destroy(), 500);
setTimeout(() => client.close(), 1000);
setTimeout(() => server.close(), 1500);
req.on('close', common.mustCall(() => { }));
});
}));With JSSocket - exception on Node 14.x and master |
|
The reason I try to spawn the server in a new process and kill the server is I want server send RST packet(not FIN packet) to end the connection. Maybe the error RST end the connection is not the same as FIN. |
|
@jasnell, @addaleax is |
|
using createConnection instead: ...
const client = h2.connect(`https://localhost:${this.address().port}`, {
rejectUnauthorized: false,
createConnection: () => tls.connect({
socket: new JSSocket(socket),
host: 'localhost', port: this.address().port, ALPNProtocols: ['h2']
}),
// socket: new JSSocket(socket)
});
...the same error:
but this can prevent the error: ...
createConnection: () => {
const jsSocket = new JSSocket(socket)
const tlsSocket = tls.connect({
socket: jsSocket,
host: 'localhost', port: this.address().port, ALPNProtocols: ['h2']
})
// tlsSocket.on('close', ()=>{jsSocket.destroy()})
jsSocket.on('close', ()=>{tlsSocket.destroy()}) // <-- add this line
return tlsSocket
}
... |
|
@panmenghan the exception is trivial to fix on the |
|
@mmomtchev Thanks, please fix it. I already rewrite my code to use |
When using a JSStreamSocket, the HTTP2Session constructor will replace the socket object http2 events should be attached to the JSStreamSocket object because the http2 session handle lives there Fixes: nodejs#35695
|
@panmenghan the bug is in the http2 code |


v14.14.0 + v12.19.0
Win10(2004, 64bit) + Ubuntu 18.04.4(wsl2, Linux 4.19.128-microsoft-standard SMP Tue Jun 23 12:58:10 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux)
http2
What steps will reproduce the bug?
server.js
client.js
the error(bug):
client.js argv(command line options) mean:
Win10(2004)
Ubuntu 18.04.4(wsl2)
How often does it reproduce? Is there a required condition?
What is the expected behavior?
No "TypeError: Cannot read property 'finishShutdown' of null" error
What do you see instead?
Additional information