mirror of
https://github.com/discourse/discourse.git
synced 2025-03-21 17:45:34 +08:00
FEATURE: set 'Retry-After' header for 429 responses (#5659)
This commit is contained in:
parent
9b651adadb
commit
f7bd05e534
@ -107,7 +107,15 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
|
||||
def render_rate_limit_error(e)
|
||||
render_json_error e.description, type: :rate_limit, status: 429, extras: { wait_seconds: e&.available_in }
|
||||
retry_time_in_seconds = e&.available_in
|
||||
|
||||
render_json_error(
|
||||
e.description,
|
||||
type: :rate_limit,
|
||||
status: 429,
|
||||
extras: { wait_seconds: retry_time_in_seconds },
|
||||
headers: { 'Retry-After': retry_time_in_seconds },
|
||||
)
|
||||
end
|
||||
|
||||
# If they hit the rate limiter
|
||||
@ -523,12 +531,15 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
# Render action for a JSON error.
|
||||
#
|
||||
# obj - a translated string, an ActiveRecord model, or an array of translated strings
|
||||
# obj - a translated string, an ActiveRecord model, or an array of translated strings
|
||||
# opts:
|
||||
# type - a machine-readable description of the error
|
||||
# status - HTTP status code to return
|
||||
# type - a machine-readable description of the error
|
||||
# status - HTTP status code to return
|
||||
# headers - extra headers for the response
|
||||
def render_json_error(obj, opts = {})
|
||||
opts = { status: opts } if opts.is_a?(Integer)
|
||||
opts.fetch(:headers, {}).each { |name, value| headers[name.to_s] = value }
|
||||
|
||||
render json: MultiJson.dump(create_errors_json(obj, opts)), status: opts[:status] || 422
|
||||
end
|
||||
|
||||
|
@ -70,7 +70,7 @@ MessageBus.on_middleware_error do |env, e|
|
||||
if Discourse::InvalidAccess === e
|
||||
[403, {}, ["Invalid Access"]]
|
||||
elsif RateLimiter::LimitExceeded === e
|
||||
[429, {}, [e.description]]
|
||||
[429, { 'Retry-After' => e.available_in }, [e.description]]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -25,7 +25,7 @@ describe 'rate limiter integration' do
|
||||
}
|
||||
end
|
||||
|
||||
it 'can cleanly limit requests' do
|
||||
it 'can cleanly limit requests and sets a Retry-After header' do
|
||||
freeze_time
|
||||
#request.set_header("action_dispatch.show_exceptions", true)
|
||||
|
||||
@ -50,6 +50,7 @@ describe 'rate limiter integration' do
|
||||
|
||||
data = JSON.parse(response.body)
|
||||
|
||||
expect(response.headers['Retry-After']).to eq(60)
|
||||
expect(data["extras"]["wait_seconds"]).to eq(60)
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user