Domanda Rileva e cattura i loop infiniti di reindirizzamento in Rails


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

12
2018-03-19 23:43


origine


risposte:


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

7
2018-03-25 06:40



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 .


3
2018-03-20 00:56