2012-03-12 13 views
5

Sto usando rack-throttle come un motore che limita la velocità nella mia applicazione rails 3. Ho creato una mia classe basata su Rack::Throttle::Interval per definire la logica di limitazione della velocità personalizzata. Sto verificando se la richiesta è fatta per il controller esatto e l'azione esatta. Funziona bene se faccio la richiesta GET. Comunque se invio la richiesta POST ottengo qualche problema.Throttling POST request in rails application

class CustomLimiter < Rack::Throttle::Interval 
    def allowed?(request) 
    path_info = Rails.application.routes.recognize_path request.url rescue path_info = {} 
    if path_info[:controller] == "some_controller" and path_info[:action] == "some_action" 
     super 
    else 
     true 
    end 
    end 
end 

Qui sono le mie azioni di controllo

def question 
    #user is redirected here 
end 

def check_answer 
    #some logic to check answer 
    redirect_to question_path 
end 

miei itinerari

get "questions" => "application#question", :as => "question" 
post "check_answer" => "application#check_answer", :as => "check_answer" 

EDIT:

Il problema è che POST le richieste stanno arrivando a applicazione in modo che il metodo allowed? viene chiamato . Ma quando chiamo Rails.application.routes.recognize_path ottengo un'eccezione Route set not finalized. Come posso impedire a un utente di inviare un sacco di richieste POST sull'azione esatto del controller esatto con l'aiuto di rack-throttle

Il middleware viene aggiunto in application.rb

class Application < Rails::Application 
    #Set up rate limiting 
    config.require "ip_limiter" 
    config.require "ip_user_agent_limiter" 
    config.middleware.use IpLimiter, :min => 0.2 
    config.middleware.use IpUserAgentLimiter, :min => 2 
end 

Sia IpLimiter e IpUserAgentLimiter sono derivati ​​da limitatore personalizzato

+0

Come avete inserire il rack :: :: Throttle intervallo nella vostra applicazione? – shingara

+0

@shingara è incluso in 'application.rb' – RomanKapitonov

+0

Il permesso? il metodo è chiamato nel metodo POST o no? Puoi pase la parte in cui aggiungi questo middleware nella tua applicazione? – shingara

risposta

2

Dopo aver letto il codice di Rails.application.routes.recognize_path (http://apidock.com/rails/ActionDispatch/Routing/RouteSet/recognize_path), questo metodo ottiene un secondo argomento in cui è possibile passare il METODO.

Prova con:

path_info = Rails.application.routes.recognize_path(request.url, {:method => request.request_method}) rescue path_info = {} 

Dopo tutto il metodo può funzionare suppongo.

+1

Mi viene ancora visualizzato il messaggio di errore 'RuntimeError: route set not finalized da /home/rkapitonov/.rvm/gems/ruby-1.9.2-p290/gems/rack-mount-0.8.3/lib/rack/mount/route_set .rb: 81: in 'recognition'' quando si sta cercando di fare quanto segue' Rails.application.routes.recognize_path (request.url, {: method => request.request_method}) ' – RomanKapitonov

0

Questo ha funzionato per me, per catturare tutte le richieste POST e ignorare tutte le richieste GET:

class CustomLimiter < Rack::Throttle::Interval 

    def allowed?(request) 
    return true unless request.request_method == "POST" 
    super request 
    end 

end