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_ciconst http2 = require('http2');
81cb0ef41Sopenharmony_ciconst { internalBinding } = require('internal/test/binding');
91cb0ef41Sopenharmony_ciconst {
101cb0ef41Sopenharmony_ci  constants,
111cb0ef41Sopenharmony_ci  Http2Stream,
121cb0ef41Sopenharmony_ci  nghttp2ErrorString
131cb0ef41Sopenharmony_ci} = internalBinding('http2');
141cb0ef41Sopenharmony_ciconst { NghttpError } = require('internal/http2/util');
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci// Tests error handling within respond
171cb0ef41Sopenharmony_ci// - every other NGHTTP2 error from binding (should emit stream error)
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciconst specificTestKeys = [];
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciconst specificTests = [];
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciconst genericTests = Object.getOwnPropertyNames(constants)
241cb0ef41Sopenharmony_ci  .filter((key) => (
251cb0ef41Sopenharmony_ci    key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0
261cb0ef41Sopenharmony_ci  ))
271cb0ef41Sopenharmony_ci  .map((key) => ({
281cb0ef41Sopenharmony_ci    ngError: constants[key],
291cb0ef41Sopenharmony_ci    error: {
301cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_ERROR',
311cb0ef41Sopenharmony_ci      constructor: NghttpError,
321cb0ef41Sopenharmony_ci      name: 'Error',
331cb0ef41Sopenharmony_ci      message: nghttp2ErrorString(constants[key])
341cb0ef41Sopenharmony_ci    },
351cb0ef41Sopenharmony_ci    type: 'stream'
361cb0ef41Sopenharmony_ci  }));
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ciconst tests = specificTests.concat(genericTests);
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_cilet currentError;
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci// Mock submitResponse because we only care about testing error handling
441cb0ef41Sopenharmony_ciHttp2Stream.prototype.respond = () => currentError.ngError;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciconst server = http2.createServer();
471cb0ef41Sopenharmony_ciserver.on('stream', common.mustCall((stream, headers) => {
481cb0ef41Sopenharmony_ci  const errorMustCall = common.expectsError(currentError.error);
491cb0ef41Sopenharmony_ci  const errorMustNotCall = common.mustNotCall(
501cb0ef41Sopenharmony_ci    `${currentError.error.code} should emit on ${currentError.type}`
511cb0ef41Sopenharmony_ci  );
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  if (currentError.type === 'stream') {
541cb0ef41Sopenharmony_ci    stream.session.on('error', errorMustNotCall);
551cb0ef41Sopenharmony_ci    stream.on('error', errorMustCall);
561cb0ef41Sopenharmony_ci    stream.on('error', common.mustCall(() => {
571cb0ef41Sopenharmony_ci      stream.destroy();
581cb0ef41Sopenharmony_ci    }));
591cb0ef41Sopenharmony_ci  } else {
601cb0ef41Sopenharmony_ci    stream.session.once('error', errorMustCall);
611cb0ef41Sopenharmony_ci    stream.on('error', errorMustNotCall);
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  stream.respond();
651cb0ef41Sopenharmony_ci}, tests.length));
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => runTest(tests.shift())));
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_cifunction runTest(test) {
701cb0ef41Sopenharmony_ci  const port = server.address().port;
711cb0ef41Sopenharmony_ci  const url = `http://localhost:${port}`;
721cb0ef41Sopenharmony_ci  const headers = {
731cb0ef41Sopenharmony_ci    ':path': '/',
741cb0ef41Sopenharmony_ci    ':method': 'POST',
751cb0ef41Sopenharmony_ci    ':scheme': 'http',
761cb0ef41Sopenharmony_ci    ':authority': `localhost:${port}`
771cb0ef41Sopenharmony_ci  };
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  const client = http2.connect(url);
801cb0ef41Sopenharmony_ci  const req = client.request(headers);
811cb0ef41Sopenharmony_ci  req.on('error', common.expectsError({
821cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_STREAM_ERROR',
831cb0ef41Sopenharmony_ci    name: 'Error',
841cb0ef41Sopenharmony_ci    message: 'Stream closed with error code NGHTTP2_INTERNAL_ERROR'
851cb0ef41Sopenharmony_ci  }));
861cb0ef41Sopenharmony_ci  req.on('end', common.mustNotCall());
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  currentError = test;
891cb0ef41Sopenharmony_ci  req.resume();
901cb0ef41Sopenharmony_ci  req.end();
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  req.on('close', common.mustCall(() => {
931cb0ef41Sopenharmony_ci    client.close();
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci    if (!tests.length) {
961cb0ef41Sopenharmony_ci      server.close();
971cb0ef41Sopenharmony_ci    } else {
981cb0ef41Sopenharmony_ci      runTest(tests.shift());
991cb0ef41Sopenharmony_ci    }
1001cb0ef41Sopenharmony_ci  }));
1011cb0ef41Sopenharmony_ci}
102