Attualmente sto cercando di determinare la causa di un bug di reindirizzamento in un'app Rails. Le specifiche sono documentate Qui, anche se non sto cercando una soluzione specifica qui su StackOverflow. Piuttosto, mentre sto lavorando per risolvere questo problema, mi piacerebbe sviluppare un modo generico per catturare, registrare e indagare su infiniti loop di reindirizzamento in un'app Rails.
Ho un'idea qui, ma mi piacerebbe ancora vedere se ci sono tecniche provate e vere.
La mia idea:
Override Rails ' redirect_to
per "reindirizzare" i reindirizzamenti nella sessione:
def redirect_to(destination)
session[:redirects] << {destination: destination, timestamp: Time.now}
if is_inifinite_redirect?(session[:redirects])
render "a_redirect_error_page"
else
super
end
end
Quindi, disporre di una sorta di analisi dell'array di reindirizzamenti per determinare se esiste un ciclo infinito:
def is_inifinite_redirect?(redirects)
recent = redirects.last(21) # 21 is the max redirects allowed by Chrome
return recent.odds.map(&:destination).uniq.length == 1 && \
recent.evens.map(&:destination).uniq.length == 1 && \
(recent.last.timestamp - recent.first.timestamp < 10.seconds)
end
Sono d'accordo che i test dovrebbero in teoria ti impedisce di imbatterti in infiniti circuiti di reindirizzamento. Ma capisco che i test non sono la risposta alla tua domanda.
Penso che puoi considerare un ciclo di reindirizzamento infinito non appena hai due reindirizzamenti in una riga con gli stessi argomenti. Penso che non ci siano buone ragioni per aspettare ulteriori reindirizzamenti.
La mia idea è di archiviare gli argomenti del reindirizzamento in flash
. Se gli argomenti nel flash
sono sempre gli stessi quando avviene il prossimo reindirizzamento, quindi sei in un ciclo. Se ci fosse un reindirizzamento in un'altra posizione o una pagina normale venisse visualizzata tra quella posizione non corrisponderebbe o la flash
sarebbe vuoto:
def redirect_to(*args)
if flash[:redirected_with_args] == args
raise "Infinited redirect loop detected: #{args.inspect}"
else
flash[:redirected_with_args] = args
super
end
end
La tecnica collaudata è quella di scrivere test per garantire che la tua app funzioni nel modo in cui ti aspetti. Questo particolare problema potrebbe essere facilmente rilevato da un test del controller guasto e / o da un test di integrazione non riuscito.
Non c'è niente di sbagliato nell'aggiungere il codice che hai sopra per aiutarti a eseguire il debug di questa particolare situazione (se lo fa), ma la vera soluzione qui per un'app di produzione è di avere dei test in modo da non avere questi loop di reindirizzamento .