RateLimiter Class
Sliding window rate limiter for API protection and abuse prevention. Prevent brute force attacks and ensure fair resource usage.
RateLimiter(key, limit, window_seconds)
Creates a new rate limiter instance for the given key.
Parameters
key(String) - Rate limit key (e.g., "ip:192.168.1.1" or "user:123")limit(Int) - Maximum requests allowed in the windowwindow_seconds(Int) - Time window in seconds
Example
# Create a rate limiter for API access
let limiter = RateLimiter("api:user123", 100, 60)
limiter.allowed()
Checks if a request is allowed under the rate limit using sliding window algorithm.
Returns
Bool - true if allowed, false if rate limited
Example
# Limit API calls to 100 per minute per IP
let limiter = RateLimiter("ip:" + req["headers"]["X-Forwarded-For"], 100, 60)
if !limiter.allowed() {
return { "status": 429, "body": "Too Many Requests" }
}
limiter.throttle()
Returns the number of seconds until the next request is allowed.
Returns
Int - Seconds to wait (0 if allowed immediately)
limiter.status()
Gets detailed rate limit status with remaining requests and reset time.
Returns
Hash with keys:
allowed, remaining, reset_in, limit, window
let limiter = RateLimiter("api:" + api_key, 1000, 3600)
let status = limiter.status()
println("Remaining: " + str(status["remaining"]) + "/" + str(status["limit"]))
limiter.headers()
Generates rate limit headers for HTTP responses.
Returns
Hash with:
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
limiter.reset()
Resets the rate limit for this instance's key.
Returns
Bool - true on success
Static Methods
RateLimiter.reset_all()
Resets all rate limit counters.
RateLimiter.cleanup()
Cleans up expired rate limit entries.
Helper Functions
rate_limiter_from_ip(req, limit, window_seconds)
Creates a RateLimiter instance based on client IP address (extracts from X-Forwarded-For or Remote-Addr).
Complete Example
# API middleware with rate limiting
def rate_limit_middleware(req)
let ip = req["headers"]["X-Forwarded-For"] || req["headers"]["Remote-Addr"]
let limiter = RateLimiter("api:" + ip, 100, 60)
# Check rate limit (100 requests per minute)
if !limiter.allowed() {
let status = limiter.status()
let headers = limiter.headers()
return {
"continue": false,
"response": {
"status": 429,
"headers": headers,
"body": json_stringify({
"error": "Rate limit exceeded",
"retry_after": status["reset_in"]
})
}
}
}
{ "continue": true, "request": req }
end