diff --git a/node_modules/c9/ratelimit.js b/node_modules/c9/ratelimit.js index 0efc15ef..33f9d47c 100644 --- a/node_modules/c9/ratelimit.js +++ b/node_modules/c9/ratelimit.js @@ -7,34 +7,42 @@ var _ = require("lodash"); module.exports = ratelimit; function ratelimit(key, duration, max) { - var requests = {}; + var requests = Object.create(null); // in case there handles like 'constructor' setInterval(function() { - _.forIn(requests, function (requestsForHandle, key) { - var totalToSplice = 0; - var expireTime = Date.now() - duration; - /* Requests are already sorted by date as they are appended, so we just loop - until we find one that shouldn't have expired and splice them from the list */ - for (var i = 0; i < requestsForHandle.length; i++) { - if (requestsForHandle[i] >= expireTime) break; - totalToSplice++; - } - requests[key].splice(0, totalToSplice); - if (requests[key].length == 0) { - delete requests[key]; - } - }); - }, 10); - return function(req, res, next) { - var handle = req.params[key]; - - requests[handle] = requests[handle] || []; - if (requests[handle].length >= max) { - var err = new error.TooManyRequests("Rate limit exceeded"); - err.retryIn = Math.min(duration, 5000); - return next(err); + Object.keys(requests).forEach(expireRequests); + }, duration * 0.75); + + function expireRequests(value) { + var requestsForHandle = requests[value]; + var totalToSplice = 0; + var expireTime = Date.now() - duration; + /* Requests are already sorted by date as they are appended, so we just loop + until we find one that shouldn't have expired and splice them from the list */ + for (var i = 0; i < requestsForHandle.length; i++) { + if (requestsForHandle[i] >= expireTime) break; + totalToSplice++; + } + requests[value].splice(0, totalToSplice); + if (requests[value].length == 0) { + delete requests[value]; } - requests[handle].push(Date.now()); + return true; + } + + 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"); + err.retryIn = Math.min(duration, 5000); + return next(err); + } + } + + requests[value].push(Date.now()); return next(); }; }