diff options
| author | Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> | 2024-06-13 10:56:26 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-13 10:56:26 +0900 |
| commit | dc3629e732e5aefd792452f0b43a7bb7fdaf103e (patch) | |
| tree | c10692a00f80c034498d76967d480be9f9104f95 /packages/backend/src/server/api/RateLimiterService.ts | |
| parent | node 22 support (diff) | |
| download | sharkey-dc3629e732e5aefd792452f0b43a7bb7fdaf103e.tar.gz sharkey-dc3629e732e5aefd792452f0b43a7bb7fdaf103e.tar.bz2 sharkey-dc3629e732e5aefd792452f0b43a7bb7fdaf103e.zip | |
feat(backend): report `Retry-After` if client hit rate limit (#13949)
* feat(backend): report `Retry-After` if client hit rate limit
* refactor(backend): fix lint error
Diffstat (limited to 'packages/backend/src/server/api/RateLimiterService.ts')
| -rw-r--r-- | packages/backend/src/server/api/RateLimiterService.ts | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/packages/backend/src/server/api/RateLimiterService.ts b/packages/backend/src/server/api/RateLimiterService.ts index 0439cdfe5e..cae106c273 100644 --- a/packages/backend/src/server/api/RateLimiterService.ts +++ b/packages/backend/src/server/api/RateLimiterService.ts @@ -32,11 +32,13 @@ export class RateLimiterService { @bindThis public limit(limitation: IEndpointMeta['limit'] & { key: NonNullable<string> }, actor: string, factor = 1) { - return new Promise<void>((ok, reject) => { - if (this.disabled) ok(); + { + if (this.disabled) { + return Promise.resolve(); + } // Short-term limit - const min = (): void => { + const min = new Promise<void>((ok, reject) => { const minIntervalLimiter = new Limiter({ id: `${actor}:${limitation.key}:min`, duration: limitation.minInterval! * factor, @@ -46,25 +48,25 @@ export class RateLimiterService { minIntervalLimiter.get((err, info) => { if (err) { - return reject('ERR'); + return reject({ code: 'ERR', info }); } this.logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`); if (info.remaining === 0) { - reject('BRIEF_REQUEST_INTERVAL'); + return reject({ code: 'BRIEF_REQUEST_INTERVAL', info }); } else { if (hasLongTermLimit) { - max(); + return max; } else { - ok(); + return ok(); } } }); - }; + }); // Long term limit - const max = (): void => { + const max = new Promise<void>((ok, reject) => { const limiter = new Limiter({ id: `${actor}:${limitation.key}`, duration: limitation.duration! * factor, @@ -74,18 +76,18 @@ export class RateLimiterService { limiter.get((err, info) => { if (err) { - return reject('ERR'); + return reject({ code: 'ERR', info }); } this.logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`); if (info.remaining === 0) { - reject('RATE_LIMIT_EXCEEDED'); + return reject({ code: 'RATE_LIMIT_EXCEEDED', info }); } else { - ok(); + return ok(); } }); - }; + }); const hasShortTermLimit = typeof limitation.minInterval === 'number'; @@ -94,12 +96,12 @@ export class RateLimiterService { typeof limitation.max === 'number'; if (hasShortTermLimit) { - min(); + return min; } else if (hasLongTermLimit) { - max(); + return max; } else { - ok(); + return Promise.resolve(); } - }); + } } } |