web-font/backend/routes/upload.ts
崮生(子虚) c18dc44e72 chore: 升级至 v1.7.0,新增内存缓存与运行时统计
- 新增通用 LruCache 类,支持按条目数/字节容量两种淘汰策略
- 字体裁剪结果 LRU 内存缓存(默认 10MB,X-Cache 响应头标识命中)
- 新增 GET /api/stats 运行时统计接口
- 前端统计面板(10s 轮询,页面不可见时暂停)
- API handler 拆分到 routes/ 目录,提取 shared.ts 共享模块

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 19:34:30 +08:00

48 lines
1.9 KiB
TypeScript

import { jsonResponse, parseUrl } from "../shared";
import { parseMultipart } from "../multipart";
import { handleTempUpload, handleAdminUpload } from "../upload";
/** POST /api/upload?mode=temp|admin — 上传字体 */
export async function handleUpload(req: Request, res: Response) {
const url = parseUrl(req);
const mode = url.searchParams.get("mode") ?? "temp";
const contentType = req.headers.get("Content-Type") ?? "";
console.log("[upload] mode:", mode, "contentType:", contentType);
const body = (req as Request & { _bodyBuffer?: ArrayBuffer })._bodyBuffer;
if (!body || body.byteLength === 0) {
return { req, res: jsonResponse({ success: false, error: "请求体为空" }, 400) };
}
console.log("[upload] body size:", body.byteLength);
let parsed;
try {
parsed = parseMultipart(contentType, body);
console.log("[upload] parsed files:", parsed.files.length);
} catch (err) {
console.log("[upload] parse error:", err);
return { req, res: jsonResponse({ success: false, error: "无效的 multipart 数据" }, 400) };
}
if (!parsed.files || parsed.files.length === 0) {
return { req, res: jsonResponse({ success: false, error: "未提供文件" }, 400) };
}
const file = parsed.files[0];
console.log("[upload] file:", file.name, "filename:", file.filename, "data size:", file.data.length);
let result;
if (mode === "admin") {
const authHeader = req.headers.get("Authorization") ?? "";
const apiKey = authHeader.replace("Bearer ", "");
result = await handleAdminUpload({ data: file.data, filename: file.filename }, apiKey);
console.log("[upload] admin result:", result);
return { req, res: jsonResponse(result, result.success ? 200 : 403) };
}
result = await handleTempUpload({ data: file.data, filename: file.filename });
console.log("[upload] temp result:", result);
return { req, res: jsonResponse(result, result.success ? 200 : 400) };
}