Initial U-Navigator prototype
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
export async function readRequestBody(req, limitBytes) {
|
||||
const chunks = [];
|
||||
let size = 0;
|
||||
|
||||
for await (const chunk of req) {
|
||||
size += chunk.length;
|
||||
if (size > limitBytes) {
|
||||
const error = new Error('Request body is too large');
|
||||
error.status = 413;
|
||||
throw error;
|
||||
}
|
||||
chunks.push(chunk);
|
||||
}
|
||||
|
||||
return Buffer.concat(chunks);
|
||||
}
|
||||
|
||||
export function parseMultipart(buffer, contentType) {
|
||||
const match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType || '');
|
||||
if (!match) {
|
||||
const error = new Error('Missing multipart boundary');
|
||||
error.status = 400;
|
||||
throw error;
|
||||
}
|
||||
|
||||
const boundary = `--${match[1] || match[2]}`;
|
||||
const binary = buffer.toString('binary');
|
||||
const parts = [];
|
||||
|
||||
for (const raw of binary.split(boundary)) {
|
||||
if (!raw || raw === '--\r\n' || raw === '--') {
|
||||
continue;
|
||||
}
|
||||
|
||||
const trimmed = raw.replace(/^\r\n/, '').replace(/\r\n--$/, '');
|
||||
const separator = trimmed.indexOf('\r\n\r\n');
|
||||
if (separator === -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const headerText = trimmed.slice(0, separator);
|
||||
let bodyText = trimmed.slice(separator + 4);
|
||||
if (bodyText.endsWith('\r\n')) {
|
||||
bodyText = bodyText.slice(0, -2);
|
||||
}
|
||||
|
||||
const disposition = /content-disposition:\s*form-data;\s*([^\r\n]+)/i.exec(headerText)?.[1] || '';
|
||||
const name = /name="([^"]+)"/i.exec(disposition)?.[1] || '';
|
||||
const filename = /filename="([^"]*)"/i.exec(disposition)?.[1] || '';
|
||||
|
||||
parts.push({
|
||||
name,
|
||||
filename,
|
||||
data: Buffer.from(bodyText, 'binary')
|
||||
});
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
Reference in New Issue
Block a user