handle method

  1. @override
Future<void> handle(
  1. Request req
)
override

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},
    );
  }
}