11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci// Flags: --expose-internals 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciconst common = require('../common'); 51cb0ef41Sopenharmony_ciif (!common.hasCrypto) 61cb0ef41Sopenharmony_ci common.skip('missing crypto'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst { internalBinding } = require('internal/test/binding'); 91cb0ef41Sopenharmony_ciconst { 101cb0ef41Sopenharmony_ci constants, 111cb0ef41Sopenharmony_ci Http2Session, 121cb0ef41Sopenharmony_ci nghttp2ErrorString 131cb0ef41Sopenharmony_ci} = internalBinding('http2'); 141cb0ef41Sopenharmony_ciconst http2 = require('http2'); 151cb0ef41Sopenharmony_ciconst { NghttpError } = require('internal/http2/util'); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci// Tests error handling within requestOnConnect 181cb0ef41Sopenharmony_ci// - NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE (should emit session error) 191cb0ef41Sopenharmony_ci// - NGHTTP2_ERR_INVALID_ARGUMENT (should emit stream error) 201cb0ef41Sopenharmony_ci// - every other NGHTTP2 error from binding (should emit session error) 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciconst specificTestKeys = [ 231cb0ef41Sopenharmony_ci 'NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE', 241cb0ef41Sopenharmony_ci 'NGHTTP2_ERR_INVALID_ARGUMENT', 251cb0ef41Sopenharmony_ci]; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciconst specificTests = [ 281cb0ef41Sopenharmony_ci { 291cb0ef41Sopenharmony_ci ngError: constants.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE, 301cb0ef41Sopenharmony_ci error: { 311cb0ef41Sopenharmony_ci code: 'ERR_HTTP2_OUT_OF_STREAMS', 321cb0ef41Sopenharmony_ci name: 'Error', 331cb0ef41Sopenharmony_ci message: 'No stream ID is available because ' + 341cb0ef41Sopenharmony_ci 'maximum stream ID has been reached' 351cb0ef41Sopenharmony_ci }, 361cb0ef41Sopenharmony_ci type: 'stream' 371cb0ef41Sopenharmony_ci }, 381cb0ef41Sopenharmony_ci { 391cb0ef41Sopenharmony_ci ngError: constants.NGHTTP2_ERR_INVALID_ARGUMENT, 401cb0ef41Sopenharmony_ci error: { 411cb0ef41Sopenharmony_ci code: 'ERR_HTTP2_STREAM_SELF_DEPENDENCY', 421cb0ef41Sopenharmony_ci name: 'Error', 431cb0ef41Sopenharmony_ci message: 'A stream cannot depend on itself' 441cb0ef41Sopenharmony_ci }, 451cb0ef41Sopenharmony_ci type: 'stream' 461cb0ef41Sopenharmony_ci }, 471cb0ef41Sopenharmony_ci]; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ciconst genericTests = Object.getOwnPropertyNames(constants) 501cb0ef41Sopenharmony_ci .filter((key) => ( 511cb0ef41Sopenharmony_ci key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0 521cb0ef41Sopenharmony_ci )) 531cb0ef41Sopenharmony_ci .map((key) => ({ 541cb0ef41Sopenharmony_ci ngError: constants[key], 551cb0ef41Sopenharmony_ci error: { 561cb0ef41Sopenharmony_ci code: 'ERR_HTTP2_ERROR', 571cb0ef41Sopenharmony_ci constructor: NghttpError, 581cb0ef41Sopenharmony_ci name: 'Error', 591cb0ef41Sopenharmony_ci message: nghttp2ErrorString(constants[key]) 601cb0ef41Sopenharmony_ci }, 611cb0ef41Sopenharmony_ci type: 'session' 621cb0ef41Sopenharmony_ci })); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ciconst tests = specificTests.concat(genericTests); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_cilet currentError; 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci// Mock submitRequest because we only care about testing error handling 691cb0ef41Sopenharmony_ciHttp2Session.prototype.request = () => currentError; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ciconst server = http2.createServer(common.mustNotCall()); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => runTest(tests.shift()))); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_cifunction runTest(test) { 761cb0ef41Sopenharmony_ci const client = http2.connect(`http://localhost:${server.address().port}`); 771cb0ef41Sopenharmony_ci client.on('close', common.mustCall()); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci const req = client.request({ ':method': 'POST' }); 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci currentError = test.ngError; 821cb0ef41Sopenharmony_ci req.resume(); 831cb0ef41Sopenharmony_ci req.end(); 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci const errorMustCall = common.expectsError(test.error); 861cb0ef41Sopenharmony_ci const errorMustNotCall = common.mustNotCall( 871cb0ef41Sopenharmony_ci `${test.error.code} should emit on ${test.type}` 881cb0ef41Sopenharmony_ci ); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci if (test.type === 'stream') { 911cb0ef41Sopenharmony_ci client.on('error', errorMustNotCall); 921cb0ef41Sopenharmony_ci req.on('error', errorMustCall); 931cb0ef41Sopenharmony_ci } else { 941cb0ef41Sopenharmony_ci client.on('error', errorMustCall); 951cb0ef41Sopenharmony_ci req.on('error', (err) => { 961cb0ef41Sopenharmony_ci common.expectsError({ 971cb0ef41Sopenharmony_ci code: 'ERR_HTTP2_STREAM_CANCEL' 981cb0ef41Sopenharmony_ci })(err); 991cb0ef41Sopenharmony_ci common.expectsError({ 1001cb0ef41Sopenharmony_ci code: 'ERR_HTTP2_ERROR' 1011cb0ef41Sopenharmony_ci })(err.cause); 1021cb0ef41Sopenharmony_ci }); 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci req.on('end', common.mustNotCall()); 1061cb0ef41Sopenharmony_ci req.on('close', common.mustCall(() => { 1071cb0ef41Sopenharmony_ci client.destroy(); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci if (!tests.length) { 1101cb0ef41Sopenharmony_ci server.close(); 1111cb0ef41Sopenharmony_ci } else { 1121cb0ef41Sopenharmony_ci runTest(tests.shift()); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci })); 1151cb0ef41Sopenharmony_ci} 116