kopia lustrzana https://github.com/c9/core
Made requests object safer. Expire requests before sending error back
rodzic
9d6c7e47d7
commit
1e04331410
|
@ -7,9 +7,13 @@ var _ = require("lodash");
|
||||||
module.exports = ratelimit;
|
module.exports = ratelimit;
|
||||||
|
|
||||||
function ratelimit(key, duration, max) {
|
function ratelimit(key, duration, max) {
|
||||||
var requests = {};
|
var requests = Object.create(null); // in case there handles like 'constructor'
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
_.forIn(requests, function (requestsForHandle, key) {
|
Object.keys(requests).forEach(expireRequests);
|
||||||
|
}, duration * 0.75);
|
||||||
|
|
||||||
|
function expireRequests(value) {
|
||||||
|
var requestsForHandle = requests[value];
|
||||||
var totalToSplice = 0;
|
var totalToSplice = 0;
|
||||||
var expireTime = Date.now() - duration;
|
var expireTime = Date.now() - duration;
|
||||||
/* Requests are already sorted by date as they are appended, so we just loop
|
/* Requests are already sorted by date as they are appended, so we just loop
|
||||||
|
@ -18,23 +22,27 @@ function ratelimit(key, duration, max) {
|
||||||
if (requestsForHandle[i] >= expireTime) break;
|
if (requestsForHandle[i] >= expireTime) break;
|
||||||
totalToSplice++;
|
totalToSplice++;
|
||||||
}
|
}
|
||||||
requests[key].splice(0, totalToSplice);
|
requests[value].splice(0, totalToSplice);
|
||||||
if (requests[key].length == 0) {
|
if (requests[value].length == 0) {
|
||||||
delete requests[key];
|
delete requests[value];
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}, 10);
|
|
||||||
return function(req, res, next) {
|
|
||||||
var handle = req.params[key];
|
|
||||||
|
|
||||||
requests[handle] = requests[handle] || [];
|
return true;
|
||||||
if (requests[handle].length >= max) {
|
}
|
||||||
|
|
||||||
|
return function(req, res, next) {
|
||||||
|
var value = req.params[key];
|
||||||
|
|
||||||
|
requests[value] = requests[value] || [];
|
||||||
|
if (requests[value].length >= max) {
|
||||||
|
if (expireRequests(value) && requests[value].length >= max) {
|
||||||
var err = new error.TooManyRequests("Rate limit exceeded");
|
var err = new error.TooManyRequests("Rate limit exceeded");
|
||||||
err.retryIn = Math.min(duration, 5000);
|
err.retryIn = Math.min(duration, 5000);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
requests[handle].push(Date.now());
|
requests[value].push(Date.now());
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue