修复md导入问题
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
// 简单的内存速率限制器(基于 IP)
|
||||
|
||||
interface RateLimitEntry {
|
||||
count: number;
|
||||
resetAt: number;
|
||||
}
|
||||
|
||||
const store = new Map<string, RateLimitEntry>();
|
||||
|
||||
// 定期清理过期条目,防止内存泄漏
|
||||
const CLEANUP_INTERVAL_MS = 5 * 60 * 1000; // 5 分钟
|
||||
setInterval(() => {
|
||||
const now = Date.now();
|
||||
for (const [key, entry] of store) {
|
||||
if (now >= entry.resetAt) {
|
||||
store.delete(key);
|
||||
}
|
||||
}
|
||||
}, CLEANUP_INTERVAL_MS);
|
||||
|
||||
/**
|
||||
* 检查请求是否超过速率限制
|
||||
* @param key 限制键(通常是 IP 地址)
|
||||
* @param maxAttempts 窗口期内最大尝试次数
|
||||
* @param windowMs 窗口期(毫秒)
|
||||
* @returns 如果超限返回 true,否则返回 false
|
||||
*/
|
||||
export function isRateLimited(
|
||||
key: string,
|
||||
maxAttempts: number = 5,
|
||||
windowMs: number = 60 * 1000
|
||||
): boolean {
|
||||
const now = Date.now();
|
||||
const entry = store.get(key);
|
||||
|
||||
if (!entry || now >= entry.resetAt) {
|
||||
store.set(key, { count: 1, resetAt: now + windowMs });
|
||||
return false;
|
||||
}
|
||||
|
||||
entry.count += 1;
|
||||
return entry.count > maxAttempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Request 对象中提取客户端 IP
|
||||
*/
|
||||
export function getClientIp(req: Request): string {
|
||||
// 常见的代理头
|
||||
const forwarded = req.headers.get("x-forwarded-for");
|
||||
if (forwarded) {
|
||||
return forwarded.split(",")[0].trim();
|
||||
}
|
||||
const realIp = req.headers.get("x-real-ip");
|
||||
if (realIp) {
|
||||
return realIp.trim();
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
Reference in New Issue
Block a user