Программно обнаруживать и улавливать бесконечные петли перенаправления в Rails
В настоящее время я пытаюсь определить причину неприятной ошибки перенаправления в приложении Rails. Специфика документирована здесь, хотя я не ищу здесь конкретного решения в StackOverflow. Скорее, пока я работаю над исправлением этого, я хотел бы разработать общий способ для поиска, регистрации и исследования бесконечных циклов перенаправления в приложении Rails.
У меня есть идея здесь, но мне все равно хотелось бы посмотреть, есть ли какие-либо проверенные методы.
Моя идея:
Переопределить Rails 'redirect_to
в "log" перенаправления в сеансе:
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
Затем сделайте некоторый анализ массива перенаправления, чтобы определить, существует ли бесконечный цикл:
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
Ответы
Ответ 1
Я согласен с тем, что тесты должны теоретически препятствовать запуску в бесконечные циклы перенаправления. Но я понимаю, что тесты не являются ответом на ваш вопрос.
Я думаю, вы можете рассматривать бесконечный цикл переадресации, как только у вас есть две переадресации в строке с теми же аргументами. Я думаю, что нет веских оснований ждать новых переадресаций.
Моя идея - сохранить аргументы перенаправления в flash
. Если аргументы в flash
все те же, когда происходит следующее перенаправление, чем вы находитесь в цикле. Если произошла переадресация в другое место или была отображена обычная страница между ними, то это местоположение не будет совпадать или flash
будет пустым:
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
Ответ 2
Проверенная и правильная техника заключается в написании тестов, чтобы убедиться, что ваше приложение работает так, как вы ожидаете. Эта конкретная проблема будет легко обнаружена с помощью теста с ошибкой контроллера и/или с ошибкой интеграции.
Нет ничего плохого в добавлении кода, который вы получили выше, чтобы помочь вам отладить эту конкретную ситуацию (если это произойдет), но реальное решение здесь для производственного приложения - это провести тесты, чтобы вы не получали эти петли перенаправления.