Browse files

Added support for outputting the Retry-After header.

  • Loading branch information...
1 parent 06e71d1 commit c428f7af065f0ece2da0185d680fa5602f0d09d3 @bendiken bendiken committed Mar 21, 2010
Showing with 18 additions and 10 deletions.
  1. +10 −1 lib/rack/throttle/interval.rb
  2. +8 −9 lib/rack/throttle/limiter.rb
View
11 lib/rack/throttle/interval.rb
@@ -29,7 +29,7 @@ def initialize(app, options = {})
def allowed?(request)
t1 = request_start_time(request)
t0 = cache_get(key = cache_key(request)) rescue nil
- allowed = !t0 || (t1 - t0.to_f) >= minimum_interval
+ allowed = !t0 || (dt = t1 - t0.to_f) >= minimum_interval
begin
cache_set(key, t1)
allowed
@@ -43,6 +43,15 @@ def allowed?(request)
end
##
+ # Returns the number of seconds before the client is allowed to retry an
+ # HTTP request.
+ #
+ # @return [Float]
+ def retry_after
+ minimum_interval
+ end
+
+ ##
# Returns the required minimal interval (in terms of seconds) that must
# elapse between two subsequent HTTP requests.
#
View
17 lib/rack/throttle/limiter.rb
@@ -173,22 +173,21 @@ def request_start_time(request)
##
# Outputs a `Rate Limit Exceeded` error.
#
- # @param [Integer] code
- # @param [String] message
# @return [Array(Integer, Hash, #each)]
- def rate_limit_exceeded(code = nil, message = nil)
- http_error(code || options[:code] || 403,
- message || options[:message] || 'Rate Limit Exceeded')
+ def rate_limit_exceeded
+ headers = respond_to?(:retry_after) ? {'Retry-After' => retry_after.to_f.ceil.to_s} : {}
+ http_error(options[:code] || 403, options[:message] || 'Rate Limit Exceeded', headers)
end
##
# Outputs an HTTP `4xx` or `5xx` response.
#
- # @param [Integer] code
- # @param [String, #to_s] message
+ # @param [Integer] code
+ # @param [String, #to_s] message
+ # @param [Hash{String => String}] headers
# @return [Array(Integer, Hash, #each)]
- def http_error(code, message = nil)
- [code, {'Content-Type' => 'text/plain; charset=utf-8'},
+ def http_error(code, message = nil, headers = {})
+ [code, {'Content-Type' => 'text/plain; charset=utf-8'}.merge(headers),
http_status(code) + (message.nil? ? "\n" : " (#{message})\n")]
end

0 comments on commit c428f7a

Please sign in to comment.