Merge pull request #109 from seejohnrun/rate_limiting
Added user-configurable rate limiting
This commit is contained in:
commit
6835eef468
4 changed files with 82 additions and 38 deletions
10
README.md
10
README.md
|
@ -46,6 +46,16 @@ STDOUT. Check the README there for more details and usages.
|
||||||
* `storage` - storage options (see below)
|
* `storage` - storage options (see below)
|
||||||
* `logging` - logging preferences
|
* `logging` - logging preferences
|
||||||
* `keyGenerator` - key generator options (see below)
|
* `keyGenerator` - key generator options (see below)
|
||||||
|
* `rateLimits` - settings for rate limiting (see below)
|
||||||
|
|
||||||
|
## Rate Limiting
|
||||||
|
|
||||||
|
When present, the `rateLimits` option enables built-in rate limiting courtesy
|
||||||
|
of `connect-ratelimit`. Any of the options supported by that library can be
|
||||||
|
used and set in `config.json`.
|
||||||
|
|
||||||
|
See the README for [connect-ratelimit](https://github.com/dharmafly/connect-ratelimit)
|
||||||
|
for more information!
|
||||||
|
|
||||||
## Key Generation
|
## Key Generation
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,15 @@
|
||||||
"type": "phonetic"
|
"type": "phonetic"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"rateLimits": {
|
||||||
|
"categories": {
|
||||||
|
"normal": {
|
||||||
|
"totalRequests": 500,
|
||||||
|
"every": 60000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"storage": {
|
"storage": {
|
||||||
"type": "redis",
|
"type": "redis",
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
},
|
},
|
||||||
"main": "haste",
|
"main": "haste",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"connect-ratelimit": "0.0.7",
|
||||||
|
"connect-route": "0.1.5",
|
||||||
|
"connect": "3.4.1",
|
||||||
|
"st": "1.1.0",
|
||||||
"winston": "0.6.2",
|
"winston": "0.6.2",
|
||||||
"connect": "1.9.2",
|
|
||||||
"redis-url": "0.1.0",
|
"redis-url": "0.1.0",
|
||||||
"redis": "0.8.1",
|
"redis": "0.8.1",
|
||||||
"uglify-js": "1.3.3",
|
"uglify-js": "1.3.3",
|
||||||
|
|
58
server.js
58
server.js
|
@ -4,6 +4,9 @@ var fs = require('fs');
|
||||||
|
|
||||||
var winston = require('winston');
|
var winston = require('winston');
|
||||||
var connect = require('connect');
|
var connect = require('connect');
|
||||||
|
var route = require('connect-route');
|
||||||
|
var connect_st = require('st');
|
||||||
|
var connect_rate_limit = require('connect-ratelimit');
|
||||||
|
|
||||||
var DocumentHandler = require('./lib/document_handler');
|
var DocumentHandler = require('./lib/document_handler');
|
||||||
|
|
||||||
|
@ -99,22 +102,28 @@ var documentHandler = new DocumentHandler({
|
||||||
keyGenerator: keyGenerator
|
keyGenerator: keyGenerator
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the server up with a static cache
|
var app = connect();
|
||||||
connect.createServer(
|
|
||||||
// First look for api calls
|
// Rate limit all requests
|
||||||
connect.router(function(app) {
|
if (config.rateLimits) {
|
||||||
|
config.rateLimits.end = true;
|
||||||
|
app.use(connect_rate_limit(config.rateLimits));
|
||||||
|
}
|
||||||
|
|
||||||
|
// first look at API calls
|
||||||
|
app.use(route(function(router) {
|
||||||
// get raw documents - support getting with extension
|
// get raw documents - support getting with extension
|
||||||
app.get('/raw/:id', function(request, response, next) {
|
router.get('/raw/:id', function(request, response, next) {
|
||||||
var skipExpire = !!config.documents[request.params.id];
|
var skipExpire = !!config.documents[request.params.id];
|
||||||
var key = request.params.id.split('.')[0];
|
var key = request.params.id.split('.')[0];
|
||||||
return documentHandler.handleRawGet(key, response, skipExpire);
|
return documentHandler.handleRawGet(key, response, skipExpire);
|
||||||
});
|
});
|
||||||
// add documents
|
// add documents
|
||||||
app.post('/documents', function(request, response, next) {
|
router.post('/documents', function(request, response, next) {
|
||||||
return documentHandler.handlePost(request, response);
|
return documentHandler.handlePost(request, response);
|
||||||
});
|
});
|
||||||
// get documents
|
// get documents
|
||||||
app.get('/documents/:id', function(request, response, next) {
|
router.get('/documents/:id', function(request, response, next) {
|
||||||
var skipExpire = !!config.documents[request.params.id];
|
var skipExpire = !!config.documents[request.params.id];
|
||||||
return documentHandler.handleGet(
|
return documentHandler.handleGet(
|
||||||
request.params.id,
|
request.params.id,
|
||||||
|
@ -122,19 +131,32 @@ connect.createServer(
|
||||||
skipExpire
|
skipExpire
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}),
|
}));
|
||||||
// Otherwise, static
|
|
||||||
connect.staticCache(),
|
// Otherwise, try to match static files
|
||||||
connect.static(__dirname + '/static', { maxAge: config.staticMaxAge }),
|
app.use(connect_st({
|
||||||
|
path: __dirname + '/static',
|
||||||
|
content: { maxAge: config.staticMaxAge },
|
||||||
|
passthrough: true,
|
||||||
|
index: false
|
||||||
|
}));
|
||||||
|
|
||||||
// Then we can loop back - and everything else should be a token,
|
// Then we can loop back - and everything else should be a token,
|
||||||
// so route it back to /index.html
|
// so route it back to /
|
||||||
connect.router(function(app) {
|
app.use(route(function(router) {
|
||||||
app.get('/:id', function(request, response, next) {
|
router.get('/:id', function(request, response, next) {
|
||||||
request.url = request.originalUrl = '/index.html';
|
request.sturl = '/';
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}),
|
}));
|
||||||
connect.static(__dirname + '/static', { maxAge: config.staticMaxAge })
|
|
||||||
).listen(config.port, config.host);
|
// And match index
|
||||||
|
app.use(connect_st({
|
||||||
|
path: __dirname + '/static',
|
||||||
|
content: { maxAge: config.staticMaxAge },
|
||||||
|
index: 'index.html'
|
||||||
|
}));
|
||||||
|
|
||||||
|
http.createServer(app).listen(config.port, config.host);
|
||||||
|
|
||||||
winston.info('listening on ' + config.host + ':' + config.port);
|
winston.info('listening on ' + config.host + ':' + config.port);
|
||||||
|
|
Loading…
Reference in a new issue