You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
http2: server.close not behaving like http1 or net #20630
An http2 server inherits from net.Server, so a user might expect that the behavior of close() is the same (and we document it as being the same). However, the following will never call the close(cb) callback.
'use strict';consthttp2=require('http2');constassert=require('assert');constserver=http2.createServer();letclient;server.listen(0,function(){client=http2.connect(`http://localhost:${server.address().port}`);client.on('connect',function(){console.log('connect');server.close(function(){console.log('the close callback');});});});server.on('session',(s)=>{s.setTimeout(10,function(){console.log('timeout');s.destroy();});});
This is the same code for net that works as expected:
'use strict';constnet=require('net');constassert=require('assert');constserver=net.createServer();letclient;server.listen(0,function(){client=net.connect(server.address().port);client.on('connect',function(){console.log('connect');server.close(function(){console.log('the close callback');});});});server.on('connection',(s)=>{s.setTimeout(10,function(){console.log('timeout');s.destroy();});});
Hmmm... I get ECONNRESET pretty consistently but the callback definitely does run.
(node:69948) ExperimentalWarning: The http2 module is an experimental API.
connect
the close callback
events.js:167
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onread (net.js:659:25)
Emitted 'error' event at:
at emitClose (internal/http2/core.js:810:10)
at process._tickCallback (internal/process/next_tick.js:63:19)
Something like this replicates it for me reliably though:
'use strict';consthttp2=require('http2');constassert=require('assert');constserver=http2.createServer();letclient;server.listen(0,function(){client=http2.connect(`http://localhost:${server.address().port}`);client.on('connect',function(){console.log('connect');});});server.on('session',(s)=>{s.destroy();server.close(function(){console.log('the close callback');});});
@mcollina That's not strictly true. The test case above is a more reliable way to test the same issue. To sum it up: the close callback is dependent upon sockets being destroyed which they currently aren't.
Activity
jasnell commentedon May 9, 2018
Yep, able to reproduce, not sure why it's happening yet. Will investigate!
apapirovski commentedon May 9, 2018
Hmmm... I get
ECONNRESETpretty consistently but the callback definitely does run.Something like this replicates it for me reliably though:
mcollina commentedon May 9, 2018
@apapirovski the bug is about calling
server.close()beforesession.destroy().apapirovski commentedon May 10, 2018
@mcollina That's not strictly true. The test case above is a more reliable way to test the same issue. To sum it up: the close callback is dependent upon sockets being destroyed which they currently aren't.
It's fixed by this PR: #19852
mcollina commentedon May 10, 2018
@apapirovski it's nice it ends up being a PR that I've not finished yet. I completely forgot about that one. Thanks.
apapirovski commentedon May 14, 2018
Fixed in #19852