mirror of
https://github.com/kainy/Open-API.git
synced 2026-06-14 20:41:11 +08:00
Add files via upload
网关框架。
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
const { logger } = require('../utils/logger');
|
||||
|
||||
exports.errorHandler = async (ctx, next) => {
|
||||
try {
|
||||
await next();
|
||||
} catch (err) {
|
||||
logger.error('Request error:', err);
|
||||
|
||||
ctx.status = err.status || 500;
|
||||
ctx.body = {
|
||||
error: {
|
||||
message: err.message || 'Internal server error',
|
||||
status: ctx.status,
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
|
||||
// Emit error for potential monitoring
|
||||
ctx.app.emit('error', err, ctx);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
const { RedisClient } = require('../utils/redis');
|
||||
const { logger } = require('../utils/logger');
|
||||
|
||||
const RATE_LIMIT_WINDOW = 60; // 1 minute window
|
||||
const MAX_REQUESTS = 100; // Maximum requests per window
|
||||
|
||||
exports.rateLimiter = async (ctx, next) => {
|
||||
const apiKey = ctx.get('X-API-Key');
|
||||
if (!apiKey) {
|
||||
ctx.status = 401;
|
||||
ctx.body = { error: 'API key required' };
|
||||
return;
|
||||
}
|
||||
|
||||
const key = `ratelimit:${apiKey}`;
|
||||
|
||||
try {
|
||||
const [requests] = await RedisClient
|
||||
.multi()
|
||||
.incr(key)
|
||||
.expire(key, RATE_LIMIT_WINDOW)
|
||||
.exec();
|
||||
|
||||
const requestCount = requests[1];
|
||||
|
||||
ctx.set('X-RateLimit-Limit', MAX_REQUESTS);
|
||||
ctx.set('X-RateLimit-Remaining', Math.max(0, MAX_REQUESTS - requestCount));
|
||||
|
||||
if (requestCount > MAX_REQUESTS) {
|
||||
ctx.status = 429;
|
||||
ctx.body = { error: 'Rate limit exceeded' };
|
||||
return;
|
||||
}
|
||||
|
||||
await next();
|
||||
} catch (error) {
|
||||
logger.error('Rate limiter error:', error);
|
||||
await next(); // Proceed even if rate limiting fails
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user