1'use strict'; 2 3const common = require('../common'); 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6const assert = require('assert'); 7const h2 = require('http2'); 8 9const server = h2.createServer(); 10server.on('stream', (stream) => { 11 stream.on('close', common.mustCall()); 12 stream.respond(); 13 stream.end('ok'); 14}); 15 16server.listen(0, common.mustCall(() => { 17 const client = h2.connect(`http://localhost:${server.address().port}`); 18 const req = client.request(); 19 const closeCode = 1; 20 21 assert.throws( 22 () => req.close(2 ** 32), 23 { 24 name: 'RangeError', 25 code: 'ERR_OUT_OF_RANGE', 26 message: 'The value of "code" is out of range. It must be ' + 27 '>= 0 && <= 4294967295. Received 4294967296' 28 } 29 ); 30 assert.strictEqual(req.closed, false); 31 32 [true, 1, {}, [], null, 'test'].forEach((notFunction) => { 33 assert.throws( 34 () => req.close(closeCode, notFunction), 35 { 36 name: 'TypeError', 37 code: 'ERR_INVALID_ARG_TYPE', 38 } 39 ); 40 assert.strictEqual(req.closed, false); 41 }); 42 43 req.close(closeCode, common.mustCall()); 44 assert.strictEqual(req.closed, true); 45 46 // Make sure that destroy is called. 47 req._destroy = common.mustCall(req._destroy.bind(req)); 48 49 // Second call doesn't do anything. 50 req.close(closeCode + 1); 51 52 req.on('close', common.mustCall(() => { 53 assert.strictEqual(req.destroyed, true); 54 assert.strictEqual(req.rstCode, closeCode); 55 server.close(); 56 client.close(); 57 })); 58 59 req.on('error', common.expectsError({ 60 code: 'ERR_HTTP2_STREAM_ERROR', 61 name: 'Error', 62 message: 'Stream closed with error code NGHTTP2_PROTOCOL_ERROR' 63 })); 64 65 // The `response` event should not fire as the server should receive the 66 // RST_STREAM frame before it ever has a chance to reply. 67 req.on('response', common.mustNotCall()); 68 69 // The `end` event should still fire as we close the readable stream by 70 // pushing a `null` chunk. 71 req.on('end', common.mustCall()); 72 73 req.resume(); 74 req.end(); 75})); 76