2016-03-04 56 views
0

我在Openshift Onlinehttp://rsdbtest-abex.rhcloud.com/有一个应用程序。它有别名和匹配CNAME S为以下领域:Openshift 302 mangling

http://rsdb-test.tk/http://www.rsdb-test.tk/http://sub.rsdb-test.tk/http://sub.sub.rsdb-test.tk/

服务器设置到/明确的请求对象作出回应。任何其他路径生成一个302,其中Location头设置为路径,因此理论上请求http://rsdb-test.tk/http://sub.rsdb-test.tk将带您到http://sub.rsdb-test.tk。这适用于本地,但是退出OpenShift路由器后的位置是http://rsdb-test.tk。该域被替换为请求的域。如果您在本地运行服务器或从设备内部卷曲,则Location标头仍然正确,表明我的代码不是问题。

有没有办法解决此问题并重定向到任何域,还是必须使用<meta>来重定向?

服务器侦听是一个简单的Express服务器:

var express = require("express"); 
var util=require("util"); 

var e = process.env; 
var config = { 
    IP:e.OPENSHIFT_NODEJS_IP||"", 
    Port:e.OPENSHIFT_NODEJS_PORT||80, 
    TrustProxy:true, 
} 

var app = express(); 
app.set("trust proxy",config.TrustProxy) 


app.use(function(req,res,next){ 
    var path=req.path.substr(1); 
    if(path){ 
     res.redirect(302,path); 
    }else{ 
     res.send(util.inspect(req)); 
    } 
}); 

app.listen(config.Port,config.IP,function(){ 
    console.log("Started"); 
}); 
+0

我刚刚在Firefox中尝试http://rsdb-test.tk/hubp://sub.rsdb-test.tk,它的工作原理与您所描述的一样。 – 2016-03-04 13:37:42

+0

它似乎是间歇性的。在写入'http://rsdb-test.tk/http://sub.rsdb-test.tk/http:// sub.sub.rsdb-test.tk /'时不正确地重定向,再次丢弃子域。 – Abex

+0

所以看起来,如果'Location'头以'/'结尾,那么位置就会变形,否则就没有问题。 – Abex

回答

0

这直接关系到ProxyPassReverse如何工作的Apache。

在OpenShift每个应用程序都与至少两个ProxyPassReverse指令定义 - 一个用于内部IP地址,以及一个用于应用程序FQDN:

ProxyPassReverse/http://127.12.219.1:8080/ 
ProxyPassReverse/http://rsdbtest-abex.rhcloud.com/ 

你的情况,你有几个,一个是每个别名已定义:

ProxyPassReverse/http://rsdb-test.tk/ 
ProxyPassReverse/http://sub.rsdb-test.tk/ 
ProxyPassReverse/http://sub.sub.rsdb-test.tk/ 
ProxyPassReverse/http://www.rsdb-test.tk/ 

时间不限你的应用程序返回一个重定向到这些主机之一,Apache的重写的主机部分来在原始请求中使用的宿主报头相匹配。所以,让我们借这个例子:

http://rsdb-test.tk/http://sub.rsdb-test.tk/http://sub.sub.rsdb-test.tk/ 

你先做出这样的请求:

GET /http://sub.rsdb-test.tk/http://sub.sub.rsdb-test.tk/ HTTP/1.1 
Host: rsdb-test.tk 

您的应用程序的回报:

http://sub.rsdb-test.tk/http://sub.sub.rsdb-test.tk/ 

但ProxyPassReverse配置重写这:

http://rsdb-test.tk/http://sub.sub.rsdb-test.tk/ 

接下来你跟踪该重定向:

GET /http://sub.sub.rsdb-test.tk/ HTTP/1.1 
Host: rsdb-test.tk 

您的应用程序返回:

http://sub.sub.rsdb-test.tk/ 

但同样,ProxyPassReverse重写这:

http://rsdb-test.tk/ 

当您删除结尾的斜线,什么情况是,第二重定向有一个空的“路径”元素,所以“ProxyPassReverse/...”规则不再匹配它,这是一个不幸的不一致。但是,即使它工作正常,我也不认为它完全符合你的期望,因为它向rsdb-test.tk发出了两个请求,然后是对sub.sub.rsdb-test的请求。tk(而你可能期望rsdb-test.tk,然后是sub.rsdb-test.tk,然后是sub.sub.rsdb-test.tk)。

通常,重定向似乎按预期工作,并且我们没有任何简单的方法可以从应用程序中删除ProxyPassReverse设置。让我知道这个解释是否合理。

+0

感谢您的详细解释,我怀疑它是ProxyPassReverse,但我找不到关于路由层如何工作的文档。现在我已经换成了元刷新,这适用于我的情况,但是如果不能选择元刷新,有一种方法可以绕过这一点,这将是很好的。 – Abex