handle method
Inspect or reject the request. Throw to abort the chain.
The default implementation does nothing, so a middleware that only overrides process does not need to define it.
Implementation
@override
Future<void> handle(Request req) async {
// Fails closed: an unset APP_ENV is treated as production, so an app
// that never sets it still gets rate limiting.
if (bypassInDevelopment &&
_developmentEnvironments.contains(
env<String>('APP_ENV', 'production'),
)) {
return;
}
final String identifier = await _getRequestIdentifier(req);
final allowed = _throttle.request(identifier);
// Counted after this request, so the last one allowed says 0 left.
_addRateLimitHeaders(
req.response,
_throttle.remainingAttempts(identifier),
_throttle.resetAt(identifier),
);
if (!allowed) {
final retryAfter = _throttle.retryAfter(identifier);
throw ThrottleException(
message: customMessage ?? 'Too Many Requests. Please try again later.',
code: HttpStatus.tooManyRequests,
headers: {'Retry-After': retryAfter.inSeconds.toString(), ...?headers},
);
}
}