Windshaft-cartodb/lib/api/middlewares/rate-limit.js

72 lines
2.2 KiB
JavaScript
Raw Normal View History

2018-02-13 00:19:08 +08:00
'use strict';
const RATE_LIMIT_ENDPOINTS_GROUPS = {
2018-02-28 00:57:25 +08:00
ANONYMOUS: 'anonymous',
STATIC: 'static',
STATIC_NAMED: 'static_named',
DATAVIEW: 'dataview',
DATAVIEW_SEARCH: 'dataview_search',
ANALYSIS: 'analysis',
2018-03-15 00:46:19 +08:00
ANALYSIS_CATALOG: 'analysis_catalog',
2018-02-28 00:57:25 +08:00
TILE: 'tile',
ATTRIBUTES: 'attributes',
NAMED_LIST: 'named_list',
NAMED_CREATE: 'named_create',
NAMED_GET: 'named_get',
NAMED: 'named',
NAMED_UPDATE: 'named_update',
NAMED_DELETE: 'named_delete',
NAMED_TILES: 'named_tiles'
2018-02-13 00:19:08 +08:00
};
2019-10-22 01:07:24 +08:00
function rateLimit (userLimitsBackend, endpointGroup = null) {
2018-03-02 22:48:31 +08:00
if (!isRateLimitEnabled(endpointGroup)) {
2019-10-22 01:07:24 +08:00
return function rateLimitDisabledMiddleware (req, res, next) { next(); };
2018-03-02 22:33:50 +08:00
}
2018-02-26 18:20:31 +08:00
2019-10-22 01:07:24 +08:00
return function rateLimitMiddleware (req, res, next) {
userLimitsBackend.getRateLimit(res.locals.user, endpointGroup, function (err, userRateLimit) {
2018-02-13 00:19:08 +08:00
if (err) {
return next(err);
}
2018-03-02 22:33:50 +08:00
2018-03-02 22:35:38 +08:00
if (!userRateLimit) {
2018-02-15 01:39:57 +08:00
return next();
}
2018-03-02 22:33:50 +08:00
2018-03-02 22:35:38 +08:00
const [isBlocked, limit, remaining, retry, reset] = userRateLimit;
2018-03-02 22:33:50 +08:00
2018-02-13 00:19:08 +08:00
res.set({
2018-03-14 19:09:20 +08:00
'Carto-Rate-Limit-Limit': limit,
'Carto-Rate-Limit-Remaining': remaining,
'Carto-Rate-Limit-Reset': reset
2018-02-13 00:19:08 +08:00
});
2018-03-02 22:33:50 +08:00
2018-02-28 00:36:03 +08:00
if (isBlocked) {
2018-03-23 17:23:57 +08:00
// retry is floor rounded in seconds by redis-cell
res.set('Retry-After', retry + 1);
2019-10-22 01:07:24 +08:00
const rateLimitError = new Error(
2018-07-03 20:48:54 +08:00
'You are over platform\'s limits: too many requests.' +
' Please contact us to know more details'
2018-03-23 18:42:53 +08:00
);
2018-03-01 22:50:20 +08:00
rateLimitError.http_status = 429;
rateLimitError.type = 'limit';
rateLimitError.subtype = 'rate-limit';
2018-03-01 22:50:20 +08:00
return next(rateLimitError);
2018-02-13 00:19:08 +08:00
}
2018-03-02 22:33:50 +08:00
2018-02-15 01:39:57 +08:00
return next();
2018-02-13 00:19:08 +08:00
});
};
2018-02-20 00:08:26 +08:00
}
2018-02-13 00:19:08 +08:00
2019-10-22 01:07:24 +08:00
function isRateLimitEnabled (endpointGroup) {
2018-03-02 22:33:50 +08:00
return global.environment.enabledFeatures.rateLimitsEnabled &&
endpointGroup &&
global.environment.enabledFeatures.rateLimitsByEndpoint[endpointGroup];
}
2018-03-02 22:35:38 +08:00
module.exports = rateLimit;
module.exports.RATE_LIMIT_ENDPOINTS_GROUPS = RATE_LIMIT_ENDPOINTS_GROUPS;