Class: Rack::ApiKeyLimit::Base
- Inherits:
-
Object
- Object
- Rack::ApiKeyLimit::Base
- Defined in:
- lib/rack_api_key_limit/base.rb
Direct Known Subclasses
Instance Method Summary collapse
- #allowed?(request, key) ⇒ Boolean
- #cache ⇒ Object
- #call(env) ⇒ Object
- #get_key(request, cache) ⇒ Object
- #has_param?(request) ⇒ Boolean
- #http_error(code, message = nil, headers = {}) ⇒ Object
- #http_status(code) ⇒ Object
-
#initialize(app, options) ⇒ Base
constructor
A new instance of Base.
- #limit_seconds ⇒ Object
- #not_rate_limited(env, request, key) ⇒ Object
- #options ⇒ Object
- #param(request) ⇒ Object
- #param_name ⇒ Object
- #rate_limit_exceeded(key) ⇒ Object
- #rate_limit_headers(key) ⇒ Object
- #remaining(key) ⇒ Object
- #request_count(key) ⇒ Object
- #request_limit ⇒ Object
Constructor Details
#initialize(app, options) ⇒ Base
Returns a new instance of Base.
4 5 6 7 |
# File 'lib/rack_api_key_limit/base.rb', line 4 def initialize(app, ) @app = app @options = end |
Instance Method Details
#allowed?(request, key) ⇒ Boolean
74 75 76 77 |
# File 'lib/rack_api_key_limit/base.rb', line 74 def allowed?(request, key) return true unless has_param?(request) # always allowed if no key present cache.increment(key, limit_seconds) and return true if remaining(key) > 0 end |
#cache ⇒ Object
13 14 15 |
# File 'lib/rack_api_key_limit/base.rb', line 13 def cache @options[:cache] end |
#call(env) ⇒ Object
17 18 19 20 21 |
# File 'lib/rack_api_key_limit/base.rb', line 17 def call(env) request = Rack::Request.new(env) key = get_key(request, cache) allowed?(request, key) ? not_rate_limited(env, request, key) : rate_limit_exceeded(key) end |
#get_key(request, cache) ⇒ Object
35 36 37 |
# File 'lib/rack_api_key_limit/base.rb', line 35 def get_key(request, cache) raise NotImplementedError.new("You must implement get_key.") end |
#has_param?(request) ⇒ Boolean
31 32 33 |
# File 'lib/rack_api_key_limit/base.rb', line 31 def has_param?(request) request.params.has_key?(param_name) end |
#http_error(code, message = nil, headers = {}) ⇒ Object
79 80 81 82 83 |
# File 'lib/rack_api_key_limit/base.rb', line 79 def http_error(code, = nil, headers = {}) [code, {'Content-Type' => 'text/plain; charset=utf-8'}.merge(headers), [http_status(code) + (.nil? ? "\n" : " (#{})\n")] ] end |
#http_status(code) ⇒ Object
85 86 87 |
# File 'lib/rack_api_key_limit/base.rb', line 85 def http_status(code) [code, Rack::Utils::HTTP_STATUS_CODES[code]].join(' ') end |
#limit_seconds ⇒ Object
49 50 51 |
# File 'lib/rack_api_key_limit/base.rb', line 49 def limit_seconds raise NotImplementedError.new("You must implement limit_seconds.") end |
#not_rate_limited(env, request, key) ⇒ Object
39 40 41 42 43 |
# File 'lib/rack_api_key_limit/base.rb', line 39 def not_rate_limited(env, request, key) status, headers, response = @app.call(env) headers = headers.merge(rate_limit_headers(key)) if has_param?(request) [status, headers, response] end |
#options ⇒ Object
9 10 11 |
# File 'lib/rack_api_key_limit/base.rb', line 9 def @options || {} end |
#param(request) ⇒ Object
27 28 29 |
# File 'lib/rack_api_key_limit/base.rb', line 27 def param(request) request.params[param_name] end |
#param_name ⇒ Object
23 24 25 |
# File 'lib/rack_api_key_limit/base.rb', line 23 def param_name [:param_name] || "api_key" end |
#rate_limit_exceeded(key) ⇒ Object
61 62 63 |
# File 'lib/rack_api_key_limit/base.rb', line 61 def rate_limit_exceeded(key) http_error([:status] || 429, [:message] || 'Rate Limit Exceeded', rate_limit_headers(key)) end |
#rate_limit_headers(key) ⇒ Object
53 54 55 56 57 58 59 |
# File 'lib/rack_api_key_limit/base.rb', line 53 def rate_limit_headers(key) headers = {} headers["X-RateLimit-Limit"] = request_limit.to_s headers["X-RateLimit-Remaining"] = remaining(key).to_s headers["X-RateLimit-Reset"] = retry_after.to_f.ceil.to_s if respond_to?(:retry_after) headers end |
#remaining(key) ⇒ Object
70 71 72 |
# File 'lib/rack_api_key_limit/base.rb', line 70 def remaining(key) request_limit - request_count(key) end |
#request_count(key) ⇒ Object
65 66 67 68 |
# File 'lib/rack_api_key_limit/base.rb', line 65 def request_count(key) request_count = cache.get(key) (request_count.to_i if request_count) || 0 end |
#request_limit ⇒ Object
45 46 47 |
# File 'lib/rack_api_key_limit/base.rb', line 45 def request_limit [:request_limit] || 150 end |