mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 12:56:01 -06:00
fix(gateway): cap non-finite preauth limits
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createPreauthConnectionBudget } from "./preauth-connection-budget.js";
|
||||
|
||||
describe("createPreauthConnectionBudget", () => {
|
||||
it("caps connections with a finite configured limit", () => {
|
||||
const budget = createPreauthConnectionBudget(2);
|
||||
|
||||
expect(budget.acquire("127.0.0.1")).toBe(true);
|
||||
expect(budget.acquire("127.0.0.1")).toBe(true);
|
||||
expect(budget.acquire("127.0.0.1")).toBe(false);
|
||||
|
||||
budget.release("127.0.0.1");
|
||||
expect(budget.acquire("127.0.0.1")).toBe(true);
|
||||
});
|
||||
|
||||
it("uses the default cap for non-finite direct limits", () => {
|
||||
const budget = createPreauthConnectionBudget(Number.NaN);
|
||||
|
||||
for (let i = 0; i < 32; i += 1) {
|
||||
expect(budget.acquire("127.0.0.1")).toBe(true);
|
||||
}
|
||||
expect(budget.acquire("127.0.0.1")).toBe(false);
|
||||
});
|
||||
|
||||
it("shares one capped bucket for missing client IPs", () => {
|
||||
const budget = createPreauthConnectionBudget(Number.POSITIVE_INFINITY);
|
||||
|
||||
for (let i = 0; i < 32; i += 1) {
|
||||
expect(budget.acquire(i % 2 === 0 ? undefined : " ")).toBe(true);
|
||||
}
|
||||
expect(budget.acquire(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,5 @@
|
||||
import { resolveIntegerOption } from "../../shared/number-coercion.js";
|
||||
|
||||
const DEFAULT_MAX_PREAUTH_CONNECTIONS_PER_IP = 32;
|
||||
const UNKNOWN_CLIENT_IP_BUDGET_KEY = "__openclaw_unknown_client_ip__";
|
||||
|
||||
@@ -23,6 +25,9 @@ export type PreauthConnectionBudget = {
|
||||
export function createPreauthConnectionBudget(
|
||||
limit = getMaxPreauthConnectionsPerIpFromEnv(),
|
||||
): PreauthConnectionBudget {
|
||||
const maxConnectionsPerIp = resolveIntegerOption(limit, getMaxPreauthConnectionsPerIpFromEnv(), {
|
||||
min: 1,
|
||||
});
|
||||
const counts = new Map<string, number>();
|
||||
const normalizeBudgetKey = (clientIp: string | undefined) => {
|
||||
const ip = clientIp?.trim();
|
||||
@@ -36,7 +41,7 @@ export function createPreauthConnectionBudget(
|
||||
acquire(clientIp) {
|
||||
const ip = normalizeBudgetKey(clientIp);
|
||||
const next = (counts.get(ip) ?? 0) + 1;
|
||||
if (next > limit) {
|
||||
if (next > maxConnectionsPerIp) {
|
||||
return false;
|
||||
}
|
||||
counts.set(ip, next);
|
||||
|
||||
Reference in New Issue
Block a user