Grails重定向 - 为什么它总是绝对的?

Han*_*ank 4 https grails redirect reverse-proxy

我有两个Jetty AppServers在Apache 2.2反向代理后运行Grails Web App.SSL终止由apach完成,后者将HTTP传递给Jetty AppServers.

当Grails Web应用程序执行重定向时

redirect(action:'index')
Run Code Online (Sandbox Code Playgroud)

最终用户收到带有完整URL的HTTP 302重定向请求,该URL使用http://协议,而不是https://:

HTTP/1.1 302 Found
Date: Tue, 08 Mar 2011 17:50:46 GMT
Server: Jetty(6.1.17)
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://hostname.domain/web/?lang=en
Run Code Online (Sandbox Code Playgroud)

这很烦人,因为所有HTTP请求都被代理捕获并重定向到HTTPS请求.所以这是一次不必要的往返.

我看到两个解决方案:

  1. Apache的mod_proxy可以在将响应传递给用户之前将该Location-header重写为https://.(它可以?)
  2. 重定向时,Grails可能根本不使用绝对URL: Location: /web/?lang=en

我认为第一个选择有点愚蠢吧?

你知道如何让grails发送非绝对重定向头(理想情况下无需切换每个重定向uri:)吗?

编辑:目前我通过修改响应标头(a2enmod headers然后添加)Header edit Location ^http://(.*)$ https://$1在第一种方法之后有一个解决方法<Location>.灵感来自这个serverfault帖子.我仍然想知道为什么这首先是必要的.

Ted*_*eid 6

HTTP 1.1 RFC要求302重定向是绝对的,而不是相对位置.即使它在某些浏览器中有效,但这些都超出了规范,我确信如果你做了一个相对的网址,某些实现将无法正常工作.

你看到这个问题的原因是因为apache正在发生SSL终止,而apache正在向Jetty发出一个vanilla HTTP请求.所以Jetty正在获得一个非常的非HTTPS请求,所以它不知道发送HTTPS响应,而不是常规的HTTP响应.如果您在Jetty中进行SSL终止,则不会出现问题(但Jetty在SSL终止时不是很好).

我们已经在我们的应用程序(apache/HA Proxy-> Tomcat)中处理了这个问题,因为它具有硬编码响应协议的每个环境配置值(无论如何我们都需要弄乱网址,因为它是一个具有许多潜在主机名的多租户系统进来,长篇故事...... :),但你的apache解决方案也有效.