2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-06 10:50:21 +08:00

FEATURE: optional default off global per ip rate limiter

This commit is contained in:
Sam 2017-12-11 17:21:00 +11:00
parent 3c230d8f97
commit 4986ebcf24
4 changed files with 132 additions and 1 deletions

View file

@ -126,6 +126,13 @@ class Middleware::RequestTracker
end
def call(env)
result = nil
if rate_limit(env)
result = [429, {}, ["Slow down, too Many Requests from this IP Address"]]
return result
end
env["discourse.request_tracker"] = self
MethodProfiler.start if @@detailed_request_loggers
result = @app.call(env)
@ -135,6 +142,46 @@ class Middleware::RequestTracker
log_request_info(env, result, info) unless env["discourse.request_tracker.skip"]
end
def rate_limit(env)
if (
GlobalSetting.max_requests_per_ip_mode == "block" ||
GlobalSetting.max_requests_per_ip_mode == "warn"
)
ip = Rack::Request.new(env).ip
limiter10 = RateLimiter.new(
nil,
"global_ip_limit_10_#{ip}",
GlobalSetting.max_requests_per_ip_per_10_seconds,
10,
global: true
)
limiter60 = RateLimiter.new(
nil,
"global_ip_limit_60_#{ip}",
GlobalSetting.max_requests_per_ip_per_10_seconds,
10,
global: true
)
type = 10
begin
limiter10.performed!
type = 60
limiter60.performed!
rescue RateLimiter::LimitExceeded
if GlobalSetting.max_requests_per_ip_mode == "warn"
Rails.logger.warn("Global IP rate limit exceeded for #{ip} type: #{type}")
false
else
true
end
end
end
end
def log_later(data, host)
Scheduler::Defer.later("Track view", _db = nil) do
self.class.log_request_on_site(data, host)