























@@ -923,7 +923,7 @@ export async function fetchJson(url, options = {}) {
923923 ...(abortPromise ? [abortPromise] : []),
924924]);
925925const text = await Promise.race([
926-readBoundedResponseText(response, maxBodyBytes),
926+readBoundedResponseText(response, maxBodyBytes, timeoutPromise),
927927timeoutPromise,
928928 ...(abortPromise ? [abortPromise] : []),
929929]);
@@ -950,39 +950,44 @@ export async function fetchJson(url, options = {}) {
950950throw toLintErrorObject(lastError ?? new Error(`fetch ${url} failed`), "Non-Error thrown");
951951}
952952953-export async function readBoundedResponseText(
954-response,
955-byteLimit = resolveKitchenSinkRpcConfig().fetchBodyMaxBytes,
956-) {
953+export async function readBoundedResponseText(response, byteLimit, timeoutPromise) {
954+const resolvedByteLimit = byteLimit ?? resolveKitchenSinkRpcConfig().fetchBodyMaxBytes;
957955const contentLength = response.headers?.get?.("content-length");
958956if (contentLength && /^\d+$/u.test(contentLength)) {
959957const parsedContentLength = Number(contentLength);
960-if (Number.isSafeInteger(parsedContentLength) && parsedContentLength > byteLimit) {
958+if (Number.isSafeInteger(parsedContentLength) && parsedContentLength > resolvedByteLimit) {
961959await response.body?.cancel?.().catch(() => undefined);
962-throw createFetchBodyTooLargeError(byteLimit);
960+throw createFetchBodyTooLargeError(resolvedByteLimit);
963961}
964962}
965963966964const reader = response.body?.getReader?.();
967965if (!reader) {
968-const text = await response.text();
969-if (Buffer.byteLength(text, "utf8") > byteLimit) {
970-throw createFetchBodyTooLargeError(byteLimit);
966+const text = await withOptionalTimeout(response.text(), timeoutPromise);
967+if (Buffer.byteLength(text, "utf8") > resolvedByteLimit) {
968+throw createFetchBodyTooLargeError(resolvedByteLimit);
971969}
972970return text;
973971}
974972const chunks = [];
975973let totalBytes = 0;
976974for (;;) {
977-const { done, value } = await reader.read();
975+const read = reader.read();
976+const { done, value } = await withOptionalTimeout(
977+read,
978+timeoutPromise?.catch((error) => {
979+cancelReaderSoon(reader);
980+throw error;
981+}),
982+);
978983if (done) {
979984break;
980985}
981986const chunk = Buffer.from(value);
982987totalBytes += chunk.byteLength;
983-if (totalBytes > byteLimit) {
988+if (totalBytes > resolvedByteLimit) {
984989await reader.cancel().catch(() => undefined);
985-throw createFetchBodyTooLargeError(byteLimit);
990+throw createFetchBodyTooLargeError(resolvedByteLimit);
986991}
987992chunks.push(chunk);
988993}
@@ -995,6 +1000,19 @@ function createFetchBodyTooLargeError(byteLimit) {
9951000});
9961001}
99710021003+async function withOptionalTimeout(promise, timeoutPromise) {
1004+if (!timeoutPromise) {
1005+return await promise;
1006+}
1007+return await Promise.race([promise, timeoutPromise]);
1008+}
1009+1010+function cancelReaderSoon(reader) {
1011+void Promise.resolve()
1012+.then(() => reader.cancel())
1013+.catch(() => undefined);
1014+}
1015+9981016function configureKitchenSink(env, port) {
9991017const configPath = env.OPENCLAW_CONFIG_PATH;
10001018const config = fs.existsSync(configPath) ? readJson(configPath) : {};
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。