mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
feat: integrate Pi backend and Pi Web
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
export class RequestBodyTooLargeError extends Error {
|
||||
constructor() {
|
||||
super("Request body exceeds the allowed size");
|
||||
}
|
||||
}
|
||||
|
||||
function declaredContentLength(request: Request): number | null {
|
||||
const value = request.headers.get("content-length");
|
||||
if (!value || !/^\d+$/.test(value)) return null;
|
||||
const length = Number(value);
|
||||
return Number.isSafeInteger(length) ? length : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse multipart data only after constraining the complete wire body. This
|
||||
* bounds chunked requests too, where Content-Length is unavailable or false.
|
||||
*/
|
||||
export async function parseFormDataWithinLimit(request: Request, maxBytes: number): Promise<FormData> {
|
||||
const declared = declaredContentLength(request);
|
||||
if (declared !== null && declared > maxBytes) {
|
||||
throw new RequestBodyTooLargeError();
|
||||
}
|
||||
|
||||
const reader = request.body?.getReader();
|
||||
if (!reader) return request.formData();
|
||||
|
||||
const chunks: BlobPart[] = [];
|
||||
let size = 0;
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
if (size + value.byteLength > maxBytes) {
|
||||
await reader.cancel().catch(() => {});
|
||||
throw new RequestBodyTooLargeError();
|
||||
}
|
||||
size += value.byteLength;
|
||||
const chunk = new Uint8Array(value.byteLength);
|
||||
chunk.set(value);
|
||||
chunks.push(chunk);
|
||||
}
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
|
||||
const contentType = request.headers.get("content-type");
|
||||
const headers = contentType ? { "content-type": contentType } : undefined;
|
||||
return new Response(new Blob(chunks), { headers }).formData();
|
||||
}
|
||||
Reference in New Issue
Block a user