Skip to content

Instantly share code, notes, and snippets.

@whisher
Created November 7, 2015 20:10
Show Gist options
  • Save whisher/d6e3db7c11d632720133 to your computer and use it in GitHub Desktop.
Save whisher/d6e3db7c11d632720133 to your computer and use it in GitHub Desktop.
'use strict';
/**
* Module dependencies.
*/
const Hoek = require('hoek');
const Limiter = require('ratelimiter');
const RedisClient = require('../utils/redis');
const ReplyUtil = require('../utils/reply');
const internals = {};
internals.defaults = {
namespace: 'hrl',
global: {
limit: -1,
duration: 1
}
};
const MILLISECONDS = 1000;
exports.register = (server, options, next) => {
const settings = Hoek.applyToDefaults(internals.defaults, options);
server.ext('onPreAuth', (request, reply) => {
const route = request.route;
const currentSettings = route.settings.plugins && route.settings.plugins['hapi-rate-limit'];
if (currentSettings) {
const routeSettings = Hoek.applyToDefaults(settings.global, currentSettings);
const id = settings.namespace + ':' + request.info.remoteAddress + ':' + route.path;
const limiter = new Limiter({
id: id,
db: RedisClient,
max: routeSettings.limit,
duration: routeSettings.duration * MILLISECONDS
});
limiter.get((err, limit) => {
if (err) {
return reply(err);
}
request.plugins['hapi-rate-limit'] = {};
request.plugins['hapi-rate-limit'].limit = limit.total;
request.plugins['hapi-rate-limit'].remaining = limit.remaining - 1;
request.plugins['hapi-rate-limit'].reset = limit.reset;
if (limit.remaining <= 0) {
const error = ReplyUtil.tooManyRequests();
error.output.headers['X-RateLimit-Limit'] = request.plugins['hapi-rate-limit'].limit;
error.output.headers['X-RateLimit-Remaining'] = request.plugins['hapi-rate-limit'].remaining;
error.output.headers['X-RateLimit-Reset'] = request.plugins['hapi-rate-limit'].reset;
return reply(error);
}
return reply.continue();
});
} else {
return reply.continue();
}
});
return next();
};
exports.register.attributes = {
name: 'hapi-rate-limit',
version: '1.0.0'
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment