work on #2693 Separate API Limits by Writes/Reads
This commit is contained in:
@@ -41,7 +41,7 @@ protected
|
|||||||
|
|
||||||
def api_check
|
def api_check
|
||||||
if request.format.to_s =~ /\/json|\/xml/ || params[:controller] == "iqdb"
|
if request.format.to_s =~ /\/json|\/xml/ || params[:controller] == "iqdb"
|
||||||
if ApiLimiter.throttled?(request.remote_ip)
|
if ApiLimiter.throttled?(request.remote_ip, request.request_method)
|
||||||
render :text => "421 User Throttled\n", :layout => false, :status => 421
|
render :text => "421 User Throttled\n", :layout => false, :status => 421
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,15 +1,26 @@
|
|||||||
module ApiLimiter
|
module ApiLimiter
|
||||||
def throttled?(ip_addr)
|
def idempotent?(method)
|
||||||
key = "#{ip_addr}:#{Time.now.hour}"
|
case method
|
||||||
MEMCACHE.fetch(key, 1.hour, :raw => true) {0}
|
when "POST", "PUT", "DELETE"
|
||||||
MEMCACHE.incr(key).to_i > CurrentUser.user.api_hourly_limit
|
false
|
||||||
|
|
||||||
|
else
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def remaining_hourly_limit(ip_addr)
|
def throttled?(ip_addr, http_method = "GET")
|
||||||
key = "#{ip_addr}:#{Time.now.hour}"
|
idempotent = idempotent?(http_method)
|
||||||
|
key = "api/#{ip_addr}/#{Time.now.hour}/#{idempotent}"
|
||||||
|
MEMCACHE.fetch(key, 1.hour, :raw => true) {0}
|
||||||
|
MEMCACHE.incr(key).to_i > CurrentUser.user.api_hourly_limit(idempotent)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remaining_hourly_limit(ip_addr, idempotent = true)
|
||||||
|
key = "api/#{ip_addr}/#{Time.now.hour}/#{idempotent}"
|
||||||
requests = MEMCACHE.fetch(key, 1.hour, :raw => true) {0}.to_i
|
requests = MEMCACHE.fetch(key, 1.hour, :raw => true) {0}.to_i
|
||||||
CurrentUser.user.api_hourly_limit - requests
|
CurrentUser.user.api_hourly_limit - requests
|
||||||
end
|
end
|
||||||
|
|
||||||
module_function :throttled?, :remaining_hourly_limit
|
module_function :throttled?, :idempotent?, :remaining_hourly_limit
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -611,20 +611,34 @@ class User < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_hourly_limit
|
def api_hourly_limit(idempotent = true)
|
||||||
if is_platinum? && api_key.present?
|
base = if is_platinum? && api_key.present?
|
||||||
20_000
|
2000
|
||||||
elsif is_gold? && api_key.present?
|
elsif is_gold? && api_key.present?
|
||||||
10_000
|
1000
|
||||||
else
|
else
|
||||||
3_000
|
300
|
||||||
|
end
|
||||||
|
|
||||||
|
if idempotent
|
||||||
|
base * 10
|
||||||
|
else
|
||||||
|
base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def remaining_api_hourly_limit
|
def remaining_api_hourly_limit
|
||||||
ApiLimiter.remaining_hourly_limit(CurrentUser.ip_addr)
|
ApiLimiter.remaining_hourly_limit(CurrentUser.ip_addr, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remaining_api_hourly_limit_read
|
||||||
|
ApiLimiter.remaining_hourly_limit(CurrentUser.ip_addr, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remaining_api_hourly_limit_write
|
||||||
|
ApiLimiter.remaining_hourly_limit(CurrentUser.ip_addr, false)
|
||||||
|
end
|
||||||
|
|
||||||
def statement_timeout
|
def statement_timeout
|
||||||
if is_platinum?
|
if is_platinum?
|
||||||
9_000
|
9_000
|
||||||
@@ -644,7 +658,7 @@ class User < ActiveRecord::Base
|
|||||||
def method_attributes
|
def method_attributes
|
||||||
list = [:is_banned, :can_approve_posts, :can_upload_free, :is_super_voter, :level_string]
|
list = [:is_banned, :can_approve_posts, :can_upload_free, :is_super_voter, :level_string]
|
||||||
if id == CurrentUser.user.id
|
if id == CurrentUser.user.id
|
||||||
list += [:remaining_api_hourly_limit]
|
list += [:remaining_api_hourly_limit, :remaining_api_hourly_limit_read, :remaining_api_hourly_limit_write]
|
||||||
end
|
end
|
||||||
list
|
list
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user