class GrapeThrottler::Middleware::ThrottleMiddleware
Constants
- COUNTER_START
Public Instance Methods
before()
click to toggle source
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength rubocop:disable Metrics/PerceivedComplexity, Lint/AssignmentInCondition
# File lib/grape-throttler/middleware/throttle_middleware.rb, line 11 def before endpoint = env['api.endpoint'] logger = options[:logger] || Logger.new($stdout) return unless throttle_options = endpoint.route_setting(:throttle) limit, period = find_limit_and_period(throttle_options) check_limit_and_period(limit, period) limit = limit.call(env) if limit.is_a?(Proc) return true if limit.negative? user_value = find_user_value(options) || "ip:#{env['REMOTE_ADDR']}" rate_key = generate_rate_key(endpoint, user_value) begin redis = options[:cache] redis.ping current = redis.get(rate_key).to_i if !current.nil? && current >= limit endpoint.error!('Too Many Requests', 429) else redis.multi do redis.set(rate_key, COUNTER_START, nx: true, ex: period.to_i) redis.incr(rate_key) end end rescue StandardError => e logger.warn(e.message) end end
Private Instance Methods
check_limit_and_period(limit, period)
click to toggle source
rubocop:enable Metrics/PerceivedComplexity, Lint/AssignmentInCondition rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
# File lib/grape-throttler/middleware/throttle_middleware.rb, line 50 def check_limit_and_period(limit, period) return unless limit.nil? || period.nil? raise ArgumentError, 'Please set a period and limit (see documentation)' end
find_limit_and_period(throttle_options)
click to toggle source
rubocop:disable Lint/AssignmentInCondition
# File lib/grape-throttler/middleware/throttle_middleware.rb, line 57 def find_limit_and_period(throttle_options) if limit = throttle_options[:hourly] period = 3_600 elsif limit = throttle_options[:daily] period = 86_400 elsif limit = throttle_options[:monthly] period = 2_629_746 elsif period = throttle_options[:period] limit = throttle_options[:limit] end [limit, period] end
find_user_value(options)
click to toggle source
rubocop:enable Lint/AssignmentInCondition
# File lib/grape-throttler/middleware/throttle_middleware.rb, line 72 def find_user_value(options) user_key = options[:user_key] return if user_key.nil? user_key.call(env) end
generate_rate_key(endpoint, user_value)
click to toggle source
# File lib/grape-throttler/middleware/throttle_middleware.rb, line 79 def generate_rate_key(endpoint, user_value) endpoint_route = endpoint.routes.first "#{endpoint_route.request_method}:#{endpoint_route.path}:#{user_value}" end