Commit 6835eef4 authored by John Crepezzi's avatar John Crepezzi
Browse files

Merge pull request #109 from seejohnrun/rate_limiting

Added user-configurable rate limiting
parents 4626fd9c fbb6e63c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -46,6 +46,16 @@ STDOUT. Check the README there for more details and usages.
* `storage` - storage options (see below)
* `logging` - logging preferences
* `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

+9 −0
Original line number Diff line number Diff line
@@ -23,6 +23,15 @@
    "type": "phonetic"
  },

  "rateLimits": {
    "categories": {
      "normal": {
        "totalRequests": 500,
        "every": 60000
      }
    }
  },

  "storage": {
    "type": "redis",
    "host": "0.0.0.0",
+4 −1
Original line number Diff line number Diff line
@@ -14,8 +14,11 @@
  },
  "main": "haste",
  "dependencies": {
    "connect-ratelimit": "0.0.7",
    "connect-route": "0.1.5",
    "connect": "3.4.1",
    "st": "1.1.0",
    "winston": "0.6.2",
    "connect": "1.9.2",
    "redis-url": "0.1.0",
    "redis": "0.8.1",
    "uglify-js": "1.3.3",
+59 −37
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@ var fs = require('fs');

var winston = require('winston');
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');

@@ -99,22 +102,28 @@ var documentHandler = new DocumentHandler({
  keyGenerator: keyGenerator
});

// Set the server up with a static cache
connect.createServer(
  // First look for api calls
  connect.router(function(app) {
var app = connect();

// Rate limit all requests
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
    app.get('/raw/:id', function(request, response, next) {
  router.get('/raw/:id', function(request, response, next) {
    var skipExpire = !!config.documents[request.params.id];
    var key = request.params.id.split('.')[0];
    return documentHandler.handleRawGet(key, response, skipExpire);
  });
  // add documents
    app.post('/documents', function(request, response, next) {
  router.post('/documents', function(request, response, next) {
    return documentHandler.handlePost(request, response);
  });
  // 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];
    return documentHandler.handleGet(
      request.params.id,
@@ -122,19 +131,32 @@ connect.createServer(
      skipExpire
    );
  });
  }),
  // Otherwise, static
  connect.staticCache(),
  connect.static(__dirname + '/static', { maxAge: config.staticMaxAge }),
}));

// Otherwise, try to match static files
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,
  // so route it back to /index.html
  connect.router(function(app) {
    app.get('/:id', function(request, response, next) {
      request.url = request.originalUrl = '/index.html';
// so route it back to /
app.use(route(function(router) {
  router.get('/:id', function(request, response, next) {
    request.sturl = '/';
    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);