Openshift 302 修改
Openshift 302 mangling
我在 Openshift Online http://rsdbtest-abex.rhcloud.com/
上有一个申请。它具有以下域的别名和匹配 CNAME
:
http://rsdb-test.tk/
,http://www.rsdb-test.tk/
,http://sub.rsdb-test.tk/
,http://sub.sub.rsdb-test.tk/
服务器设置为响应 /
express 的请求 object。任何其他路径都会生成 302,并将 Location
header 设置为该路径,因此理论上 http://rsdb-test.tk/http://sub.rsdb-test.tk
的请求会将您带到 http://sub.rsdb-test.tk
。这在本地有效,但是退出 OpenShift 路由器后的位置是 http://rsdb-test.tk
。该域将替换为请求的域。如果您 运行 本地服务器或从齿轮内部卷曲 Location
header 仍然正确,说明我的代码没有问题。
有没有办法解决此问题并重定向到任何域,或者我是否必须使用 <meta>
进行重定向?
侦听的服务器是一个简单的快速服务器:
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");
});
这与 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/
任何时候您的应用程序 returns 重定向到这些主机之一,Apache 都会重写主机部分以匹配原始请求中使用的主机 header。那么,让我们举个例子:
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
您的应用程序 returns:
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
您的申请returns:
http://sub.sub.rsdb-test.tk/
但 ProxyPassReverse 再次将其重写为:
http://rsdb-test.tk/
当您删除结尾的斜杠时,第二个重定向有一个空的 "path" 元素,因此 "ProxyPassReverse / ..." 规则不再匹配它,这是一个不幸的不一致。不过,即使它确实有效,我也不认为它完全按照您的预期进行,因为它向 rsdb-test.tk 发出了两个请求,然后向 sub.sub.rsdb-test 发出了一个请求。 tk(而你可能期待 rsdb-test.tk,然后是 sub.rsdb-test.tk,然后是 sub.sub.rsdb-test.tk)。
一般来说,重定向似乎按预期工作,我们没有任何简单的方法可以从您的应用程序中删除 ProxyPassReverse 设置。让我知道这个解释是否合理。
我在 Openshift Online http://rsdbtest-abex.rhcloud.com/
上有一个申请。它具有以下域的别名和匹配 CNAME
:
http://rsdb-test.tk/
,http://www.rsdb-test.tk/
,http://sub.rsdb-test.tk/
,http://sub.sub.rsdb-test.tk/
服务器设置为响应 /
express 的请求 object。任何其他路径都会生成 302,并将 Location
header 设置为该路径,因此理论上 http://rsdb-test.tk/http://sub.rsdb-test.tk
的请求会将您带到 http://sub.rsdb-test.tk
。这在本地有效,但是退出 OpenShift 路由器后的位置是 http://rsdb-test.tk
。该域将替换为请求的域。如果您 运行 本地服务器或从齿轮内部卷曲 Location
header 仍然正确,说明我的代码没有问题。
有没有办法解决此问题并重定向到任何域,或者我是否必须使用 <meta>
进行重定向?
侦听的服务器是一个简单的快速服务器:
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");
});
这与 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/
任何时候您的应用程序 returns 重定向到这些主机之一,Apache 都会重写主机部分以匹配原始请求中使用的主机 header。那么,让我们举个例子:
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
您的应用程序 returns:
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
您的申请returns:
http://sub.sub.rsdb-test.tk/
但 ProxyPassReverse 再次将其重写为:
http://rsdb-test.tk/
当您删除结尾的斜杠时,第二个重定向有一个空的 "path" 元素,因此 "ProxyPassReverse / ..." 规则不再匹配它,这是一个不幸的不一致。不过,即使它确实有效,我也不认为它完全按照您的预期进行,因为它向 rsdb-test.tk 发出了两个请求,然后向 sub.sub.rsdb-test 发出了一个请求。 tk(而你可能期待 rsdb-test.tk,然后是 sub.rsdb-test.tk,然后是 sub.sub.rsdb-test.tk)。
一般来说,重定向似乎按预期工作,我们没有任何简单的方法可以从您的应用程序中删除 ProxyPassReverse 设置。让我知道这个解释是否合理。