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