// Flags: --no-warnings 'use strict'; // Tests that both client and server can open // bidirectional and unidirectional streams, // and that the properties for each are set // accordingly. // // +------+----------------------------------+ // | ID | Stream Type | // +------+----------------------------------+ // | 0 | Client-Initiated, Bidirectional | // | | | // | 1 | Server-Initiated, Bidirectional | // | | | // | 2 | Client-Initiated, Unidirectional | // | | | // | 3 | Server-Initiated, Unidirectional | // +------+----------------------------------+ const common = require('../common'); if (!common.hasQuic) common.skip('missing quic'); const Countdown = require('../common/countdown'); const assert = require('assert'); const { once } = require('events'); const { key, cert, ca } = require('../common/quic'); const { createQuicSocket } = require('net'); const options = { key, cert, ca, alpn: 'zzz' }; const client = createQuicSocket({ client: options }); const server = createQuicSocket({ server: options }); const countdown = new Countdown(4, () => { server.close(); client.close(); }); const closeHandler = common.mustCall(() => countdown.dec(), 4); (async function() { server.on('session', common.mustCall(async (session) => { ([3, 1n, [], {}, null, 'meow']).forEach((halfOpen) => { assert.rejects( session.openStream({ halfOpen }), { code: 'ERR_INVALID_ARG_TYPE' }); }); const uni = await session.openStream({ halfOpen: true }); uni.end('test'); const bidi = await session.openStream(); bidi.end('test'); bidi.resume(); bidi.on('end', common.mustCall()); assert.strictEqual(uni.id, 3); assert(uni.unidirectional); assert(uni.serverInitiated); assert(!uni.bidirectional); assert(!uni.clientInitiated); assert.strictEqual(bidi.id, 1); assert(bidi.bidirectional); assert(bidi.serverInitiated); assert(!bidi.unidirectional); assert(!bidi.clientInitiated); session.on('stream', common.mustCall((stream) => { assert(stream.clientInitiated); assert(!stream.serverInitiated); switch (stream.id) { case 0: assert(stream.bidirectional); assert(!stream.unidirectional); stream.end('test'); break; case 2: assert(stream.unidirectional); assert(!stream.bidirectional); break; } stream.resume(); stream.on('end', common.mustCall()); }, 2)); })); await server.listen(); const req = await client.connect({ address: common.localhostIPv4, port: server.endpoints[0].address.port, }); const bidi = await req.openStream(); bidi.end('test'); bidi.resume(); bidi.on('close', closeHandler); assert.strictEqual(bidi.id, 0); assert(bidi.clientInitiated); assert(bidi.bidirectional); assert(!bidi.serverInitiated); assert(!bidi.unidirectional); const uni = await req.openStream({ halfOpen: true }); uni.end('test'); uni.on('close', closeHandler); assert.strictEqual(uni.id, 2); assert(uni.clientInitiated); assert(!uni.bidirectional); assert(!uni.serverInitiated); assert(uni.unidirectional); req.on('stream', common.mustCall((stream) => { assert(stream.serverInitiated); assert(!stream.clientInitiated); switch (stream.id) { case 1: assert(!stream.unidirectional); assert(stream.bidirectional); stream.end(); break; case 3: assert(stream.unidirectional); assert(!stream.bidirectional); } stream.resume(); stream.on('end', common.mustCall()); stream.on('close', closeHandler); }, 2)); await Promise.all([ once(server, 'close'), once(client, 'close') ]); })().then(common.mustCall());