惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
N
Netflix TechBlog - Medium
P
Proofpoint News Feed
D
Docker
J
Java Code Geeks
L
LangChain Blog
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
月光博客
月光博客
T
Tailwind CSS Blog
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
腾讯CDC
罗磊的独立博客
U
Unit 42
爱范儿
爱范儿
Vercel News
Vercel News
MyScale Blog
MyScale Blog

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(voice-call): close webhook in-flight limiter fail-ope...
davidangular · 2026-04-30 · via Recent Commits to openclaw:main

@@ -1,4 +1,4 @@

1-

import { request } from "node:http";

1+

import { request, type IncomingMessage } from "node:http";

22

import type { RealtimeTranscriptionProviderPlugin } from "openclaw/plugin-sdk/realtime-transcription";

33

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

44

import { VoiceCallConfigSchema, type VoiceCallConfig } from "./config.js";

@@ -941,7 +941,9 @@ describe("VoiceCallWebhookServer pre-auth webhook guards", () => {

941941

if (enteredReads === 8) {

942942

releaseReads();

943943

}

944-

await unblockReads;

944+

if (enteredReads <= 8) {

945+

await unblockReads;

946+

}

945947

return "CallSid=CA123&SpeechResult=hello";

946948

});

947949

@@ -967,6 +969,80 @@ describe("VoiceCallWebhookServer pre-auth webhook guards", () => {

967969

await server.stop();

968970

}

969971

});

972+973+

it("limits missing remote addresses with a shared fallback bucket", async () => {

974+

const twilioProvider: VoiceCallProvider = {

975+

...provider,

976+

name: "twilio",

977+

verifyWebhook: () => ({ ok: true, verifiedRequestKey: "twilio:req:test" }),

978+

};

979+

const { manager } = createManager([]);

980+

const config = createConfig({ provider: "twilio" });

981+

const server = new VoiceCallWebhookServer(config, manager, twilioProvider);

982+

const runWebhookPipeline = (

983+

server as unknown as {

984+

runWebhookPipeline: (

985+

req: IncomingMessage,

986+

webhookPath: string,

987+

) => Promise<{ statusCode: number; body: string }>;

988+

}

989+

).runWebhookPipeline.bind(server);

990+991+

let enteredReads = 0;

992+

let releaseReads!: () => void;

993+

let unblockReadBodies!: () => void;

994+

const enteredEightReads = new Promise<void>((resolve) => {

995+

releaseReads = resolve;

996+

});

997+

const unblockReads = new Promise<void>((resolve) => {

998+

unblockReadBodies = resolve;

999+

});

1000+

const readBodySpy = vi.spyOn(

1001+

server as unknown as {

1002+

readBody: (req: unknown, maxBytes: number, timeoutMs?: number) => Promise<string>;

1003+

},

1004+

"readBody",

1005+

);

1006+

readBodySpy.mockImplementation(async () => {

1007+

enteredReads += 1;

1008+

if (enteredReads === 8) {

1009+

releaseReads();

1010+

}

1011+

await unblockReads;

1012+

return "CallSid=CA123&SpeechResult=hello";

1013+

});

1014+1015+

const makeRequestWithoutRemoteAddress = () =>

1016+

({

1017+

method: "POST",

1018+

url: "/voice/webhook",

1019+

headers: { "x-twilio-signature": "sig" },

1020+

socket: { remoteAddress: undefined },

1021+

}) as unknown as IncomingMessage;

1022+1023+

try {

1024+

const inFlightRequests = Array.from({ length: 8 }, () =>

1025+

runWebhookPipeline(makeRequestWithoutRemoteAddress(), "/voice/webhook"),

1026+

);

1027+

await enteredEightReads;

1028+1029+

const rejected = await runWebhookPipeline(

1030+

makeRequestWithoutRemoteAddress(),

1031+

"/voice/webhook",

1032+

);

1033+

expect(rejected.statusCode).toBe(429);

1034+

expect(rejected.body).toBe("Too Many Requests");

1035+

expect(readBodySpy).toHaveBeenCalledTimes(8);

1036+1037+

unblockReadBodies();

1038+1039+

const settled = await Promise.all(inFlightRequests);

1040+

expect(settled.every((response) => response.statusCode === 200)).toBe(true);

1041+

} finally {

1042+

unblockReadBodies();

1043+

readBodySpy.mockRestore();

1044+

}

1045+

});

9701046

});

97110479721048

describe("VoiceCallWebhookServer response normalization", () => {