• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 additionalHeaders
17// - every other NGHTTP2 error from binding (should emit stream error)
18
19const specificTestKeys = [];
20const specificTests = [];
21
22const genericTests = Object.getOwnPropertyNames(constants)
23  .filter((key) => (
24    key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0
25  ))
26  .map((key) => ({
27    ngError: constants[key],
28    error: {
29      code: 'ERR_HTTP2_ERROR',
30      constructor: NghttpError,
31      name: 'Error',
32      message: nghttp2ErrorString(constants[key])
33    },
34    type: 'stream'
35  }));
36
37
38const tests = specificTests.concat(genericTests);
39
40let currentError;
41
42// Mock sendHeaders because we only care about testing error handling
43Http2Stream.prototype.info = () => currentError.ngError;
44
45const server = http2.createServer();
46server.on('stream', common.mustCall((stream, headers) => {
47  const errorMustCall = common.expectsError(currentError.error);
48  const errorMustNotCall = common.mustNotCall(
49    `${currentError.error.code} should emit on ${currentError.type}`
50  );
51
52  if (currentError.type === 'stream') {
53    stream.session.on('error', errorMustNotCall);
54    stream.on('error', errorMustCall);
55  } else {
56    stream.session.once('error', errorMustCall);
57    stream.on('error', errorMustNotCall);
58  }
59
60  stream.additionalHeaders({ ':status': 100 });
61}, tests.length));
62
63server.listen(0, common.mustCall(() => runTest(tests.shift())));
64
65function runTest(test) {
66  const client = http2.connect(`http://localhost:${server.address().port}`);
67  const req = client.request({ ':method': 'POST' });
68
69  currentError = test;
70  req.resume();
71  req.end();
72
73  req.on('error', common.expectsError({
74    code: 'ERR_HTTP2_STREAM_ERROR',
75    name: 'Error',
76    message: 'Stream closed with error code NGHTTP2_INTERNAL_ERROR'
77  }));
78
79  req.on('close', common.mustCall(() => {
80    client.close();
81
82    if (!tests.length) {
83      server.close();
84    } else {
85      runTest(tests.shift());
86    }
87  }));
88}
89