Skip to content

Commit 4eb70e3

Browse files
committed
quic: handle quic constants better
1 parent 419c80d commit 4eb70e3

File tree

3 files changed

+90
-38
lines changed

3 files changed

+90
-38
lines changed

lib/internal/quic/quic.js

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ const {
3636
setCallbacks,
3737

3838
// The constants to be exposed to end users for various options.
39-
CC_ALGO_RENO_STR,
40-
CC_ALGO_CUBIC_STR,
41-
CC_ALGO_BBR_STR,
39+
CC_ALGO_RENO_STR: CC_ALGO_RENO,
40+
CC_ALGO_CUBIC_STR: CC_ALGO_CUBIC,
41+
CC_ALGO_BBR_STR: CC_ALGO_BBR,
4242
DEFAULT_CIPHERS,
4343
DEFAULT_GROUPS,
4444

@@ -2073,16 +2073,6 @@ class QuicEndpoint {
20732073
async [SymbolAsyncDispose]() { await this.close(); }
20742074
};
20752075

2076-
function readOnlyConstant(value) {
2077-
return {
2078-
__proto__: null,
2079-
value,
2080-
writable: false,
2081-
configurable: false,
2082-
enumerable: true,
2083-
};
2084-
}
2085-
20862076
/**
20872077
* @param {EndpointOptions} endpoint
20882078
* @returns {{ endpoint: Endpoint_, created: boolean }}
@@ -2263,10 +2253,7 @@ function processSessionOptions(options, forServer = false) {
22632253
}
22642254

22652255
if (cc !== undefined) {
2266-
validateString(cc, 'options.cc');
2267-
if (cc !== 'reno' || cc !== 'bbr' || cc !== 'cubic') {
2268-
throw new ERR_INVALID_ARG_VALUE('options.cc', cc);
2269-
}
2256+
validateOneOf(cc, 'options.cc', [CC_ALGO_RENO, CC_ALGO_BBR, CC_ALGO_CUBIC]);
22702257
}
22712258

22722259
const {
@@ -2393,19 +2380,15 @@ module.exports = {
23932380
QuicSession,
23942381
QuicStream,
23952382
Http3,
2383+
CC_ALGO_RENO,
2384+
CC_ALGO_CUBIC,
2385+
CC_ALGO_BBR,
2386+
DEFAULT_CIPHERS,
2387+
DEFAULT_GROUPS,
23962388
// These are exported only for internal testing purposes.
23972389
getQuicStreamState,
23982390
getQuicSessionState,
23992391
getQuicEndpointState,
24002392
};
24012393

2402-
ObjectDefineProperties(module.exports, {
2403-
CC_ALGO_RENO: readOnlyConstant(CC_ALGO_RENO_STR),
2404-
CC_ALGO_CUBIC: readOnlyConstant(CC_ALGO_CUBIC_STR),
2405-
CC_ALGO_BBR: readOnlyConstant(CC_ALGO_BBR_STR),
2406-
DEFAULT_CIPHERS: readOnlyConstant(DEFAULT_CIPHERS),
2407-
DEFAULT_GROUPS: readOnlyConstant(DEFAULT_GROUPS),
2408-
});
2409-
2410-
24112394
/* c8 ignore stop */

lib/quic.js

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
'use strict';
22

3+
const {
4+
ObjectCreate,
5+
ObjectSeal,
6+
} = primordials;
7+
38
const {
49
emitExperimentalWarning,
510
} = require('internal/util');
@@ -18,15 +23,36 @@ const {
1823
DEFAULT_GROUPS,
1924
} = require('internal/quic/quic');
2025

21-
module.exports = {
22-
connect,
23-
listen,
24-
QuicEndpoint,
25-
QuicSession,
26-
QuicStream,
27-
CC_ALGO_RENO,
28-
CC_ALGO_CUBIC,
29-
CC_ALGO_BBR,
30-
DEFAULT_CIPHERS,
31-
DEFAULT_GROUPS,
32-
};
26+
function getEnumerableConstant(value) {
27+
return {
28+
__proto__: null,
29+
value,
30+
enumerable: true,
31+
configurable: false,
32+
writable: false,
33+
};
34+
}
35+
36+
const cc = ObjectSeal(ObjectCreate(null, {
37+
__proto__: null,
38+
RENO: getEnumerableConstant(CC_ALGO_RENO),
39+
CUBIC: getEnumerableConstant(CC_ALGO_CUBIC),
40+
BBR: getEnumerableConstant(CC_ALGO_BBR),
41+
}));
42+
43+
const constants = ObjectSeal(ObjectCreate(null, {
44+
__proto__: null,
45+
cc: getEnumerableConstant(cc),
46+
DEFAULT_CIPHERS: getEnumerableConstant(DEFAULT_CIPHERS),
47+
DEFAULT_GROUPS: getEnumerableConstant(DEFAULT_GROUPS),
48+
}));
49+
50+
module.exports = ObjectSeal(ObjectCreate(null, {
51+
__proto__: null,
52+
connect: getEnumerableConstant(connect),
53+
listen: getEnumerableConstant(listen),
54+
QuicEndpoint: getEnumerableConstant(QuicEndpoint),
55+
QuicSession: getEnumerableConstant(QuicSession),
56+
QuicStream: getEnumerableConstant(QuicStream),
57+
constants: getEnumerableConstant(constants),
58+
}));
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Flags: --experimental-quic --no-warnings
2+
import { hasQuic, skip } from '../common/index.mjs';
3+
import { strictEqual, throws } from 'node:assert';
4+
5+
if (!hasQuic) {
6+
skip('QUIC is not enabled');
7+
}
8+
9+
const quic = await import('node:quic');
10+
11+
// Test that the main exports exist and are of the correct type.
12+
strictEqual(typeof quic.connect, 'function');
13+
strictEqual(typeof quic.listen, 'function');
14+
strictEqual(typeof quic.QuicEndpoint, 'function');
15+
strictEqual(typeof quic.QuicSession, 'function');
16+
strictEqual(typeof quic.QuicStream, 'function');
17+
strictEqual(typeof quic.QuicEndpoint.Stats, 'function');
18+
strictEqual(typeof quic.QuicSession.Stats, 'function');
19+
strictEqual(typeof quic.QuicStream.Stats, 'function');
20+
strictEqual(typeof quic.constants, 'object');
21+
strictEqual(typeof quic.constants.cc, 'object');
22+
23+
// Test that the constants exist and are of the correct type.
24+
strictEqual(quic.constants.cc.RENO, 'reno');
25+
strictEqual(quic.constants.cc.CUBIC, 'cubic');
26+
strictEqual(quic.constants.cc.BBR, 'bbr');
27+
strictEqual(quic.constants.DEFAULT_CIPHERS,
28+
'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:' +
29+
'TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256');
30+
strictEqual(quic.constants.DEFAULT_GROUPS, 'X25519:P-256:P-384:P-521');
31+
32+
// Ensure the constants are.. well, constant.
33+
throws(() => { quic.constants.cc.RENO = 'foo'; }, TypeError);
34+
strictEqual(quic.constants.cc.RENO, 'reno');
35+
36+
throws(() => { quic.constants.cc.NEW_CONSTANT = 'bar'; }, TypeError);
37+
strictEqual(quic.constants.cc.NEW_CONSTANT, undefined);
38+
39+
throws(() => { quic.constants.DEFAULT_CIPHERS = 123; }, TypeError);
40+
strictEqual(typeof quic.constants.DEFAULT_CIPHERS, 'string');
41+
42+
throws(() => { quic.constants.NEW_CONSTANT = 456; }, TypeError);
43+
strictEqual(quic.constants.NEW_CONSTANT, undefined);

0 commit comments

Comments
 (0)