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