以编程方式检测并捕获Rails中的无限重定向循环

use*_*154 12 ruby redirect ruby-on-rails

我目前正在尝试确定Rails应用程序中令人讨厌的重定向错误的原因.这里详细说明,虽然我不是在StackOverflow上寻找特定的解决方案.相反,当我正在努力解决这个问题时,我想开发一种通用方法来捕获,记录和调查Rails应用程序中的无限重定向循环.

我在这里有一个想法,但我仍然想看看是否有任何经过验证的技术.

我的想法:

覆盖Rails' redirect_to以在会话中"记录"重定向:

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
Run Code Online (Sandbox Code Playgroud)

然后,对重定向数组进行某种分析,以确定是否存在无限循环:

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
Run Code Online (Sandbox Code Playgroud)

spi*_*ann 7

我同意测试理论上应该防止你遇到无限重定向循环.但我知道测试不是你问题的答案.

我认为只要在具有相同参数的行中有两个重定向,就可以考虑无限重定向循环.我认为没有充分的理由等待更多的重定向.

我的想法是将重定向的参数存储到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
Run Code Online (Sandbox Code Playgroud)


sma*_*thy 3

久经考验的真实技术是编写测试以确保您的应用程序按您期望的方式工作。这个特定问题可以通过失败的控制器测试和/或失败的集成测试轻松检测到。

添加上面的代码来帮助您调试这种特殊情况(如果确实如此)并没有什么问题,但是对于生产应用程序来说,真正的解决方案是进行测试,这样您就不会遇到这些重定向循环。