fix(gateway): cap non-finite preauth limits · openclaw/openclaw@7979639
steipete
·
2026-05-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { describe, expect, it } from "vitest"; |
| 2 | +import { createPreauthConnectionBudget } from "./preauth-connection-budget.js"; |
| 3 | + |
| 4 | +describe("createPreauthConnectionBudget", () => { |
| 5 | +it("caps connections with a finite configured limit", () => { |
| 6 | +const budget = createPreauthConnectionBudget(2); |
| 7 | + |
| 8 | +expect(budget.acquire("127.0.0.1")).toBe(true); |
| 9 | +expect(budget.acquire("127.0.0.1")).toBe(true); |
| 10 | +expect(budget.acquire("127.0.0.1")).toBe(false); |
| 11 | + |
| 12 | +budget.release("127.0.0.1"); |
| 13 | +expect(budget.acquire("127.0.0.1")).toBe(true); |
| 14 | +}); |
| 15 | + |
| 16 | +it("uses the default cap for non-finite direct limits", () => { |
| 17 | +const budget = createPreauthConnectionBudget(Number.NaN); |
| 18 | + |
| 19 | +for (let i = 0; i < 32; i += 1) { |
| 20 | +expect(budget.acquire("127.0.0.1")).toBe(true); |
| 21 | +} |
| 22 | +expect(budget.acquire("127.0.0.1")).toBe(false); |
| 23 | +}); |
| 24 | + |
| 25 | +it("shares one capped bucket for missing client IPs", () => { |
| 26 | +const budget = createPreauthConnectionBudget(Number.POSITIVE_INFINITY); |
| 27 | + |
| 28 | +for (let i = 0; i < 32; i += 1) { |
| 29 | +expect(budget.acquire(i % 2 === 0 ? undefined : " ")).toBe(true); |
| 30 | +} |
| 31 | +expect(budget.acquire(undefined)).toBe(false); |
| 32 | +}); |
| 33 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { resolveIntegerOption } from "../../shared/number-coercion.js"; |
| 2 | + |
1 | 3 | const DEFAULT_MAX_PREAUTH_CONNECTIONS_PER_IP = 32; |
2 | 4 | const UNKNOWN_CLIENT_IP_BUDGET_KEY = "__openclaw_unknown_client_ip__"; |
3 | 5 | |
@@ -23,6 +25,9 @@ export type PreauthConnectionBudget = {
|
23 | 25 | export function createPreauthConnectionBudget( |
24 | 26 | limit = getMaxPreauthConnectionsPerIpFromEnv(), |
25 | 27 | ): PreauthConnectionBudget { |
| 28 | +const maxConnectionsPerIp = resolveIntegerOption(limit, getMaxPreauthConnectionsPerIpFromEnv(), { |
| 29 | +min: 1, |
| 30 | +}); |
26 | 31 | const counts = new Map<string, number>(); |
27 | 32 | const normalizeBudgetKey = (clientIp: string | undefined) => { |
28 | 33 | const ip = clientIp?.trim(); |
@@ -36,7 +41,7 @@ export function createPreauthConnectionBudget(
|
36 | 41 | acquire(clientIp) { |
37 | 42 | const ip = normalizeBudgetKey(clientIp); |
38 | 43 | const next = (counts.get(ip) ?? 0) + 1; |
39 | | -if (next > limit) { |
| 44 | +if (next > maxConnectionsPerIp) { |
40 | 45 | return false; |
41 | 46 | } |
42 | 47 | counts.set(ip, next); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。