1// Flags: --expose-internals 2 3'use strict'; 4 5const common = require('../common'); 6if (!common.hasCrypto) 7 common.skip('missing crypto'); 8const assert = require('assert'); 9const h2 = require('http2'); 10const { kSocket } = require('internal/http2/util'); 11 12const server = h2.createServer(); 13 14// We use the lower-level API here 15server.on('stream', common.mustCall(onStream)); 16 17function onStream(stream) { 18 stream.respond(); 19 stream.write('test'); 20 21 const socket = stream.session[kSocket]; 22 23 // When the socket is destroyed, the close events must be triggered 24 // on the socket, server and session. 25 socket.on('close', common.mustCall()); 26 stream.on('close', common.mustCall()); 27 server.on('close', common.mustCall()); 28 stream.session.on('close', common.mustCall(() => server.close())); 29 30 // Also, the aborted event must be triggered on the stream 31 stream.on('aborted', common.mustCall()); 32 33 assert.notStrictEqual(stream.session, undefined); 34 socket.destroy(); 35} 36 37server.listen(0); 38 39server.on('listening', common.mustCall(() => { 40 const client = h2.connect(`http://localhost:${server.address().port}`); 41 // The client may have an ECONNRESET error here depending on the operating 42 // system, due mainly to differences in the timing of socket closing. Do 43 // not wrap this in a common mustCall. 44 client.on('error', (err) => { 45 if (err.code !== 'ECONNRESET') 46 throw err; 47 }); 48 client.on('close', common.mustCall()); 49 50 const req = client.request({ ':method': 'POST' }); 51 // The client may have an ECONNRESET error here depending on the operating 52 // system, due mainly to differences in the timing of socket closing. Do 53 // not wrap this in a common mustCall. 54 req.on('error', (err) => { 55 if (err.code !== 'ECONNRESET') 56 throw err; 57 }); 58 59 req.on('aborted', common.mustCall()); 60 req.resume(); 61 req.on('end', common.mustCall()); 62})); 63