UNPKG

@thi.ng/server

Version:

Minimal HTTP server with declarative routing, static file serving and freely extensible via pre/post interceptors

33 lines (32 loc) 843 B
import { isNumber } from "@thi.ng/checks"; import { LeakyBucketMap } from "@thi.ng/leaky-bucket"; const rateLimiter = (opts) => new RateLimiter(opts); class RateLimiter { buckets; capacity; clientID; constructor({ id, maxBuckets, bucketCapacity, leakInterval }) { this.clientID = id ?? ((ctx) => ctx.req.socket.remoteAddress); this.capacity = isNumber(bucketCapacity) ? () => bucketCapacity : bucketCapacity; this.buckets = new LeakyBucketMap({ leakInterval, maxBuckets }); } pre(ctx) { const id = this.clientID(ctx); if (!id) return true; const cap = !this.buckets.has(id) ? this.capacity(ctx, id) : void 0; if (!this.buckets.update(id, cap)) { ctx.res.rateLimit({}, `Try again later.`); return false; } return true; } } export { RateLimiter, rateLimiter };