mirror of
https://github.com/ZeroCatDev/ClassworksKV.git
synced 2025-07-01 11:59:22 +00:00
116 lines
3.1 KiB
JavaScript
116 lines
3.1 KiB
JavaScript
import "./utils/instrumentation.js";
|
||
// import createError from "http-errors";
|
||
import express from "express";
|
||
import { join, dirname } from "path";
|
||
import { fileURLToPath } from "url";
|
||
// import cookieParser from "cookie-parser";
|
||
import logger from "morgan";
|
||
import bodyParser from "body-parser";
|
||
import errorHandler from "./middleware/errorHandler.js";
|
||
import errors from "./utils/errors.js";
|
||
import { initReadme, getReadmeValue } from "./utils/siteinfo.js";
|
||
import {
|
||
globalLimiter,
|
||
apiLimiter,
|
||
methodBasedRateLimiter,
|
||
} from "./middleware/rateLimiter.js";
|
||
|
||
import kvRouter from "./routes/kv.js";
|
||
|
||
var app = express();
|
||
|
||
import cors from "cors";
|
||
app.options("/{*path}", cors());
|
||
app.use(
|
||
cors({
|
||
exposedHeaders: ["ratelimit-policy", "retry-after", "ratelimit"], // 告诉浏览器这些响应头可以暴露
|
||
maxAge: 86400, // 设置OPTIONS请求的结果缓存24小时(86400秒),减少预检请求
|
||
})
|
||
);
|
||
app.disable("x-powered-by");
|
||
|
||
// 获取当前文件的目录路径
|
||
const __filename = fileURLToPath(import.meta.url);
|
||
const __dirname = dirname(__filename);
|
||
|
||
// 初始化 readme
|
||
initReadme();
|
||
|
||
// 应用全局限速
|
||
app.use(globalLimiter);
|
||
|
||
// view engine setup
|
||
app.set("views", join(__dirname, "views"));
|
||
app.set("view engine", "ejs");
|
||
app.use(bodyParser.urlencoded({ extended: true }));
|
||
app.use(bodyParser.json());
|
||
app.use(logger("dev"));
|
||
app.use(express.json());
|
||
app.use(express.urlencoded({ extended: false }));
|
||
// app.use(cookieParser());
|
||
app.use(express.static(join(__dirname, "public")));
|
||
|
||
// 添加请求超时处理中间件
|
||
app.use((req, res, next) => {
|
||
// 设置默认请求超时时间为30秒
|
||
const timeout = 30000;
|
||
|
||
// 设置超时回调
|
||
const timeoutCallback = () => {
|
||
const timeoutError = errors.createError(408, "请求处理超时");
|
||
next(timeoutError);
|
||
};
|
||
|
||
// 设置超时
|
||
req.setTimeout(timeout, timeoutCallback);
|
||
|
||
// 监听响应完成事件
|
||
res.on("finish", () => {
|
||
// 如果响应已经完成,清除超时处理
|
||
req.setTimeout(0, timeoutCallback);
|
||
});
|
||
|
||
next();
|
||
});
|
||
app.get("/", (req, res) => {
|
||
res.render("index.ejs", { readmeValue: getReadmeValue() });
|
||
});
|
||
app.get("/check", apiLimiter, (req, res) => {
|
||
res.json({
|
||
status: "success",
|
||
message: "API is running",
|
||
time: new Date().getTime(),
|
||
});
|
||
});
|
||
|
||
// Mount the KV store router with method-based rate limiting
|
||
app.use("/", methodBasedRateLimiter, kvRouter);
|
||
|
||
// 兜底404路由 - 处理所有未匹配的路由
|
||
app.use((req, res, next) => {
|
||
const notFoundError = errors.createError(404, `找不到路径: ${req.path}`);
|
||
next(notFoundError);
|
||
});
|
||
|
||
// 全局错误处理中间件
|
||
app.use(errorHandler);
|
||
|
||
// 全局未捕获的异常处理
|
||
process.on("uncaughtException", (error) => {
|
||
console.error("未捕获的异常:", error);
|
||
// 记录错误但不退出进程
|
||
});
|
||
|
||
// 全局未处理的Promise拒绝处理
|
||
process.on("unhandledRejection", (reason, promise) => {
|
||
console.error("未处理的Promise拒绝:", reason);
|
||
// 记录错误但不退出进程
|
||
});
|
||
|
||
// 处理 SIGTERM 信号
|
||
process.on("SIGTERM", () => {
|
||
console.log("收到 SIGTERM 信号,准备关闭服务...");
|
||
});
|
||
|
||
export default app;
|