Initial commit
This commit is contained in:
55
server/utils/http.ts
Normal file
55
server/utils/http.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { H3Event } from "h3";
|
||||
import { createError, getRequestHeader } from "h3";
|
||||
export async function readBounded(
|
||||
event: H3Event,
|
||||
max: number,
|
||||
): Promise<Buffer> {
|
||||
const declared = getRequestHeader(event, "content-length");
|
||||
if (declared && (!/^\d+$/u.test(declared) || Number(declared) > max))
|
||||
throw createError({
|
||||
statusCode: 413,
|
||||
statusMessage: "Request body exceeds the limit.",
|
||||
});
|
||||
const chunks: Buffer[] = [];
|
||||
let total = 0;
|
||||
for await (const value of event.node.req) {
|
||||
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
||||
total += chunk.byteLength;
|
||||
if (total > max)
|
||||
throw createError({
|
||||
statusCode: 413,
|
||||
statusMessage: "Request body exceeds the limit.",
|
||||
});
|
||||
chunks.push(chunk);
|
||||
}
|
||||
return Buffer.concat(chunks, total);
|
||||
}
|
||||
export async function readJson<T>(event: H3Event, max: number): Promise<T> {
|
||||
const body = await readBounded(event, max);
|
||||
try {
|
||||
return JSON.parse(body.toString("utf8")) as T;
|
||||
} catch {
|
||||
throw createError({ statusCode: 400, statusMessage: "Malformed JSON." });
|
||||
}
|
||||
}
|
||||
export function requireContentType(event: H3Event, expected: string) {
|
||||
const type = (
|
||||
(getRequestHeader(event, "content-type") || "").split(";", 1)[0] || ""
|
||||
)
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if (type !== expected)
|
||||
throw createError({
|
||||
statusCode: 415,
|
||||
statusMessage: `Content-Type must be ${expected}.`,
|
||||
});
|
||||
}
|
||||
export function bearerToken(event: H3Event): string | undefined {
|
||||
const value = getRequestHeader(event, "authorization") || "";
|
||||
return /^Bearer ([A-Za-z0-9_-]{20,})$/u.exec(value)?.[1];
|
||||
}
|
||||
export function publicHeaders(event: H3Event) {
|
||||
event.node.res.setHeader("cache-control", "no-store");
|
||||
event.node.res.setHeader("referrer-policy", "no-referrer");
|
||||
event.node.res.setHeader("x-content-type-options", "nosniff");
|
||||
}
|
||||
Reference in New Issue
Block a user