CartoDB-SQL-API/app/middlewares/rate-limit.js

61 lines
1.8 KiB
JavaScript
Raw Normal View History

2018-03-01 19:19:28 +08:00
'use strict';
const RATE_LIMIT_ENDPOINTS_GROUPS = {
QUERY: 'query',
QUERY_FORMAT: 'query_format',
JOB_CREATE: 'job_create',
JOB_GET: 'job_get',
JOB_DELETE: 'job_delete'
};
function rateLimit(userLimits, endpointGroup = null) {
if (!isRateLimitEnabled(endpointGroup)) {
return function rateLimitDisabledMiddleware(req, res, next) { next(); };
}
2018-03-01 19:19:28 +08:00
return function rateLimitMiddleware(req, res, next) {
userLimits.getRateLimit(res.locals.user, endpointGroup, function(err, userRateLimit) {
2018-03-01 19:19:28 +08:00
if (err) {
return next(err);
}
if (!userRateLimit) {
2018-03-01 19:19:28 +08:00
return next();
}
const [isBlocked, limit, remaining, retry, reset] = userRateLimit;
2018-03-01 19:19:28 +08:00
res.set({
2018-03-14 19:17:26 +08:00
'Carto-Rate-Limit-Limit': limit,
'Carto-Rate-Limit-Remaining': remaining,
'Carto-Rate-Limit-Reset': reset
2018-03-01 19:19:28 +08:00
});
if (isBlocked) {
2018-03-23 22:09:16 +08:00
// retry is floor rounded in seconds by redis-cell
res.set('Retry-After', retry + 1);
2018-03-23 22:35:06 +08:00
const rateLimitError = new Error(
'You are over platform\'s limits. Please contact us to know more details'
);
2018-03-01 21:47:34 +08:00
rateLimitError.http_status = 429;
rateLimitError.context = 'limit';
rateLimitError.detail = 'rate-limit';
2018-03-01 21:47:34 +08:00
return next(rateLimitError);
2018-03-01 19:19:28 +08:00
}
return next();
});
};
}
function isRateLimitEnabled(endpointGroup) {
return global.settings.ratelimits.rateLimitsEnabled &&
endpointGroup &&
global.settings.ratelimits.endpoints[endpointGroup];
2018-03-01 19:19:28 +08:00
}
module.exports = rateLimit;
2018-03-01 19:19:28 +08:00
module.exports.RATE_LIMIT_ENDPOINTS_GROUPS = RATE_LIMIT_ENDPOINTS_GROUPS;