mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Generalized rate-limit package and updated livedata_server.js to accept rules on methods and subscriptions.
Need to add checks and throw errors if wrong format / input to rate-limit package. Updated default rule in ddp-rate-limiter to reflect new rate-limit generic design and moved the location of the DDPRateLimiter in livedata_server.js. Need to fix tests for both ddp-rate-limiter and rate-limit packages with updated code and clean up rate-limit package.
This commit is contained in:
@@ -10,7 +10,8 @@ DDPRateLimiter.RateLimiter.addRule( {
|
||||
IPAddr: function( IPAddr ) {
|
||||
return true;
|
||||
},
|
||||
method: 'login'
|
||||
type: 'method',
|
||||
name: 'login'
|
||||
}, 5, 10000 );
|
||||
|
||||
DDPRateLimiter.getErrorMessage = function( rateLimitResult ) {
|
||||
|
||||
@@ -545,16 +545,24 @@ _.extend(Session.prototype, {
|
||||
|
||||
if (_.has(self.protocol_handlers, msg.msg)) {
|
||||
// Is it bad to do these checks here? Instead of inside session.protocol_handlers and then in method
|
||||
// var rateLimiterInput = {
|
||||
// userId: self.userId,
|
||||
// IPAddr: self.connectionHandle.clientAddress,
|
||||
// type: msg.msg,
|
||||
// name: msg.name }
|
||||
// DDPRateLimiter.RateLimiter.increment(rateLimiterInput);
|
||||
// var rateLimitResult = DDPRateLimiter.RateLimiter.check(rateLimiterInput)
|
||||
// if (!rateLimitResult.valid)
|
||||
// self.sendError('too-many-requests', DDPRateLimiter.getErrorMessage(rateLimitResult));
|
||||
// else
|
||||
var rateLimiterInput = {
|
||||
userId: self.userId,
|
||||
IPAddr: self.connectionHandle.clientAddress,
|
||||
type: msg.msg,
|
||||
name: null
|
||||
};
|
||||
// Janky solution because in method, methodName is in msg.method otherwise in msg.name for subscriptions
|
||||
if (msg.msg === 'method') {
|
||||
rateLimiterInput.name = msg.method;
|
||||
} else if (msg.msg === 'sub') {
|
||||
rateLimiterInput.name = msg.name;
|
||||
}
|
||||
DDPRateLimiter.RateLimiter.newIncrement(rateLimiterInput);
|
||||
var rateLimitResult = DDPRateLimiter.RateLimiter.newCheck(rateLimiterInput)
|
||||
if (!rateLimitResult.valid) {
|
||||
self.sendError('too-many-requests', DDPRateLimiter.getErrorMessage(rateLimitResult));
|
||||
}
|
||||
else
|
||||
self.protocol_handlers[msg.msg].call(self, msg, unblock);
|
||||
}
|
||||
else
|
||||
@@ -658,16 +666,16 @@ _.extend(Session.prototype, {
|
||||
randomSeed: randomSeed
|
||||
});
|
||||
// invocation.method = msg.method;
|
||||
var rateLimiterInput = {
|
||||
userId: self.userId,
|
||||
IPAddr: self.connectionHandle.clientAddress,
|
||||
method: msg.method};
|
||||
// var rateLimiterInput = {
|
||||
// userId: self.userId,
|
||||
// IPAddr: self.connectionHandle.clientAddress,
|
||||
// method: msg.method};
|
||||
try {
|
||||
DDPRateLimiter.RateLimiter.newIncrement(rateLimiterInput);
|
||||
var rateLimitResult = DDPRateLimiter.RateLimiter.newCheck(rateLimiterInput)
|
||||
if (!rateLimitResult.valid) {
|
||||
throw new Meteor.Error(429, DDPRateLimiter.getErrorMessage(rateLimitResult));
|
||||
}
|
||||
// DDPRateLimiter.RateLimiter.newIncrement(rateLimiterInput);
|
||||
// var rateLimitResult = DDPRateLimiter.RateLimiter.newCheck(rateLimiterInput)
|
||||
// if (!rateLimitResult.valid) {
|
||||
// throw new Meteor.Error(429, DDPRateLimiter.getErrorMessage(rateLimitResult));
|
||||
// }
|
||||
|
||||
var result = DDPServer._CurrentWriteFence.withValue(fence, function () {
|
||||
return DDP._CurrentInvocation.withValue(invocation, function () {
|
||||
|
||||
@@ -24,7 +24,7 @@ RateLimiter = function() {
|
||||
* @return {object} Returns object of whether method invocation is valid, time
|
||||
* to next reset and number invocations left
|
||||
*/
|
||||
RateLimiter.prototype.check = function( methodInvocation ) {
|
||||
/*RateLimiter.prototype.check = function( methodInvocation ) {
|
||||
var self = this;
|
||||
var reply = {
|
||||
valid: true,
|
||||
@@ -63,7 +63,7 @@ RateLimiter.prototype.check = function( methodInvocation ) {
|
||||
} );
|
||||
|
||||
return reply;
|
||||
}
|
||||
} */
|
||||
|
||||
RateLimiter.prototype.newCheck = function ( input ) {
|
||||
var self = this;
|
||||
@@ -124,7 +124,7 @@ RateLimiter.prototype.addRule = function( rule, numRequestsAllowed,
|
||||
* added 'method' attribute listing the method name
|
||||
* @return {boolean} Returns whether the methodInvocation matches inputted rule
|
||||
*/
|
||||
RateLimiter.prototype.matchRuleUsingFind = function( rule, methodInvocation ) {
|
||||
/*RateLimiter.prototype.matchRuleUsingFind = function( rule, methodInvocation ) {
|
||||
var self = this;
|
||||
var ruleMatches = true;
|
||||
_.find( RATE_LIMITING_DICT, function( value, key ) {
|
||||
@@ -146,7 +146,7 @@ RateLimiter.prototype.matchRuleUsingFind = function( rule, methodInvocation ) {
|
||||
} );
|
||||
|
||||
return ruleMatches;
|
||||
}
|
||||
}*/
|
||||
|
||||
RateLimiter.prototype._matchRule = function ( rule, input ) {
|
||||
var self = this;
|
||||
@@ -180,7 +180,7 @@ RateLimiter.prototype._matchRule = function ( rule, input ) {
|
||||
* @param {object} methodInvocation DDPCommon.MethodInvocation object with
|
||||
* added 'method' attribute listing the method name
|
||||
*/
|
||||
RateLimiter.prototype.increment = function( methodInvocation ) {
|
||||
/*RateLimiter.prototype.increment = function( methodInvocation ) {
|
||||
var self = this;
|
||||
// Figure out all the rules this method invocation matches
|
||||
_.each( this.rules, function( rule ) {
|
||||
@@ -212,7 +212,7 @@ RateLimiter.prototype.increment = function( methodInvocation ) {
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}*/
|
||||
|
||||
RateLimiter.prototype.newIncrement = function ( input ) {
|
||||
var self = this;
|
||||
@@ -258,7 +258,7 @@ RateLimiter.prototype._createNewRuleId = function() {
|
||||
* @return {string} Key string made of all fields from rule that match in
|
||||
* method invocation
|
||||
*/
|
||||
RateLimiter.prototype._generateMethodInvocationKeyStringFromRuleMapping =
|
||||
/*RateLimiter.prototype._generateMethodInvocationKeyStringFromRuleMapping =
|
||||
function( rule, methodInvocation ) {
|
||||
var self = this;
|
||||
var returnString = "";
|
||||
@@ -275,7 +275,7 @@ RateLimiter.prototype._generateMethodInvocationKeyStringFromRuleMapping =
|
||||
}
|
||||
} );
|
||||
return returnString;
|
||||
}
|
||||
}*/
|
||||
|
||||
RateLimiter.prototype._generateKeyString = function (rule, input) {
|
||||
var self = this;
|
||||
@@ -283,11 +283,13 @@ RateLimiter.prototype._generateKeyString = function (rule, input) {
|
||||
_.each( rule, function ( value, key) {
|
||||
if (value !== null) {
|
||||
if (typeof value === 'function') {
|
||||
if (value(input[key]))
|
||||
if (value(input[key])){
|
||||
returnString += key + input[key];
|
||||
}
|
||||
}
|
||||
else
|
||||
else{
|
||||
returnString += key + input[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
return returnString;
|
||||
@@ -302,7 +304,7 @@ RateLimiter.prototype._generateKeyString = function (rule, input) {
|
||||
* @return {object} Returns a string, value, or object of whatever is stored in
|
||||
* appropriate field in MethodInvocation
|
||||
*/
|
||||
RateLimiter.prototype._ruleMappingtoMethodInvocationDict = function( key,
|
||||
/*RateLimiter.prototype._ruleMappingtoMethodInvocationDict = function( key,
|
||||
methodInvocation ) {
|
||||
|
||||
var arr = RATE_LIMITING_DICT[ key ].split( '.' );
|
||||
@@ -311,8 +313,8 @@ RateLimiter.prototype._ruleMappingtoMethodInvocationDict = function( key,
|
||||
methodInvocation = methodInvocation[ firstGuy ];
|
||||
}
|
||||
return methodInvocation;
|
||||
};
|
||||
|
||||
}; */
|
||||
/*
|
||||
RateLimiter.prototype._matchRuleHelper = function( rule, methodInvocation ) {
|
||||
var self = this;
|
||||
|
||||
@@ -325,7 +327,7 @@ RateLimiter.prototype._matchRuleHelper = function( rule, methodInvocation ) {
|
||||
timeSinceLastReset: timeSinceLastReset,
|
||||
timeToNextReset: timeToNextReset
|
||||
};
|
||||
}
|
||||
} */
|
||||
|
||||
RateLimiter.prototype._newRuleHelper = function (rule, input) {
|
||||
var self = this;
|
||||
|
||||
Reference in New Issue
Block a user