






















@@ -20,6 +20,10 @@ export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
2020// instead of buffering an unbounded stream via response.text().
2121const MATRIX_JSON_RESPONSE_MAX_BYTES = 8 * 1024 * 1024;
222223+// matrix-js-sdk also uses the injected fetch for raw encrypted key bundles.
24+// Keep that path bounded without applying the tighter control-plane JSON cap.
25+const MATRIX_SDK_RESPONSE_MAX_BYTES = 64 * 1024 * 1024;
26+2327type QueryValue =
2428| string
2529| number
@@ -96,7 +100,7 @@ function withoutMatrixStateAfterSyncParam(rawUrl: string): string {
9610097101function buildBufferedResponse(params: {
98102source: Response;
99-body: ArrayBuffer;
103+body: BodyInit;
100104url: string;
101105}): Response {
102106const response = new Response(params.body, {
@@ -115,6 +119,32 @@ function buildBufferedResponse(params: {
115119return response;
116120}
117121122+async function enforceDeclaredResponseSize(params: {
123+response: Response;
124+maxBytes: number;
125+createError: (length: number) => Error;
126+}): Promise<void> {
127+const contentLength = params.response.headers.get("content-length");
128+if (!contentLength) {
129+return;
130+}
131+132+let length: number | null;
133+try {
134+length = parseMediaContentLength(contentLength);
135+} catch (error) {
136+await params.response.body?.cancel(error).catch(() => undefined);
137+throw error;
138+}
139+if (length === null || length <= params.maxBytes) {
140+return;
141+}
142+143+const error = params.createError(length);
144+await params.response.body?.cancel(error).catch(() => undefined);
145+throw error;
146+}
147+118148async function fetchWithMatrixDispatcher(params: {
119149url: string;
120150init: MatrixDispatcherRequestInit;
@@ -250,10 +280,21 @@ export function createMatrixGuardedFetch(params: {
250280});
251281252282try {
253-const body = await response.arrayBuffer();
283+await enforceDeclaredResponseSize({
284+ response,
285+maxBytes: MATRIX_SDK_RESPONSE_MAX_BYTES,
286+createError: (length) =>
287+new Error(
288+`Matrix SDK response exceeds size limit (${length} bytes > ${MATRIX_SDK_RESPONSE_MAX_BYTES} bytes)`,
289+),
290+});
291+const body = await readResponseWithLimit(response, MATRIX_SDK_RESPONSE_MAX_BYTES, {
292+onOverflow: ({ maxBytes, size }) =>
293+new Error(`Matrix SDK response exceeds size limit (${size} bytes > ${maxBytes} bytes)`),
294+});
254295return buildBufferedResponse({
255296source: response,
256- body,
297+body: Uint8Array.from(body),
257298 url,
258299});
259300} finally {
@@ -324,14 +365,15 @@ export async function performMatrixRequest(params: {
324365325366try {
326367if (params.raw) {
327-const contentLength = response.headers.get("content-length");
328-if (params.maxBytes && contentLength) {
329-const length = parseMediaContentLength(contentLength);
330-if (length !== null && length > params.maxBytes) {
331-throw new MatrixMediaSizeLimitError(
332-`Matrix media exceeds configured size limit (${length} bytes > ${params.maxBytes} bytes)`,
333-);
334-}
368+if (params.maxBytes) {
369+await enforceDeclaredResponseSize({
370+ response,
371+maxBytes: params.maxBytes,
372+createError: (length) =>
373+new MatrixMediaSizeLimitError(
374+`Matrix media exceeds configured size limit (${length} bytes > ${params.maxBytes} bytes)`,
375+),
376+});
335377}
336378const bytes = params.maxBytes
337379 ? await readResponseWithLimit(response, params.maxBytes, {
@@ -349,15 +391,14 @@ export async function performMatrixRequest(params: {
349391};
350392}
351393const jsonMaxBytes = params.maxBytes ?? MATRIX_JSON_RESPONSE_MAX_BYTES;
352-const contentLength = response.headers.get("content-length");
353-if (contentLength) {
354-const length = parseMediaContentLength(contentLength);
355-if (length !== null && length > jsonMaxBytes) {
356-throw new Error(
394+await enforceDeclaredResponseSize({
395+ response,
396+maxBytes: jsonMaxBytes,
397+createError: (length) =>
398+new Error(
357399`Matrix JSON response exceeds configured size limit (${length} bytes > ${jsonMaxBytes} bytes)`,
358-);
359-}
360-}
400+),
401+});
361402const buffer = await readResponseWithLimit(response, jsonMaxBytes, {
362403onOverflow: ({ maxBytes, size }) =>
363404new Error(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。