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_ci// Http2ServerResponse should support checking and reading custom headers
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciconst server = h2.createServer();
121cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(function() {
131cb0ef41Sopenharmony_ci  const port = server.address().port;
141cb0ef41Sopenharmony_ci  server.once('request', common.mustCall(function(request, response) {
151cb0ef41Sopenharmony_ci    const real = 'foo-bar';
161cb0ef41Sopenharmony_ci    const fake = 'bar-foo';
171cb0ef41Sopenharmony_ci    const denormalised = ` ${real.toUpperCase()}\n\t`;
181cb0ef41Sopenharmony_ci    const expectedValue = 'abc123';
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci    response.setHeader(real, expectedValue);
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(real), true);
231cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(fake), false);
241cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(denormalised), true);
251cb0ef41Sopenharmony_ci    assert.strictEqual(response.getHeader(real), expectedValue);
261cb0ef41Sopenharmony_ci    assert.strictEqual(response.getHeader(denormalised), expectedValue);
271cb0ef41Sopenharmony_ci    assert.strictEqual(response.getHeader(fake), undefined);
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci    response.removeHeader(fake);
301cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(fake), false);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci    response.setHeader(real, expectedValue);
331cb0ef41Sopenharmony_ci    assert.strictEqual(response.getHeader(real), expectedValue);
341cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(real), true);
351cb0ef41Sopenharmony_ci    response.removeHeader(real);
361cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(real), false);
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci    response.setHeader(denormalised, expectedValue);
391cb0ef41Sopenharmony_ci    assert.strictEqual(response.getHeader(denormalised), expectedValue);
401cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(denormalised), true);
411cb0ef41Sopenharmony_ci    response.removeHeader(denormalised);
421cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(denormalised), false);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci    ['hasHeader', 'getHeader', 'removeHeader'].forEach((fnName) => {
451cb0ef41Sopenharmony_ci      assert.throws(
461cb0ef41Sopenharmony_ci        () => response[fnName](),
471cb0ef41Sopenharmony_ci        {
481cb0ef41Sopenharmony_ci          code: 'ERR_INVALID_ARG_TYPE',
491cb0ef41Sopenharmony_ci          name: 'TypeError',
501cb0ef41Sopenharmony_ci          message: 'The "name" argument must be of type string. Received ' +
511cb0ef41Sopenharmony_ci                   'undefined'
521cb0ef41Sopenharmony_ci        }
531cb0ef41Sopenharmony_ci      );
541cb0ef41Sopenharmony_ci    });
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci    [
571cb0ef41Sopenharmony_ci      ':status',
581cb0ef41Sopenharmony_ci      ':method',
591cb0ef41Sopenharmony_ci      ':path',
601cb0ef41Sopenharmony_ci      ':authority',
611cb0ef41Sopenharmony_ci      ':scheme',
621cb0ef41Sopenharmony_ci    ].forEach((header) => assert.throws(
631cb0ef41Sopenharmony_ci      () => response.setHeader(header, 'foobar'),
641cb0ef41Sopenharmony_ci      {
651cb0ef41Sopenharmony_ci        code: 'ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED',
661cb0ef41Sopenharmony_ci        name: 'TypeError',
671cb0ef41Sopenharmony_ci        message: 'Cannot set HTTP/2 pseudo-headers'
681cb0ef41Sopenharmony_ci      })
691cb0ef41Sopenharmony_ci    );
701cb0ef41Sopenharmony_ci    assert.throws(() => {
711cb0ef41Sopenharmony_ci      response.setHeader(real, null);
721cb0ef41Sopenharmony_ci    }, {
731cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_INVALID_HEADER_VALUE',
741cb0ef41Sopenharmony_ci      name: 'TypeError',
751cb0ef41Sopenharmony_ci      message: 'Invalid value "null" for header "foo-bar"'
761cb0ef41Sopenharmony_ci    });
771cb0ef41Sopenharmony_ci    assert.throws(() => {
781cb0ef41Sopenharmony_ci      response.setHeader(real, undefined);
791cb0ef41Sopenharmony_ci    }, {
801cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_INVALID_HEADER_VALUE',
811cb0ef41Sopenharmony_ci      name: 'TypeError',
821cb0ef41Sopenharmony_ci      message: 'Invalid value "undefined" for header "foo-bar"'
831cb0ef41Sopenharmony_ci    });
841cb0ef41Sopenharmony_ci    assert.throws(
851cb0ef41Sopenharmony_ci      () => response.setHeader(), // Header name undefined
861cb0ef41Sopenharmony_ci      {
871cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
881cb0ef41Sopenharmony_ci        name: 'TypeError',
891cb0ef41Sopenharmony_ci        message: 'The "name" argument must be of type string. Received ' +
901cb0ef41Sopenharmony_ci                 'undefined'
911cb0ef41Sopenharmony_ci      }
921cb0ef41Sopenharmony_ci    );
931cb0ef41Sopenharmony_ci    assert.throws(
941cb0ef41Sopenharmony_ci      () => response.setHeader(''),
951cb0ef41Sopenharmony_ci      {
961cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_HTTP_TOKEN',
971cb0ef41Sopenharmony_ci        name: 'TypeError',
981cb0ef41Sopenharmony_ci        message: 'Header name must be a valid HTTP token [""]'
991cb0ef41Sopenharmony_ci      }
1001cb0ef41Sopenharmony_ci    );
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci    response.setHeader(real, expectedValue);
1031cb0ef41Sopenharmony_ci    const expectedHeaderNames = [real];
1041cb0ef41Sopenharmony_ci    assert.deepStrictEqual(response.getHeaderNames(), expectedHeaderNames);
1051cb0ef41Sopenharmony_ci    const expectedHeaders = Object.create(null);
1061cb0ef41Sopenharmony_ci    expectedHeaders[real] = expectedValue;
1071cb0ef41Sopenharmony_ci    assert.deepStrictEqual(response.getHeaders(), expectedHeaders);
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci    response.getHeaders()[fake] = fake;
1101cb0ef41Sopenharmony_ci    assert.strictEqual(response.hasHeader(fake), false);
1111cb0ef41Sopenharmony_ci    assert.strictEqual(Object.getPrototypeOf(response.getHeaders()), null);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci    assert.strictEqual(response.sendDate, true);
1141cb0ef41Sopenharmony_ci    response.sendDate = false;
1151cb0ef41Sopenharmony_ci    assert.strictEqual(response.sendDate, false);
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci    response.sendDate = true;
1181cb0ef41Sopenharmony_ci    assert.strictEqual(response.sendDate, true);
1191cb0ef41Sopenharmony_ci    response.removeHeader('Date');
1201cb0ef41Sopenharmony_ci    assert.strictEqual(response.sendDate, false);
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci    response.on('finish', common.mustCall(function() {
1231cb0ef41Sopenharmony_ci      assert.strictEqual(response.headersSent, true);
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci      assert.throws(
1261cb0ef41Sopenharmony_ci        () => response.setHeader(real, expectedValue),
1271cb0ef41Sopenharmony_ci        {
1281cb0ef41Sopenharmony_ci          code: 'ERR_HTTP2_HEADERS_SENT',
1291cb0ef41Sopenharmony_ci          name: 'Error',
1301cb0ef41Sopenharmony_ci          message: 'Response has already been initiated.'
1311cb0ef41Sopenharmony_ci        }
1321cb0ef41Sopenharmony_ci      );
1331cb0ef41Sopenharmony_ci      assert.throws(
1341cb0ef41Sopenharmony_ci        () => response.removeHeader(real, expectedValue),
1351cb0ef41Sopenharmony_ci        {
1361cb0ef41Sopenharmony_ci          code: 'ERR_HTTP2_HEADERS_SENT',
1371cb0ef41Sopenharmony_ci          name: 'Error',
1381cb0ef41Sopenharmony_ci          message: 'Response has already been initiated.'
1391cb0ef41Sopenharmony_ci        }
1401cb0ef41Sopenharmony_ci      );
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci      process.nextTick(() => {
1431cb0ef41Sopenharmony_ci        assert.throws(
1441cb0ef41Sopenharmony_ci          () => response.setHeader(real, expectedValue),
1451cb0ef41Sopenharmony_ci          {
1461cb0ef41Sopenharmony_ci            code: 'ERR_HTTP2_HEADERS_SENT',
1471cb0ef41Sopenharmony_ci            name: 'Error',
1481cb0ef41Sopenharmony_ci            message: 'Response has already been initiated.'
1491cb0ef41Sopenharmony_ci          }
1501cb0ef41Sopenharmony_ci        );
1511cb0ef41Sopenharmony_ci        assert.throws(
1521cb0ef41Sopenharmony_ci          () => response.removeHeader(real, expectedValue),
1531cb0ef41Sopenharmony_ci          {
1541cb0ef41Sopenharmony_ci            code: 'ERR_HTTP2_HEADERS_SENT',
1551cb0ef41Sopenharmony_ci            name: 'Error',
1561cb0ef41Sopenharmony_ci            message: 'Response has already been initiated.'
1571cb0ef41Sopenharmony_ci          }
1581cb0ef41Sopenharmony_ci        );
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci        assert.strictEqual(response.headersSent, true);
1611cb0ef41Sopenharmony_ci        server.close();
1621cb0ef41Sopenharmony_ci      });
1631cb0ef41Sopenharmony_ci    }));
1641cb0ef41Sopenharmony_ci    response.end();
1651cb0ef41Sopenharmony_ci  }));
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  const url = `http://localhost:${port}`;
1681cb0ef41Sopenharmony_ci  const client = h2.connect(url, common.mustCall(function() {
1691cb0ef41Sopenharmony_ci    const headers = {
1701cb0ef41Sopenharmony_ci      ':path': '/',
1711cb0ef41Sopenharmony_ci      ':method': 'GET',
1721cb0ef41Sopenharmony_ci      ':scheme': 'http',
1731cb0ef41Sopenharmony_ci      ':authority': `localhost:${port}`
1741cb0ef41Sopenharmony_ci    };
1751cb0ef41Sopenharmony_ci    const request = client.request(headers);
1761cb0ef41Sopenharmony_ci    request.on('end', common.mustCall(function() {
1771cb0ef41Sopenharmony_ci      client.close();
1781cb0ef41Sopenharmony_ci    }));
1791cb0ef41Sopenharmony_ci    request.end();
1801cb0ef41Sopenharmony_ci    request.resume();
1811cb0ef41Sopenharmony_ci  }));
1821cb0ef41Sopenharmony_ci}));
183