diff --git a/README.md b/README.md index f3718b46..317d8313 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and routes. ## ThrottleGuard Global guard. Check if metadata exists for guard. If not, check if route is in -`ignoreRoutes`. If so, return `true`. If not, apply defaults from package +`excludeRoutes`. If so, return `true`. If not, apply defaults from package (configured via module). If metadata does exist, use metadata instead of defaults (easy overriding) Pull throttlerStorage from `ThrottlerStorage` class via `getRecord()` method. Will return a number, if number is gte max, return diff --git a/src/throttler.guard.ts b/src/throttler.guard.ts index 5b9e8966..909d89fa 100644 --- a/src/throttler.guard.ts +++ b/src/throttler.guard.ts @@ -18,7 +18,7 @@ export class ThrottlerGuard implements CanActivate { private readonly storageService: ThrottlerStorageService, ) {} - // TODO: Return true if current route is in ignoreRoutes. + // TODO: Return true if current route is in excludeRoutes. async canActivate(context: ExecutionContext): Promise { const handler = context.getHandler(); const headerPrefix = 'X-RateLimit'; @@ -30,21 +30,25 @@ export class ThrottlerGuard implements CanActivate { return true; } - // Return early if the current route is ignored. + // Return early if the current route should be excluded. const req = context.switchToHttp().getRequest(); - const routes = this.normalizeRoutes(this.options.ignoreRoutes); - for (const route of routes) { - const currentRoutePath = req.url.replace(/^\/+/, ''); - const currentRouteMethod = this.reflector.get('method', handler); + const routes = this.normalizeRoutes(this.options.excludeRoutes); + const originalUrl = req.originalUrl.replace(/^\/+/, ''); + const reqMethod = req.method; + const queryParamsIndex = originalUrl && originalUrl.indexOf('?'); + const pathname = queryParamsIndex >= 0 + ? originalUrl.slice(0, queryParamsIndex) + : originalUrl; - const ignored = ( - route.path === currentRoutePath && - [RequestMethod.ALL, currentRouteMethod].indexOf(route.method) !== -1 - ) || route.regex.exec(currentRoutePath); - - if (ignored) return true; - } + const isExcluded = routes.some(({ method, regex }) => { + if (RequestMethod.ALL === method || RequestMethod[method] === reqMethod) { + return regex.exec(pathname); + } + return false; + }); + if (isExcluded) return true; + // Here we start to check the amount of requests being done against the ttl. const res = context.switchToHttp().getResponse(); const key = md5(`${req.ip}-${context.getClass().name}-${handler.name}`) const record = this.storageService.getRecord(key); diff --git a/src/throttler.interface.ts b/src/throttler.interface.ts index e550ecd0..a09d8921 100644 --- a/src/throttler.interface.ts +++ b/src/throttler.interface.ts @@ -4,7 +4,7 @@ import { Type } from './type'; export interface ThrottlerOptions { - ignoreRoutes?: Array; + excludeRoutes?: Array; limit?: number; ttl?: number; storage?: Type diff --git a/test/app/app.controller.ts b/test/app/app.controller.ts index c62e6e30..841d517c 100644 --- a/test/app/app.controller.ts +++ b/test/app/app.controller.ts @@ -9,30 +9,30 @@ export class AppController { return 'test'; } - // Route that are defined in the `ignoreRoutes` property. + // Route that are defined in the `excludeRoutes` property. - // ignoreRoutes: ['ignored'] + // excludeRoutes: ['ignored'] @Get('ignored') @Throttle(2, 10) async ignored() { return 'ignored'; } - // ignoreRoutes: [{ path: 'ignored-2', method: RequestMethod.POST }] + // excludeRoutes: [{ path: 'ignored-2', method: RequestMethod.POST }] @Post('ignored-2') @Throttle(2, 10) async ignored2() { return 'ignored'; } - // ignoreRoutes: [{ path: 'ignored-3', method: RequestMethod.ALL }] + // excludeRoutes: [{ path: 'ignored-3', method: RequestMethod.ALL }] @All('ignored-3') @Throttle(2, 10) async ignored3() { return 'ignored'; } - // ignoreRoutes: [{ path: 'ignored/:foo', method: RequestMethod.GET }] + // excludeRoutes: [{ path: 'ignored/:foo', method: RequestMethod.GET }] @Get('ignored/:foo') @Throttle(2, 10) async ignored4() { diff --git a/test/app/app.module.ts b/test/app/app.module.ts index 2a3a9391..062277e5 100644 --- a/test/app/app.module.ts +++ b/test/app/app.module.ts @@ -5,7 +5,7 @@ import { AppService } from './app.service'; @Module({ imports: [ThrottlerModule.forRoot({ - ignoreRoutes: [ + excludeRoutes: [ 'ignored', { path: 'ignored-2', method: RequestMethod.POST }, { path: 'ignored-3', method: RequestMethod.ALL },