| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3b59d12 commit 147150c
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -511,6 +511,21 @@ with either a `QuicEndpoint` or `EndpointOptions` as the argument. | |||
| 511 | 511 | At most, any single `QuicEndpoint` can only be configured to listen as | |
| 512 | 512 | a server once. | |
| 513 | 513 | ||
| 514 | + ## `quic.listEndpoints([options])` | ||
| 515 | + | ||
| 516 | + <!-- YAML | ||
| 517 | + added: REPLACEME | ||
| 518 | + --> | ||
| 519 | + | ||
| 520 | + * `options` {object} | ||
| 521 | + * `active` {boolean} If `true` (the default), only returns endpoints that are | ||
| 522 | + active (not destroyed, not closing, and not busy). If `false` returns all | ||
| 523 | + endpoints. | ||
| 524 | + * Returns: {quic.QuicEndpoint\[]} | ||
| 525 | + | ||
| 526 | + Returns the list of all `QuicEndpoint` instances. By default, only active | ||
| 527 | + endpoints are returned. | ||
| 528 | + | ||
| 514 | 529 | ## `quic.constants` | |
| 515 | 530 | ||
| 516 | 531 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,6 +5,7 @@ | |||
| 5 | 5 | /* c8 ignore start */ | |
| 6 | 6 | ||
| 7 | 7 | const { | |
| 8 | + ArrayFrom, | ||
| 8 | 9 | ArrayIsArray, | |
| 9 | 10 | ArrayPrototypePush, | |
| 10 | 11 | BigInt, | |
@@ -4737,6 +4738,24 @@ function findSuitableEndpoint(targetAddress) { | |||
| 4737 | 4738 | return undefined; | |
| 4738 | 4739 | } | |
| 4739 | 4740 | ||
| 4741 | + /** | ||
| 4742 | + * Returns a list of all active endpoints. | ||
| 4743 | + * @param {object} [options] | ||
| 4744 | + * @param {boolean} [options.active] When true, only return endpoints that are not destroyed, closing, or busy. | ||
| 4745 | + * @returns {QuicEndpoint[]} | ||
| 4746 | + */ | ||
| 4747 | + function listEndpoints(options = kEmptyObject) { | ||
| 4748 | + validateObject(options, 'options'); | ||
| 4749 | + const { active = true } = options; | ||
| 4750 | + validateBoolean(active, 'options.active'); | ||
| 4751 | + if (!active) { | ||
| 4752 | + return ArrayFrom(endpointRegistry); | ||
| 4753 | + } | ||
| 4754 | + return ArrayFrom(endpointRegistry).filter((endpoint) => { | ||
| 4755 | + return !endpoint.destroyed && !endpoint.closing && !endpoint.busy; | ||
| 4756 | + }); | ||
| 4757 | + } | ||
| 4758 | + | ||
| 4740 | 4759 | /** | |
| 4741 | 4760 | * @param {EndpointOptions|QuicEndpoint|undefined} endpoint | |
| 4742 | 4761 | * @param {boolean} reuseEndpoint | |
@@ -5340,6 +5359,7 @@ module.exports = { | |||
| 5340 | 5359 | getQuicStreamState, | |
| 5341 | 5360 | getQuicSessionState, | |
| 5342 | 5361 | getQuicEndpointState, | |
| 5362 | + listEndpoints, | ||
| 5343 | 5363 | }; | |
| 5344 | 5364 | ||
| 5345 | 5365 | /* c8 ignore stop */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,10 +1,5 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | - const { | ||
| 4 | - ObjectCreate, | ||
| 5 | - ObjectSeal, | ||
| 6 | - } = primordials; | ||
| 7 | - | ||
| 8 | 3 | const { | |
| 9 | 4 | emitExperimentalWarning, | |
| 10 | 5 | } = require('internal/util'); | |
@@ -24,43 +19,32 @@ const { | |||
| 24 | 19 | DEFAULT_GROUPS, | |
| 25 | 20 | } = require('internal/quic/quic'); | |
| 26 | 21 | ||
| 27 | - function getEnumerableConstant(value) { | ||
| 28 | - return { | ||
| 29 | - __proto__: null, | ||
| 30 | - value, | ||
| 31 | - enumerable: true, | ||
| 32 | - configurable: false, | ||
| 33 | - writable: false, | ||
| 34 | - }; | ||
| 35 | - } | ||
| 36 | - | ||
| 37 | - const cc = ObjectSeal(ObjectCreate(null, { | ||
| 38 | - __proto__: null, | ||
| 39 | - RENO: getEnumerableConstant(CC_ALGO_RENO), | ||
| 40 | - CUBIC: getEnumerableConstant(CC_ALGO_CUBIC), | ||
| 41 | - BBR: getEnumerableConstant(CC_ALGO_BBR), | ||
| 42 | - })); | ||
| 22 | + const cc = { | ||
| 23 | + get RENO() { return CC_ALGO_RENO; }, | ||
| 24 | + get CUBIC() { return CC_ALGO_CUBIC; }, | ||
| 25 | + get BBR() { return CC_ALGO_BBR; }, | ||
| 26 | + }; | ||
| 43 | 27 | ||
| 44 | - const constants = ObjectSeal(ObjectCreate(null, { | ||
| 45 | - __proto__: null, | ||
| 46 | - cc: getEnumerableConstant(cc), | ||
| 47 | - DEFAULT_CIPHERS: getEnumerableConstant(DEFAULT_CIPHERS), | ||
| 48 | - DEFAULT_GROUPS: getEnumerableConstant(DEFAULT_GROUPS), | ||
| 49 | - })); | ||
| 28 | + const constants = { | ||
| 29 | + get cc() { return cc; }, | ||
| 30 | + get DEFAULT_CIPHERS() { return DEFAULT_CIPHERS; }, | ||
| 31 | + get DEFAULT_GROUPS() { return DEFAULT_GROUPS; }, | ||
| 32 | + }; | ||
| 50 | 33 | ||
| 51 | - module.exports = ObjectSeal(ObjectCreate(null, { | ||
| 52 | - __proto__: null, | ||
| 53 | - connect: getEnumerableConstant(connect), | ||
| 54 | - listen: getEnumerableConstant(listen), | ||
| 55 | - QuicEndpoint: getEnumerableConstant(QuicEndpoint), | ||
| 56 | - QuicError: getEnumerableConstant(QuicError), | ||
| 57 | - QuicSession: getEnumerableConstant(QuicSession), | ||
| 58 | - QuicStream: getEnumerableConstant(QuicStream), | ||
| 59 | - constants: getEnumerableConstant(constants), | ||
| 34 | + module.exports = { | ||
| 35 | + connect, | ||
| 36 | + listen, | ||
| 37 | + QuicEndpoint, | ||
| 38 | + QuicError, | ||
| 39 | + QuicSession, | ||
| 40 | + QuicStream, | ||
| 41 | + get constants() { | ||
| 42 | + return constants; | ||
| 43 | + }, | ||
| 60 | 44 | ||
| 61 | 45 | CC_ALGO_RENO, | |
| 62 | 46 | CC_ALGO_CUBIC, | |
| 63 | 47 | CC_ALGO_BBR, | |
| 64 | 48 | DEFAULT_CIPHERS, | |
| 65 | 49 | DEFAULT_GROUPS, | |
| 66 | - })); | ||
| 50 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,11 +35,5 @@ strictEqual(quic.constants.DEFAULT_GROUPS, 'X25519:P-256:P-384:P-521'); | |||
| 35 | 35 | throws(() => { quic.constants.cc.RENO = 'foo'; }, TypeError); | |
| 36 | 36 | strictEqual(quic.constants.cc.RENO, 'reno'); | |
| 37 | 37 | ||
| 38 | - throws(() => { quic.constants.cc.NEW_CONSTANT = 'bar'; }, TypeError); | ||
| 39 | - strictEqual(quic.constants.cc.NEW_CONSTANT, undefined); | ||
| 40 | - | ||
| 41 | 38 | throws(() => { quic.constants.DEFAULT_CIPHERS = 123; }, TypeError); | |
| 42 | 39 | strictEqual(typeof quic.constants.DEFAULT_CIPHERS, 'string'); | |
| 43 | - | ||
| 44 | - throws(() => { quic.constants.NEW_CONSTANT = 456; }, TypeError); | ||
| 45 | - strictEqual(quic.constants.NEW_CONSTANT, undefined); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,105 @@ | |||
| 1 | + // Flags: --experimental-quic --no-warnings | ||
| 2 | + | ||
| 3 | + // Test: listEndpoints returns live endpoints filtered by active state. | ||
| 4 | + // - Returns an empty array when no endpoints exist. | ||
| 5 | + // - Includes all created endpoints. | ||
| 6 | + // - active=true (default) filters out destroyed, closing, and busy endpoints. | ||
| 7 | + // - active=false returns all registered endpoints regardless of state. | ||
| 8 | + // - Validates options argument types. | ||
| 9 | + | ||
| 10 | + import { hasQuic, skip } from '../common/index.mjs'; | ||
| 11 | + import assert from 'node:assert'; | ||
| 12 | + | ||
| 13 | + const { deepStrictEqual, strictEqual, throws, ok } = assert; | ||
| 14 | + | ||
| 15 | + if (!hasQuic) { | ||
| 16 | + skip('QUIC is not enabled'); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + const { listEndpoints, QuicEndpoint } = await import('node:quic'); | ||
| 20 | + | ||
| 21 | + // listEndpoints is exported as a function. | ||
| 22 | + strictEqual(typeof listEndpoints, 'function'); | ||
| 23 | + | ||
| 24 | + // Empty when no endpoints have been created. | ||
| 25 | + deepStrictEqual(listEndpoints(), []); | ||
| 26 | + deepStrictEqual(listEndpoints({ active: false }), []); | ||
| 27 | + | ||
| 28 | + // Created endpoints appear in the list. | ||
| 29 | + { | ||
| 30 | + const ep1 = new QuicEndpoint(); | ||
| 31 | + const ep2 = new QuicEndpoint(); | ||
| 32 | + | ||
| 33 | + const list = listEndpoints(); | ||
| 34 | + strictEqual(list.length, 2); | ||
| 35 | + ok(list.includes(ep1)); | ||
| 36 | + ok(list.includes(ep2)); | ||
| 37 | + | ||
| 38 | + // active=false also returns them. | ||
| 39 | + const all = listEndpoints({ active: false }); | ||
| 40 | + strictEqual(all.length, 2); | ||
| 41 | + ok(all.includes(ep1)); | ||
| 42 | + ok(all.includes(ep2)); | ||
| 43 | + | ||
| 44 | + // Returns plain QuicEndpoint instances, not wrapped in arrays. | ||
| 45 | + ok(list[0] instanceof QuicEndpoint); | ||
| 46 | + ok(list[1] instanceof QuicEndpoint); | ||
| 47 | + | ||
| 48 | + await ep1.close(); | ||
| 49 | + await ep2.close(); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + // Destroyed endpoints are excluded by active filter. | ||
| 53 | + { | ||
| 54 | + const ep = new QuicEndpoint(); | ||
| 55 | + strictEqual(listEndpoints().length, 1); | ||
| 56 | + | ||
| 57 | + await ep.close(); | ||
| 58 | + await ep.closed; | ||
| 59 | + strictEqual(ep.destroyed, true); | ||
| 60 | + | ||
| 61 | + // Default (active=true) excludes destroyed endpoint. | ||
| 62 | + strictEqual(listEndpoints().length, 0); | ||
| 63 | + | ||
| 64 | + // active=false still includes it... but destroyed endpoints are removed | ||
| 65 | + // from the registry entirely in kFinishClose, so it won't appear at all. | ||
| 66 | + strictEqual(listEndpoints({ active: false }).length, 0); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + // Busy endpoints are excluded by the active filter. | ||
| 70 | + { | ||
| 71 | + const ep = new QuicEndpoint(); | ||
| 72 | + strictEqual(listEndpoints().length, 1); | ||
| 73 | + | ||
| 74 | + ep.busy = true; | ||
| 75 | + strictEqual(ep.busy, true); | ||
| 76 | + | ||
| 77 | + // active=true excludes busy endpoint. | ||
| 78 | + strictEqual(listEndpoints().length, 0); | ||
| 79 | + | ||
| 80 | + // active=false includes it. | ||
| 81 | + const all = listEndpoints({ active: false }); | ||
| 82 | + strictEqual(all.length, 1); | ||
| 83 | + ok(all.includes(ep)); | ||
| 84 | + | ||
| 85 | + ep.busy = false; | ||
| 86 | + | ||
| 87 | + // After un-busying, it reappears in the active list. | ||
| 88 | + strictEqual(listEndpoints().length, 1); | ||
| 89 | + | ||
| 90 | + await ep.close(); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + // Options validation. | ||
| 94 | + throws(() => listEndpoints('bad'), { | ||
| 95 | + code: 'ERR_INVALID_ARG_TYPE', | ||
| 96 | + }); | ||
| 97 | + throws(() => listEndpoints(null), { | ||
| 98 | + code: 'ERR_INVALID_ARG_TYPE', | ||
| 99 | + }); | ||
| 100 | + throws(() => listEndpoints({ active: 'yes' }), { | ||
| 101 | + code: 'ERR_INVALID_ARG_TYPE', | ||
| 102 | + }); | ||
| 103 | + throws(() => listEndpoints({ active: 1 }), { | ||
| 104 | + code: 'ERR_INVALID_ARG_TYPE', | ||
| 105 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments