1'use strict'; 2// Flags: --expose-internals 3 4const common = require('../common'); 5if (!common.hasCrypto) 6 common.skip('missing crypto'); 7const http2 = require('http2'); 8const { internalBinding } = require('internal/test/binding'); 9const { 10 constants, 11 Http2Stream, 12 nghttp2ErrorString 13} = internalBinding('http2'); 14const { NghttpError } = require('internal/http2/util'); 15 16// Tests error handling within respond 17// - every other NGHTTP2 error from binding (should emit stream error) 18 19const specificTestKeys = []; 20 21const specificTests = []; 22 23const genericTests = Object.getOwnPropertyNames(constants) 24 .filter((key) => ( 25 key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0 26 )) 27 .map((key) => ({ 28 ngError: constants[key], 29 error: { 30 code: 'ERR_HTTP2_ERROR', 31 constructor: NghttpError, 32 name: 'Error', 33 message: nghttp2ErrorString(constants[key]) 34 }, 35 type: 'stream' 36 })); 37 38 39const tests = specificTests.concat(genericTests); 40 41let currentError; 42 43// Mock submitResponse because we only care about testing error handling 44Http2Stream.prototype.respond = () => currentError.ngError; 45 46const server = http2.createServer(); 47server.on('stream', common.mustCall((stream, headers) => { 48 const errorMustCall = common.expectsError(currentError.error); 49 const errorMustNotCall = common.mustNotCall( 50 `${currentError.error.code} should emit on ${currentError.type}` 51 ); 52 53 if (currentError.type === 'stream') { 54 stream.session.on('error', errorMustNotCall); 55 stream.on('error', errorMustCall); 56 stream.on('error', common.mustCall(() => { 57 stream.destroy(); 58 })); 59 } else { 60 stream.session.once('error', errorMustCall); 61 stream.on('error', errorMustNotCall); 62 } 63 64 stream.respond(); 65}, tests.length)); 66 67server.listen(0, common.mustCall(() => runTest(tests.shift()))); 68 69function runTest(test) { 70 const port = server.address().port; 71 const url = `http://localhost:${port}`; 72 const headers = { 73 ':path': '/', 74 ':method': 'POST', 75 ':scheme': 'http', 76 ':authority': `localhost:${port}` 77 }; 78 79 const client = http2.connect(url); 80 const req = client.request(headers); 81 req.on('error', common.expectsError({ 82 code: 'ERR_HTTP2_STREAM_ERROR', 83 name: 'Error', 84 message: 'Stream closed with error code NGHTTP2_INTERNAL_ERROR' 85 })); 86 87 currentError = test; 88 req.resume(); 89 req.end(); 90 91 req.on('end', common.mustCall(() => { 92 client.close(); 93 94 if (!tests.length) { 95 server.close(); 96 } else { 97 runTest(tests.shift()); 98 } 99 })); 100} 101