2018-03-01 19:19:28 +08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const RATE_LIMIT_ENDPOINTS_GROUPS = {
|
|
|
|
QUERY: 'query',
|
|
|
|
JOB_CREATE: 'job_create',
|
|
|
|
JOB_GET: 'job_get',
|
2018-05-04 00:50:13 +08:00
|
|
|
JOB_DELETE: 'job_delete',
|
|
|
|
COPY_FROM: 'copy_from',
|
|
|
|
COPY_TO: 'copy_to'
|
2018-03-01 19:19:28 +08:00
|
|
|
};
|
|
|
|
|
2019-12-24 01:19:08 +08:00
|
|
|
function rateLimit (userLimits, endpointGroup = null) {
|
2018-03-02 23:42:45 +08:00
|
|
|
if (!isRateLimitEnabled(endpointGroup)) {
|
2019-12-24 01:19:08 +08:00
|
|
|
return function rateLimitDisabledMiddleware (req, res, next) { next(); };
|
2018-03-02 23:42:45 +08:00
|
|
|
}
|
2018-03-01 19:19:28 +08:00
|
|
|
|
2019-12-24 01:19:08 +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);
|
|
|
|
}
|
2018-12-11 01:20:10 +08:00
|
|
|
|
2018-03-02 23:42:45 +08:00
|
|
|
if (!userRateLimit) {
|
2018-03-01 19:19:28 +08:00
|
|
|
return next();
|
|
|
|
}
|
2018-12-11 01:20:10 +08:00
|
|
|
|
2018-03-02 23:42:45 +08:00
|
|
|
const [isBlocked, limit, remaining, retry, reset] = userRateLimit;
|
2018-12-11 01:20:10 +08:00
|
|
|
|
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
|
|
|
});
|
2018-12-11 01:20:10 +08:00
|
|
|
|
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-12-11 01:20:10 +08:00
|
|
|
|
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;
|
2018-03-27 01:10:23 +08:00
|
|
|
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
|
|
|
}
|
2018-12-11 01:20:10 +08:00
|
|
|
|
2018-03-01 19:19:28 +08:00
|
|
|
return next();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-12-24 01:19:08 +08:00
|
|
|
function isRateLimitEnabled (endpointGroup) {
|
2018-03-02 23:42:45 +08:00
|
|
|
return global.settings.ratelimits.rateLimitsEnabled &&
|
|
|
|
endpointGroup &&
|
|
|
|
global.settings.ratelimits.endpoints[endpointGroup];
|
2018-03-01 19:19:28 +08:00
|
|
|
}
|
|
|
|
|
2018-03-02 23:42:45 +08:00
|
|
|
module.exports = rateLimit;
|
2018-03-01 19:19:28 +08:00
|
|
|
module.exports.RATE_LIMIT_ENDPOINTS_GROUPS = RATE_LIMIT_ENDPOINTS_GROUPS;
|