11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciif (!common.hasCrypto)
51cb0ef41Sopenharmony_ci  common.skip('missing crypto');
61cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ciconst http2 = require('http2');
91cb0ef41Sopenharmony_ciconst fs = require('fs');
101cb0ef41Sopenharmony_ciconst { inspect } = require('util');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst optionsWithTypeError = {
131cb0ef41Sopenharmony_ci  offset: 'number',
141cb0ef41Sopenharmony_ci  length: 'number',
151cb0ef41Sopenharmony_ci  statCheck: 'function'
161cb0ef41Sopenharmony_ci};
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciconst types = {
191cb0ef41Sopenharmony_ci  boolean: true,
201cb0ef41Sopenharmony_ci  function: () => {},
211cb0ef41Sopenharmony_ci  number: 1,
221cb0ef41Sopenharmony_ci  object: {},
231cb0ef41Sopenharmony_ci  array: [],
241cb0ef41Sopenharmony_ci  null: null,
251cb0ef41Sopenharmony_ci  symbol: Symbol('test')
261cb0ef41Sopenharmony_ci};
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciconst fname = fixtures.path('elipses.txt');
291cb0ef41Sopenharmony_ciconst fd = fs.openSync(fname, 'r');
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciconst server = http2.createServer();
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciserver.on('stream', common.mustCall((stream) => {
341cb0ef41Sopenharmony_ci  // Should throw if fd isn't a number
351cb0ef41Sopenharmony_ci  Object.keys(types).forEach((type) => {
361cb0ef41Sopenharmony_ci    if (type === 'number') {
371cb0ef41Sopenharmony_ci      return;
381cb0ef41Sopenharmony_ci    }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci    assert.throws(
411cb0ef41Sopenharmony_ci      () => stream.respondWithFD(types[type], {
421cb0ef41Sopenharmony_ci        'content-type': 'text/plain'
431cb0ef41Sopenharmony_ci      }),
441cb0ef41Sopenharmony_ci      {
451cb0ef41Sopenharmony_ci        name: 'TypeError',
461cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
471cb0ef41Sopenharmony_ci        message: 'The "fd" argument must be of type number or an instance of' +
481cb0ef41Sopenharmony_ci                 ` FileHandle.${common.invalidArgTypeHelper(types[type])}`
491cb0ef41Sopenharmony_ci      }
501cb0ef41Sopenharmony_ci    );
511cb0ef41Sopenharmony_ci  });
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  // Check for all possible TypeError triggers on options
541cb0ef41Sopenharmony_ci  Object.keys(optionsWithTypeError).forEach((option) => {
551cb0ef41Sopenharmony_ci    Object.keys(types).forEach((type) => {
561cb0ef41Sopenharmony_ci      if (type === optionsWithTypeError[option]) {
571cb0ef41Sopenharmony_ci        return;
581cb0ef41Sopenharmony_ci      }
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci      assert.throws(
611cb0ef41Sopenharmony_ci        () => stream.respondWithFD(fd, {
621cb0ef41Sopenharmony_ci          'content-type': 'text/plain'
631cb0ef41Sopenharmony_ci        }, {
641cb0ef41Sopenharmony_ci          [option]: types[type]
651cb0ef41Sopenharmony_ci        }),
661cb0ef41Sopenharmony_ci        {
671cb0ef41Sopenharmony_ci          name: 'TypeError',
681cb0ef41Sopenharmony_ci          code: 'ERR_INVALID_ARG_VALUE',
691cb0ef41Sopenharmony_ci          message: `The property 'options.${option}' is invalid. ` +
701cb0ef41Sopenharmony_ci            `Received ${inspect(types[type])}`
711cb0ef41Sopenharmony_ci        }
721cb0ef41Sopenharmony_ci      );
731cb0ef41Sopenharmony_ci    });
741cb0ef41Sopenharmony_ci  });
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  // Should throw if :status 204, 205 or 304
771cb0ef41Sopenharmony_ci  [204, 205, 304].forEach((status) => assert.throws(
781cb0ef41Sopenharmony_ci    () => stream.respondWithFD(fd, {
791cb0ef41Sopenharmony_ci      'content-type': 'text/plain',
801cb0ef41Sopenharmony_ci      ':status': status,
811cb0ef41Sopenharmony_ci    }),
821cb0ef41Sopenharmony_ci    {
831cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_PAYLOAD_FORBIDDEN',
841cb0ef41Sopenharmony_ci      name: 'Error',
851cb0ef41Sopenharmony_ci      message: `Responses with ${status} status must not have a payload`
861cb0ef41Sopenharmony_ci    }
871cb0ef41Sopenharmony_ci  ));
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  // Should throw if headers already sent
901cb0ef41Sopenharmony_ci  stream.respond();
911cb0ef41Sopenharmony_ci  assert.throws(
921cb0ef41Sopenharmony_ci    () => stream.respondWithFD(fd, {
931cb0ef41Sopenharmony_ci      'content-type': 'text/plain'
941cb0ef41Sopenharmony_ci    }),
951cb0ef41Sopenharmony_ci    {
961cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_HEADERS_SENT',
971cb0ef41Sopenharmony_ci      name: 'Error',
981cb0ef41Sopenharmony_ci      message: 'Response has already been initiated.'
991cb0ef41Sopenharmony_ci    }
1001cb0ef41Sopenharmony_ci  );
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  // Should throw if stream already destroyed
1031cb0ef41Sopenharmony_ci  stream.destroy();
1041cb0ef41Sopenharmony_ci  assert.throws(
1051cb0ef41Sopenharmony_ci    () => stream.respondWithFD(fd, {
1061cb0ef41Sopenharmony_ci      'content-type': 'text/plain'
1071cb0ef41Sopenharmony_ci    }),
1081cb0ef41Sopenharmony_ci    {
1091cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_INVALID_STREAM',
1101cb0ef41Sopenharmony_ci      name: 'Error',
1111cb0ef41Sopenharmony_ci      message: 'The stream has been destroyed'
1121cb0ef41Sopenharmony_ci    }
1131cb0ef41Sopenharmony_ci  );
1141cb0ef41Sopenharmony_ci}));
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => {
1171cb0ef41Sopenharmony_ci  const client = http2.connect(`http://localhost:${server.address().port}`);
1181cb0ef41Sopenharmony_ci  const req = client.request();
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  req.on('close', common.mustCall(() => {
1211cb0ef41Sopenharmony_ci    client.close();
1221cb0ef41Sopenharmony_ci    server.close();
1231cb0ef41Sopenharmony_ci  }));
1241cb0ef41Sopenharmony_ci  req.end();
1251cb0ef41Sopenharmony_ci}));
126