1'use strict';
2
3const common = require('../common');
4if (!common.hasCrypto)
5  common.skip('missing crypto');
6const assert = require('assert');
7const h2 = require('http2');
8
9const server = h2.createServer();
10server.on('stream', (stream) => {
11  stream.on('close', common.mustCall());
12  stream.respond();
13  stream.end('ok');
14});
15
16server.listen(0, common.mustCall(() => {
17  const client = h2.connect(`http://localhost:${server.address().port}`);
18  const req = client.request();
19  const closeCode = 1;
20
21  assert.throws(
22    () => req.close(2 ** 32),
23    {
24      name: 'RangeError',
25      code: 'ERR_OUT_OF_RANGE',
26      message: 'The value of "code" is out of range. It must be ' +
27               '>= 0 && <= 4294967295. Received 4294967296'
28    }
29  );
30  assert.strictEqual(req.closed, false);
31
32  [true, 1, {}, [], null, 'test'].forEach((notFunction) => {
33    assert.throws(
34      () => req.close(closeCode, notFunction),
35      {
36        name: 'TypeError',
37        code: 'ERR_INVALID_ARG_TYPE',
38      }
39    );
40    assert.strictEqual(req.closed, false);
41  });
42
43  req.close(closeCode, common.mustCall());
44  assert.strictEqual(req.closed, true);
45
46  // Make sure that destroy is called.
47  req._destroy = common.mustCall(req._destroy.bind(req));
48
49  // Second call doesn't do anything.
50  req.close(closeCode + 1);
51
52  req.on('close', common.mustCall(() => {
53    assert.strictEqual(req.destroyed, true);
54    assert.strictEqual(req.rstCode, closeCode);
55    server.close();
56    client.close();
57  }));
58
59  req.on('error', common.expectsError({
60    code: 'ERR_HTTP2_STREAM_ERROR',
61    name: 'Error',
62    message: 'Stream closed with error code NGHTTP2_PROTOCOL_ERROR'
63  }));
64
65  // The `response` event should not fire as the server should receive the
66  // RST_STREAM frame before it ever has a chance to reply.
67  req.on('response', common.mustNotCall());
68
69  // The `end` event should still fire as we close the readable stream by
70  // pushing a `null` chunk.
71  req.on('end', common.mustCall());
72
73  req.resume();
74  req.end();
75}));
76