mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 12:11:23 +00:00
refactor: dedupe media and request-body test scaffolding
This commit is contained in:
@@ -113,15 +113,29 @@ describe("http body limits", () => {
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
|
||||
it("timeout surfaces typed error", async () => {
|
||||
it("timeout surfaces typed error when timeoutMs is clamped", async () => {
|
||||
const req = createMockRequest({ emitEnd: false });
|
||||
const promise = readRequestBodyWithLimit(req, { maxBytes: 128, timeoutMs: 10 });
|
||||
const promise = readRequestBodyWithLimit(req, { maxBytes: 128, timeoutMs: 0 });
|
||||
await expect(promise).rejects.toSatisfy((error: unknown) =>
|
||||
isRequestBodyLimitError(error, "REQUEST_BODY_TIMEOUT"),
|
||||
);
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
|
||||
it("guard clamps invalid maxBytes to one byte", async () => {
|
||||
const req = createMockRequest({ chunks: ["ab"], emitEnd: false });
|
||||
const res = createMockServerResponse();
|
||||
const guard = installRequestBodyLimitGuard(req, res, {
|
||||
maxBytes: Number.NaN,
|
||||
responseFormat: "text",
|
||||
});
|
||||
await waitForMicrotaskTurn();
|
||||
expect(guard.isTripped()).toBe(true);
|
||||
expect(guard.code()).toBe("PAYLOAD_TOO_LARGE");
|
||||
expect(res.statusCode).toBe(413);
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
|
||||
it("declared oversized content-length does not emit unhandled error", async () => {
|
||||
const req = createMockRequest({
|
||||
headers: { "content-length": "9999" },
|
||||
|
||||
@@ -79,10 +79,15 @@ export type ReadRequestBodyOptions = {
|
||||
encoding?: BufferEncoding;
|
||||
};
|
||||
|
||||
export async function readRequestBodyWithLimit(
|
||||
req: IncomingMessage,
|
||||
options: ReadRequestBodyOptions,
|
||||
): Promise<string> {
|
||||
type RequestBodyLimitValues = {
|
||||
maxBytes: number;
|
||||
timeoutMs: number;
|
||||
};
|
||||
|
||||
function resolveRequestBodyLimitValues(options: {
|
||||
maxBytes: number;
|
||||
timeoutMs?: number;
|
||||
}): RequestBodyLimitValues {
|
||||
const maxBytes = Number.isFinite(options.maxBytes)
|
||||
? Math.max(1, Math.floor(options.maxBytes))
|
||||
: 1;
|
||||
@@ -90,6 +95,14 @@ export async function readRequestBodyWithLimit(
|
||||
typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)
|
||||
? Math.max(1, Math.floor(options.timeoutMs))
|
||||
: DEFAULT_WEBHOOK_BODY_TIMEOUT_MS;
|
||||
return { maxBytes, timeoutMs };
|
||||
}
|
||||
|
||||
export async function readRequestBodyWithLimit(
|
||||
req: IncomingMessage,
|
||||
options: ReadRequestBodyOptions,
|
||||
): Promise<string> {
|
||||
const { maxBytes, timeoutMs } = resolveRequestBodyLimitValues(options);
|
||||
const encoding = options.encoding ?? "utf-8";
|
||||
|
||||
const declaredLength = parseContentLengthHeader(req);
|
||||
@@ -241,13 +254,7 @@ export function installRequestBodyLimitGuard(
|
||||
res: ServerResponse,
|
||||
options: RequestBodyLimitGuardOptions,
|
||||
): RequestBodyLimitGuard {
|
||||
const maxBytes = Number.isFinite(options.maxBytes)
|
||||
? Math.max(1, Math.floor(options.maxBytes))
|
||||
: 1;
|
||||
const timeoutMs =
|
||||
typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)
|
||||
? Math.max(1, Math.floor(options.timeoutMs))
|
||||
: DEFAULT_WEBHOOK_BODY_TIMEOUT_MS;
|
||||
const { maxBytes, timeoutMs } = resolveRequestBodyLimitValues(options);
|
||||
const responseFormat = options.responseFormat ?? "json";
|
||||
const customText = options.responseText ?? {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user