11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciif (!common.hasCrypto)
51cb0ef41Sopenharmony_ci  common.skip('missing crypto');
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst h2 = require('http2');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst server = h2.createServer();
101cb0ef41Sopenharmony_ciserver.on('stream', (stream) => {
111cb0ef41Sopenharmony_ci  stream.on('close', common.mustCall());
121cb0ef41Sopenharmony_ci  stream.respond();
131cb0ef41Sopenharmony_ci  stream.end('ok');
141cb0ef41Sopenharmony_ci});
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => {
171cb0ef41Sopenharmony_ci  const client = h2.connect(`http://localhost:${server.address().port}`);
181cb0ef41Sopenharmony_ci  const req = client.request();
191cb0ef41Sopenharmony_ci  const closeCode = 1;
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci  assert.throws(
221cb0ef41Sopenharmony_ci    () => req.close(2 ** 32),
231cb0ef41Sopenharmony_ci    {
241cb0ef41Sopenharmony_ci      name: 'RangeError',
251cb0ef41Sopenharmony_ci      code: 'ERR_OUT_OF_RANGE',
261cb0ef41Sopenharmony_ci      message: 'The value of "code" is out of range. It must be ' +
271cb0ef41Sopenharmony_ci               '>= 0 && <= 4294967295. Received 4294967296'
281cb0ef41Sopenharmony_ci    }
291cb0ef41Sopenharmony_ci  );
301cb0ef41Sopenharmony_ci  assert.strictEqual(req.closed, false);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  [true, 1, {}, [], null, 'test'].forEach((notFunction) => {
331cb0ef41Sopenharmony_ci    assert.throws(
341cb0ef41Sopenharmony_ci      () => req.close(closeCode, notFunction),
351cb0ef41Sopenharmony_ci      {
361cb0ef41Sopenharmony_ci        name: 'TypeError',
371cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
381cb0ef41Sopenharmony_ci      }
391cb0ef41Sopenharmony_ci    );
401cb0ef41Sopenharmony_ci    assert.strictEqual(req.closed, false);
411cb0ef41Sopenharmony_ci  });
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  req.close(closeCode, common.mustCall());
441cb0ef41Sopenharmony_ci  assert.strictEqual(req.closed, true);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  // Make sure that destroy is called.
471cb0ef41Sopenharmony_ci  req._destroy = common.mustCall(req._destroy.bind(req));
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  // Second call doesn't do anything.
501cb0ef41Sopenharmony_ci  req.close(closeCode + 1);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  req.on('close', common.mustCall(() => {
531cb0ef41Sopenharmony_ci    assert.strictEqual(req.destroyed, true);
541cb0ef41Sopenharmony_ci    assert.strictEqual(req.rstCode, closeCode);
551cb0ef41Sopenharmony_ci    server.close();
561cb0ef41Sopenharmony_ci    client.close();
571cb0ef41Sopenharmony_ci  }));
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  req.on('error', common.expectsError({
601cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_STREAM_ERROR',
611cb0ef41Sopenharmony_ci    name: 'Error',
621cb0ef41Sopenharmony_ci    message: 'Stream closed with error code NGHTTP2_PROTOCOL_ERROR'
631cb0ef41Sopenharmony_ci  }));
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  // The `response` event should not fire as the server should receive the
661cb0ef41Sopenharmony_ci  // RST_STREAM frame before it ever has a chance to reply.
671cb0ef41Sopenharmony_ci  req.on('response', common.mustNotCall());
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  // The `end` event should still fire as we close the readable stream by
701cb0ef41Sopenharmony_ci  // pushing a `null` chunk.
711cb0ef41Sopenharmony_ci  req.on('end', common.mustCall());
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  req.resume();
741cb0ef41Sopenharmony_ci  req.end();
751cb0ef41Sopenharmony_ci}));
76