109 lines
3.2 KiB
JavaScript
109 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
require('../helper');
|
|
|
|
const qs = require('querystring');
|
|
const assert = require('../support/assert');
|
|
const redis = require('redis');
|
|
const rateLimitMiddleware = require('../../lib/api/middlewares/rate-limit');
|
|
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimitMiddleware;
|
|
|
|
const app = require('../../lib/server');
|
|
let server;
|
|
|
|
let redisClient;
|
|
const keysToDelete = [];
|
|
const user = 'vizzuality';
|
|
|
|
var request = {
|
|
url: '/api/v1/sql?' + qs.stringify({
|
|
q: 'SELECT * FROM untitle_table_4'
|
|
}),
|
|
headers: {
|
|
host: 'vizzuality.cartodb.com'
|
|
},
|
|
method: 'GET'
|
|
};
|
|
|
|
function setLimit (count, period, burst) {
|
|
redisClient.SELECT(8, err => {
|
|
if (err) {
|
|
return;
|
|
}
|
|
|
|
const key = `limits:rate:store:${user}:sql:${RATE_LIMIT_ENDPOINTS_GROUPS.QUERY}`;
|
|
redisClient.rpush(key, burst);
|
|
redisClient.rpush(key, count);
|
|
redisClient.rpush(key, period);
|
|
keysToDelete.push(key);
|
|
});
|
|
}
|
|
|
|
function assertRequest (status, limit, remaining, reset, retry, done = null) {
|
|
assert.response(
|
|
server,
|
|
request,
|
|
{ status },
|
|
function (err, res) {
|
|
assert.ifError(err);
|
|
assert.strictEqual(res.headers['carto-rate-limit-limit'], limit);
|
|
assert.strictEqual(res.headers['carto-rate-limit-remaining'], remaining);
|
|
assert.strictEqual(res.headers['carto-rate-limit-reset'], reset);
|
|
|
|
if (retry) {
|
|
assert.strictEqual(res.headers['retry-after'], retry);
|
|
}
|
|
|
|
if (status === 429) {
|
|
const expectedResponse = {
|
|
error: ['You are over platform\'s limits. Please contact us to know more details'],
|
|
context: 'limit',
|
|
detail: 'rate-limit'
|
|
};
|
|
|
|
assert.deepStrictEqual(JSON.parse(res.body), expectedResponse);
|
|
}
|
|
|
|
if (done) {
|
|
setTimeout(done, 1000);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
describe('rate limit', function () {
|
|
before(function () {
|
|
global.settings.ratelimits.rateLimitsEnabled = true;
|
|
global.settings.ratelimits.endpoints.query = true;
|
|
|
|
server = app();
|
|
redisClient = redis.createClient({
|
|
port: global.settings.redis_port,
|
|
host: global.settings.redis_host
|
|
});
|
|
|
|
const count = 1;
|
|
const period = 1;
|
|
const burst = 1;
|
|
setLimit(count, period, burst);
|
|
});
|
|
|
|
after(function () {
|
|
global.settings.ratelimits.rateLimitsEnabled = false;
|
|
global.settings.ratelimits.endpoints.query = false;
|
|
|
|
keysToDelete.forEach(key => {
|
|
redisClient.del(key);
|
|
});
|
|
});
|
|
|
|
it('1 req/sec: 2 req/seg should be limited', function (done) {
|
|
assertRequest(200, '2', '1', '1');
|
|
setTimeout(() => assertRequest(200, '2', '0', '1', null), 250);
|
|
setTimeout(() => assertRequest(429, '2', '0', '1', '1'), 500);
|
|
setTimeout(() => assertRequest(429, '2', '0', '1', '1'), 750);
|
|
setTimeout(() => assertRequest(429, '2', '0', '1', '1'), 950);
|
|
setTimeout(() => assertRequest(200, '2', '0', '1', null, done), 1050);
|
|
});
|
|
});
|