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