Skip to content

Instantly share code, notes, and snippets.

@analytically
Created December 15, 2012 13:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save analytically/4295042 to your computer and use it in GitHub Desktop.
Save analytically/4295042 to your computer and use it in GitHub Desktop.
Migration of gist:4293859
def rateLimit(action: => String, subject: => String, maxRequests: => Int): Directive0 = {
mapInnerRoute {
inner => ctx =>
val key = action + ":" + subject
add(redis, key)
val actionCount = count(redis, key, interval)
if (actionCount >= maxRequests) {
logger.warn("Rate limiting user '" + subject + "': exceeded max number of requests (" + maxRequests + ").")
ctx.reject(AuthorizationFailedRejection)
}
else inner(ctx.mapHttpResponseHeaders(
headers =>
// Number of requests allowed for that IP address per interval
RawHeader("X-FeatureRateLimit-Limit", maxRequests.toString) ::
// Number of seconds in the rate limit interval
RawHeader("X-FeatureRateLimit-IntervalSecs", interval.toString) ::
// Number of requests remaining.
RawHeader("X-FeatureRateLimit-Remaining", "" + (maxRequests - actionCount)) ::
// Time at which your quota is reset, in Unix epoch time
RawHeader("X-FeatureRateLimit-Reset", "" + (System.currentTimeMillis() + (redis.withClient(client => client.ttl(key).getOrElse(0l) * 1000)))) ::
headers
))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment