11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  mustCall,
51cb0ef41Sopenharmony_ci  hasCrypto,
61cb0ef41Sopenharmony_ci  hasIPv6,
71cb0ef41Sopenharmony_ci  skip,
81cb0ef41Sopenharmony_ci  expectsError
91cb0ef41Sopenharmony_ci} = require('../common');
101cb0ef41Sopenharmony_ciif (!hasCrypto)
111cb0ef41Sopenharmony_ci  skip('missing crypto');
121cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
131cb0ef41Sopenharmony_ciconst assert = require('assert');
141cb0ef41Sopenharmony_ciconst { createServer, createSecureServer, connect } = require('http2');
151cb0ef41Sopenharmony_ciconst { connect: netConnect } = require('net');
161cb0ef41Sopenharmony_ciconst { connect: tlsConnect } = require('tls');
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci// Check for session connect callback and event
191cb0ef41Sopenharmony_ci{
201cb0ef41Sopenharmony_ci  const server = createServer();
211cb0ef41Sopenharmony_ci  server.listen(0, mustCall(() => {
221cb0ef41Sopenharmony_ci    const authority = `http://localhost:${server.address().port}`;
231cb0ef41Sopenharmony_ci    const options = {};
241cb0ef41Sopenharmony_ci    const listener = () => mustCall();
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci    const clients = new Set();
271cb0ef41Sopenharmony_ci    // Should not throw.
281cb0ef41Sopenharmony_ci    clients.add(connect(authority));
291cb0ef41Sopenharmony_ci    clients.add(connect(authority, options));
301cb0ef41Sopenharmony_ci    clients.add(connect(authority, options, listener()));
311cb0ef41Sopenharmony_ci    clients.add(connect(authority, listener()));
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci    for (const client of clients) {
341cb0ef41Sopenharmony_ci      client.once('connect', mustCall((headers) => {
351cb0ef41Sopenharmony_ci        client.close();
361cb0ef41Sopenharmony_ci        clients.delete(client);
371cb0ef41Sopenharmony_ci        if (clients.size === 0) {
381cb0ef41Sopenharmony_ci          server.close();
391cb0ef41Sopenharmony_ci        }
401cb0ef41Sopenharmony_ci      }));
411cb0ef41Sopenharmony_ci    }
421cb0ef41Sopenharmony_ci  }));
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci// Check for session connect callback on already connected socket
461cb0ef41Sopenharmony_ci{
471cb0ef41Sopenharmony_ci  const server = createServer();
481cb0ef41Sopenharmony_ci  server.listen(0, mustCall(() => {
491cb0ef41Sopenharmony_ci    const { port } = server.address();
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci    const onSocketConnect = () => {
521cb0ef41Sopenharmony_ci      const authority = `http://localhost:${port}`;
531cb0ef41Sopenharmony_ci      const createConnection = mustCall(() => socket);
541cb0ef41Sopenharmony_ci      const options = { createConnection };
551cb0ef41Sopenharmony_ci      connect(authority, options, mustCall(onSessionConnect));
561cb0ef41Sopenharmony_ci    };
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    const onSessionConnect = (session) => {
591cb0ef41Sopenharmony_ci      session.close();
601cb0ef41Sopenharmony_ci      server.close();
611cb0ef41Sopenharmony_ci    };
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci    const socket = netConnect(port, mustCall(onSocketConnect));
641cb0ef41Sopenharmony_ci  }));
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci// Check for https as protocol
681cb0ef41Sopenharmony_ci{
691cb0ef41Sopenharmony_ci  const authority = 'https://localhost';
701cb0ef41Sopenharmony_ci  // A socket error may or may not be reported, keep this as a non-op
711cb0ef41Sopenharmony_ci  // instead of a mustCall or mustNotCall
721cb0ef41Sopenharmony_ci  connect(authority).on('error', () => {});
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci// Check for session connect callback on already connected TLS socket
761cb0ef41Sopenharmony_ci{
771cb0ef41Sopenharmony_ci  const serverOptions = {
781cb0ef41Sopenharmony_ci    key: fixtures.readKey('agent1-key.pem'),
791cb0ef41Sopenharmony_ci    cert: fixtures.readKey('agent1-cert.pem')
801cb0ef41Sopenharmony_ci  };
811cb0ef41Sopenharmony_ci  const server = createSecureServer(serverOptions);
821cb0ef41Sopenharmony_ci  server.listen(0, mustCall(() => {
831cb0ef41Sopenharmony_ci    const { port } = server.address();
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci    const onSocketConnect = () => {
861cb0ef41Sopenharmony_ci      const authority = `https://localhost:${port}`;
871cb0ef41Sopenharmony_ci      const createConnection = mustCall(() => socket);
881cb0ef41Sopenharmony_ci      const options = { createConnection };
891cb0ef41Sopenharmony_ci      connect(authority, options, mustCall(onSessionConnect));
901cb0ef41Sopenharmony_ci    };
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci    const onSessionConnect = (session) => {
931cb0ef41Sopenharmony_ci      session.close();
941cb0ef41Sopenharmony_ci      server.close();
951cb0ef41Sopenharmony_ci    };
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci    const clientOptions = {
981cb0ef41Sopenharmony_ci      ALPNProtocols: ['h2'],
991cb0ef41Sopenharmony_ci      port,
1001cb0ef41Sopenharmony_ci      rejectUnauthorized: false
1011cb0ef41Sopenharmony_ci    };
1021cb0ef41Sopenharmony_ci    const socket = tlsConnect(clientOptions, mustCall(onSocketConnect));
1031cb0ef41Sopenharmony_ci  }));
1041cb0ef41Sopenharmony_ci}
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci// Check for error for init settings error
1071cb0ef41Sopenharmony_ci{
1081cb0ef41Sopenharmony_ci  createServer(function() {
1091cb0ef41Sopenharmony_ci    connect(`http://localhost:${this.address().port}`, {
1101cb0ef41Sopenharmony_ci      settings: {
1111cb0ef41Sopenharmony_ci        maxFrameSize: 1   // An incorrect settings
1121cb0ef41Sopenharmony_ci      }
1131cb0ef41Sopenharmony_ci    }).on('error', expectsError({
1141cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
1151cb0ef41Sopenharmony_ci      name: 'RangeError'
1161cb0ef41Sopenharmony_ci    }));
1171cb0ef41Sopenharmony_ci  });
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci// Check for error for an invalid protocol (not http or https)
1211cb0ef41Sopenharmony_ci{
1221cb0ef41Sopenharmony_ci  const authority = 'ssh://localhost';
1231cb0ef41Sopenharmony_ci  assert.throws(() => {
1241cb0ef41Sopenharmony_ci    connect(authority);
1251cb0ef41Sopenharmony_ci  }, {
1261cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_UNSUPPORTED_PROTOCOL',
1271cb0ef41Sopenharmony_ci    name: 'Error'
1281cb0ef41Sopenharmony_ci  });
1291cb0ef41Sopenharmony_ci}
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci// Check for literal IPv6 addresses in URL's
1321cb0ef41Sopenharmony_ciif (hasIPv6) {
1331cb0ef41Sopenharmony_ci  const server = createServer();
1341cb0ef41Sopenharmony_ci  server.listen(0, '::1', mustCall(() => {
1351cb0ef41Sopenharmony_ci    const { port } = server.address();
1361cb0ef41Sopenharmony_ci    const clients = new Set();
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci    clients.add(connect(`http://[::1]:${port}`));
1391cb0ef41Sopenharmony_ci    clients.add(connect(new URL(`http://[::1]:${port}`)));
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci    for (const client of clients) {
1421cb0ef41Sopenharmony_ci      client.once('connect', mustCall(() => {
1431cb0ef41Sopenharmony_ci        client.close();
1441cb0ef41Sopenharmony_ci        clients.delete(client);
1451cb0ef41Sopenharmony_ci        if (clients.size === 0) {
1461cb0ef41Sopenharmony_ci          server.close();
1471cb0ef41Sopenharmony_ci        }
1481cb0ef41Sopenharmony_ci      }));
1491cb0ef41Sopenharmony_ci    }
1501cb0ef41Sopenharmony_ci  }));
1511cb0ef41Sopenharmony_ci}
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci// Check that `options.host` and `options.port` take precedence over
1541cb0ef41Sopenharmony_ci// `authority.host` and `authority.port`.
1551cb0ef41Sopenharmony_ci{
1561cb0ef41Sopenharmony_ci  const server = createServer();
1571cb0ef41Sopenharmony_ci  server.listen(0, mustCall(() => {
1581cb0ef41Sopenharmony_ci    connect('http://foo.bar', {
1591cb0ef41Sopenharmony_ci      host: 'localhost',
1601cb0ef41Sopenharmony_ci      port: server.address().port
1611cb0ef41Sopenharmony_ci    }, mustCall((session) => {
1621cb0ef41Sopenharmony_ci      session.close();
1631cb0ef41Sopenharmony_ci      server.close();
1641cb0ef41Sopenharmony_ci    }));
1651cb0ef41Sopenharmony_ci  }));
1661cb0ef41Sopenharmony_ci}
167