New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dddos

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dddos - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

.eslintrc.json

116

index.js

@@ -1,63 +0,83 @@

const Util = require('util');
const {isArray} = require('util');
const Rule = require('./rule');
const DEFAULT_RULES = [{ regexp: '.*' }];
const DEFAULT_CHECK_INTERVAL = 1000; // One second
const DEFAULT_RULES = [{regexp: '.*'}];
function DDDoS(options) {
if (typeof options === 'null' || typeof options === 'undefined') {
options = {};
class DDDoS {
constructor(options = {}) {
if (options === null) {
options = {};
}
let checkInterval = Number(options.checkInterval);
if (isNaN(checkInterval) || checkInterval <= 0) {
checkInterval = DEFAULT_CHECK_INTERVAL;
}
this.checkInterval = checkInterval;
this.paths = new Map();
this.rules = [];
const rules = isArray(options.rules) ? options.rules : DEFAULT_RULES;
rules.forEach(rule => this._addRule(rule, options));
setInterval(this._check.bind(this), checkInterval);
}
this.checkInterval = +options.checkInterval;
if (isNaN(this.checkInterval) || this.checkInterval <= 0) {
this.checkInterval = 1000; //NOTE: One second.
}
this.paths = new Map();
this.rules = [];
(Util.isArray(options.rules) ? options.rules : DEFAULT_RULES).forEach((rule) => {
if (typeof rule.regexp === 'string') {
this.rules.push(new Rule(rule));
} else if (rule.string) {
this.paths.set(rule.string, new Rule(rule));
request(ip, path, ddos, next) {
if (typeof path !== 'string') {
path = '';
}
});
setInterval(this._check.bind(this), this.checkInterval);
}
DDDoS.prototype._check = function() {
this.paths.forEach((path) => { path.check(); });
this.rules.forEach((rule) => { rule.check(); });
};
const rule = this.paths.get(path);
DDDoS.prototype.request = function(ip, path, ddos, next) {
if (typeof path !== 'string') {
path = '';
}
let rule = this.paths.get(path);
if (rule) {
return rule.use(ip, path, ddos, next);
}
this.rules.some((rule) => {
let matches = path.match(rule.regexp);
if (matches) {
if (rule) {
rule.use(ip, path, ddos, next);
return;
}
return matches;
});
};
DDDoS.prototype.express = function(ipPropertyName, pathPropertyName) {
if (typeof ipPropertyName !== 'string' || !ipPropertyName) {
ipPropertyName = 'ip';
this.rules.some(rule => {
const matches = path.match(rule.regexp);
if (matches) {
rule.use(ip, path, ddos, next);
}
return matches;
});
}
if (typeof pathPropertyName !== 'string' || !pathPropertyName) {
pathPropertyName = 'path';
express(ipPropertyName, pathPropertyName) {
if (typeof ipPropertyName !== 'string' || !ipPropertyName) {
ipPropertyName = 'ip';
}
if (typeof pathPropertyName !== 'string' || !pathPropertyName) {
pathPropertyName = 'path';
}
return (req, res, next) => {
this.request(req[ipPropertyName], req[pathPropertyName], (errorCode, errorData) => {
res.status(errorCode).send(errorData);
}, next);
};
}
return (req, res, next) => {
this.request(req[ipPropertyName], req[pathPropertyName], (errorCode, errorData) => {
res.status(errorCode).send(errorData);
}, next);
};
};
_addRule(rule, options) {
if (typeof rule.regexp === 'string') {
this.rules.push(new Rule(rule, options));
} else if (typeof rule.string === 'string') {
this.paths.set(rule.string, new Rule(rule, options));
}
}
_check() {
this.paths.forEach(path => path.check());
this.rules.forEach(rule => rule.check());
}
}
module.exports = DDDoS;
{
"name": "dddos",
"version": "0.1.1",
"description": "",
"version": "0.1.2",
"description": "Configurable Denial-Of-Service prevention library",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"lint": "eslint ./*.js",
"test": "mocha ./tests/*"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"repository": {

@@ -18,3 +22,3 @@ "type": "git",

],
"author": "Andrey Bogdanov <ololoepepe@gmail.com> (https://ololoepepe.me)",
"author": "Andrey Bogdanov <ololoepepe@gmail.com> (https://ololoepepe.ru)",
"license": "MIT",

@@ -24,3 +28,8 @@ "bugs": {

},
"homepage": "https://github.com/ololoepepe/dddos"
"homepage": "https://github.com/ololoepepe/dddos",
"devDependencies": {
"eslint": "^4.8.0",
"eslint-config-xo": "^0.18.2",
"mocha": "^3.4.2"
}
}

@@ -7,4 +7,4 @@ # Configurable Denial-Of-Service prevention library

```
/* With Express*/
```js
/* With Express */

@@ -64,3 +64,3 @@ let expresss = require('express');

```
```js
rules: [

@@ -67,0 +67,0 @@ { /*Allow 4 requests accessing the application API per checkInterval*/

@@ -1,52 +0,80 @@

function setProperty(name, options, defOptions, defValue) {
this[name] = +options[name] || +defOptions[name] || defValue;
if (isNaN(this[name]) || this[name] < 0) {
this[name] = defValue;
const HTTP_TOO_MANY_REQUESTS = 429;
const DEFAULT_WEIGHT = 1;
const DEFAULT_MAX_WEIGHT = 10;
const DEFAULT_ERROR_CODE = HTTP_TOO_MANY_REQUESTS;
const DEFAULT_QUEUE_SIZE = 0; // No queue.
const DEFAULT_ERROR_DATA = 'Not so fast!';
class Rule {
static get DEFAULT_WEIGHT() {
return DEFAULT_WEIGHT;
}
}
function Rule(options, defOptions) {
if (typeof options === 'null' || typeof options === 'undefined') {
options = {};
static get DEFAULT_MAX_WEIGHT() {
return DEFAULT_MAX_WEIGHT;
}
if (typeof defOptions === 'null' || typeof defOptions === 'undefined') {
defOptions = {};
static get DEFAULT_ERROR_CODE() {
return DEFAULT_ERROR_CODE;
}
if (typeof options.string === 'string') {
this.string = options.string;
} else if (typeof options.regexp === 'string') {
this.regexp = new RegExp(options.regexp, options.flags);
static get DEFAULT_QUEUE_SIZE() {
return DEFAULT_QUEUE_SIZE;
}
setProperty.call(this, 'weight', options, defOptions, 1);
setProperty.call(this, 'maxWeight', options, defOptions, 10);
setProperty.call(this, 'errorCode', options, defOptions, 429); //NOTE: 429 - Too Many Requests.
setProperty.call(this, 'queueSize', options, defOptions, 0); //NOTE: No queue.
if (typeof options.errorData !== 'undefined') {
this.errorData = options.errorData;
} else if (typeof defOptions.errorData !== 'undefined') {
this.errorData = defOptions.errorData;
} else {
this.errorData = 'Not so fast!';
static get DEFAULT_ERROR_DATA() {
return DEFAULT_ERROR_DATA;
}
if (typeof defOptions.logFunction === 'function') {
this.logFunction = defOptions.logFunction;
constructor(rule = {}, options = {}) {
if (rule === null) {
rule = {};
}
if (options === null) {
options = {};
}
const {string, regexp} = rule;
this.string = string;
this.regexp = regexp;
this.weight = _getNumber('weight', rule, options, DEFAULT_WEIGHT);
this.maxWeight = _getNumber('maxWeight', rule, options, DEFAULT_MAX_WEIGHT);
this.errorCode = _getNumber('errorCode', rule, options, DEFAULT_ERROR_CODE);
this.queueSize = _getNumber('queueSize', rule, options, DEFAULT_QUEUE_SIZE);
this.errorData = _getNonUndefined('errorData', rule, options, DEFAULT_ERROR_DATA);
this.logFunction = _getFunction('logFunction', rule, options);
this.users = new Map();
}
this.users = new Map();
}
Rule.prototype.use = function(ip, path, ddos, next) {
let user = this.users.get(ip);
if (!user) {
user = { weight: 0 };
if (this.queueSize > 0) {
user.queue = [];
use(ip, path, ddos, next) {
let user = this.users.get(ip);
if (user) {
user.weight += this.weight;
} else {
user = {
weight: this.weight,
queue: []
};
this.users.set(ip, user);
}
this.users.set(ip, user);
}
user.weight += this.weight;
if (user.weight > this.maxWeight) {
if (user.weight <= this.maxWeight) {
if (typeof next === 'function') {
next();
}
return;
}
if (typeof this.logFunction === 'function') {
this.logFunction(ip, path, user.weight, this.maxWeight, this.regexp || this.string);
}
if (user.queue && user.queue.length < this.queueSize) {
if (user.queue.length < this.queueSize) {
user.queue.push(next);

@@ -56,26 +84,68 @@ } else if (typeof ddos === 'function') {

}
return;
}
if (typeof next === 'function') {
next();
}
};
Rule.prototype.check = function() {
this.users.forEach((user, ip) => {
user.weight -= this.maxWeight;
let count = this.maxWeight - user.weight;
if (user.queue && user.queue.length > 0 && count > 0) {
let items = user.queue.splice(0, count);
if (typeof next === 'function') {
items.forEach((next) => { setImmediate(next); });
check() {
this.users.forEach((user, ip) => {
user.weight -= this.maxWeight;
const count = this.maxWeight - user.weight;
if ((count > 0) && (user.queue.length > 0)) {
user.queue
.splice(0, count)
.filter(next => typeof next === 'function')
.forEach(next => setImmediate(next));
user.weight += count;
}
user.weight += count;
}
if (user.weight <= 0) {
this.users.delete(ip);
}
});
};
if (user.weight <= 0) {
this.users.delete(ip);
}
});
}
}
function _getNumber(name, rule, options, defValue) {
const value = Number(rule[name]) || Number(options[name]);
if (isNaN(value) || (value < 0)) {
return defValue;
}
return value;
}
function _getNonUndefined(name, rule, options, defValue) {
let value = rule[name];
if (value !== undefined) {
return value;
}
value = options[name];
if (value !== undefined) {
return value;
}
return defValue;
}
function _getFunction(name, rule, options, defValue) {
let value = rule[name];
if (typeof value === 'function') {
return value;
}
value = options[name];
if (typeof value === 'function') {
return value;
}
return defValue;
}
module.exports = Rule;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc