kopia lustrzana https://github.com/c9/core
Merge pull request +14872 from c9/api-ratelimit-collab
Add ratelimits to collabpull/365/head
commit
8531719c2e
|
@ -30,8 +30,15 @@ function ratelimit(key, duration, max) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a deep value from an object. E.g. resolveValue({user: {id: 5}}, "user.id") === 5
|
||||||
|
function resolveValue(obj, path) {
|
||||||
|
return path.split('.').reduce(function(prev, curr) {
|
||||||
|
return prev ? prev[curr] : undefined;
|
||||||
|
}, obj);
|
||||||
|
}
|
||||||
|
|
||||||
return function(req, res, next) {
|
return function(req, res, next) {
|
||||||
var handle = req.params[key];
|
var handle = resolveValue(req.params, key);
|
||||||
|
|
||||||
requests[handle] = requests[handle] || [];
|
requests[handle] = requests[handle] || [];
|
||||||
if (requests[handle].length >= max) {
|
if (requests[handle].length >= max) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ require("c9/inline-mocha")(module);
|
||||||
var ratelimit = require("./ratelimit");
|
var ratelimit = require("./ratelimit");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
|
var sinon = require("sinon");
|
||||||
|
|
||||||
describe("ratelimit", function() {
|
describe("ratelimit", function() {
|
||||||
|
|
||||||
|
@ -31,7 +32,16 @@ describe("ratelimit", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should work with deep keys", function (done) {
|
||||||
|
var limiter = ratelimit("user.id", 10, 1);
|
||||||
|
limiter({params: {user: {id: "hey"}}}, null, function (err) {
|
||||||
|
assert(!err, err);
|
||||||
|
limiter({params: {user: {id: "yay"}}}, null, function (err) {
|
||||||
|
assert(!err, err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("Should work again after a delay", function (done) {
|
it("Should work again after a delay", function (done) {
|
||||||
var limiter = ratelimit("username", 10, 1);
|
var limiter = ratelimit("username", 10, 1);
|
||||||
|
@ -68,37 +78,27 @@ describe("ratelimit", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should expire keys at the correct times", function (done) {
|
it("Should expire keys at the correct times", function (done) {
|
||||||
|
var clock = sinon.useFakeTimers();
|
||||||
var limiter = ratelimit("username", 50, 2);
|
var limiter = ratelimit("username", 50, 2);
|
||||||
async.series([
|
limiter({params: {username: "mario"}}, null, function(err){
|
||||||
function(next) {
|
assert(!err, err);
|
||||||
limiter({params: {username: "mario"}}, null, function(err) {
|
});
|
||||||
assert(!err, err);
|
clock.tick(40);
|
||||||
setTimeout(next, 25);
|
limiter({params: {username: "mario"}}, null, function(err){
|
||||||
});
|
assert(!err, err);
|
||||||
},
|
});
|
||||||
function (next) {
|
clock.tick(45);
|
||||||
limiter({params: {username: "mario"}}, null, function(err) {
|
limiter({params: {username: "mario"}}, null, function(err){
|
||||||
assert(!err, err);
|
assert(!err, err);
|
||||||
setTimeout(next, 40);
|
});
|
||||||
});
|
limiter({params: {username: "mario"}}, null, function(err){
|
||||||
},
|
assert(err);
|
||||||
function (next) {
|
assert.equal(err.code, 429);
|
||||||
limiter({params: {username: "mario"}}, null, function(err) {
|
});
|
||||||
assert(!err, err);
|
clock.tick(40);
|
||||||
limiter({params: {username: "mario"}}, null, function(err) {
|
limiter({params: {username: "mario"}}, null, function(err){
|
||||||
assert(err);
|
assert(!err, err);
|
||||||
assert.equal(err.code, 429);
|
});
|
||||||
setTimeout(next, 20);
|
done();
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
limiter({params: {username: "mario"}}, null, function(err) {
|
|
||||||
assert(!err, err);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
], done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
Ładowanie…
Reference in New Issue