Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions packages/cli/src/serve/run-qwen-serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1158,14 +1158,15 @@ export async function runQwenServe(
// promise instead of escaping as an uncaught exception inside the
// listen callback (which fires from the `listening` event after the
// outer promise has already resolved). Silent fail-OPEN on NaN /
// negative would weaken the DoS/FD-exhaustion guard the cap exists
// for.
// negative / fractional values would weaken or blur the
// DoS/FD-exhaustion guard the cap exists for.
if (
opts.maxConnections !== undefined &&
(Number.isNaN(opts.maxConnections) || opts.maxConnections < 0)
!isNonNegativeIntegerOrInfinity(opts.maxConnections)
) {
throw new TypeError(
`Invalid maxConnections: ${opts.maxConnections}. Must be >= 0 ` +
`Invalid maxConnections: ${opts.maxConnections}. ` +
`Must be a non-negative integer ` +
`(0 / Infinity = unlimited).`,
);
}
Expand All @@ -1190,7 +1191,7 @@ export async function runQwenServe(
// with `SocketError: other side closed`). Treat 0 / Infinity
// as "leave the property unset" so the documented disable
// path actually disables instead of silently bricking the
// daemon. NaN / negative are rejected upstream so
// daemon. NaN / negative / fractional values are rejected upstream so
// they never reach here.
const cap = opts.maxConnections ?? 256;
if (cap > 0 && Number.isFinite(cap)) {
Expand Down
20 changes: 8 additions & 12 deletions packages/cli/src/serve/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8970,7 +8970,7 @@ describe('runQwenServe', () => {
// Node 22 `server.maxConnections = 0` causes the listener to
// refuse EVERY connection. An operator following the documented
// disable path got a daemon that booted cleanly but silently
// bricked every request. Fix treats 0 / Infinity / non-finite as
// bricked every request. Fix treats 0 / Infinity as
// "leave the property unset" so Node's default (no cap) actually
// applies.
handle = await runQwenServe({
Expand Down Expand Up @@ -9012,25 +9012,21 @@ describe('runQwenServe', () => {
expect(handle.server.maxConnections).toBe(100);
});

it('--max-connections NaN/negative throws at boot (BUF9-)', async () => {
it.each([
['NaN', NaN],
['negative', -5],
['fractional', 1.5],
])('--max-connections %s throws at boot (BUF9-)', async (_label, value) => {
// Silent fail-OPEN on a CLI typo would weaken the DoS guard.
// Boot-loud is the right behavior for an unparseable cap.
await expect(
runQwenServe({
hostname: '127.0.0.1',
port: 0,
mode: 'http-bridge',
maxConnections: NaN,
}),
).rejects.toThrow(/maxConnections: NaN/);
await expect(
runQwenServe({
hostname: '127.0.0.1',
port: 0,
mode: 'http-bridge',
maxConnections: -5,
maxConnections: value,
}),
).rejects.toThrow(/maxConnections: -5/);
).rejects.toThrow(/maxConnections/);
});

it('case-insensitive loopback: --hostname Localhost / LOCALHOST does NOT require a token (BQ92B)', async () => {
Expand Down
Loading