无url解码的Nginx pass_代理子目录
我需要编写一个nginx location指令,将对子目录的请求代理到另一台服务器保存urlencoding和删除子目录前缀 下面是一个人工示例-请求如下:无url解码的Nginx pass_代理子目录,nginx,Nginx,我需要编写一个nginx location指令,将对子目录的请求代理到另一台服务器保存urlencoding和删除子目录前缀 下面是一个人工示例-请求如下: http://1.2.3.4/api/save/http%3A%2F%2Fexample.com 应作为 http://abcd.com/save/http%3A%2F%2Fexample.com 我试过几种不同的方法。这里有两个: 从 但是它会解码字符串,所以http://abcd.com获取/save/http://example
http://1.2.3.4/api/save/http%3A%2F%2Fexample.com
应作为
http://abcd.com/save/http%3A%2F%2Fexample.com
我试过几种不同的方法。这里有两个:
http://abcd.com
获取/save/http://example.com
http://abcd.com
获取/api/save/http%3A%2F%2Fexample.com
需要的是中间的某个地方。谢谢大家!
UPD:这里有一个在nginx中的bug跟踪器
但是没有简单的方法来修复nginx的这种行为。nginx trac中有一些bug,您可以添加自己的。trac.nginx.org/nginx/…。所以,我认为最简单的方法就是拥有子域亚历克赛10号2月24日15时14分49分
如果您想让nginx做一些定制的事情,可以使用带有变量的proxy_pass(和$request_uri变量,该变量包含客户端发送的原始未经转换的请求uri)。在这种情况下,您将负责执行正确的URI转换。但请注意,这很容易导致安全问题,因此应小心操作
接受挑战
location /api/ {
rewrite ^ $request_uri;
rewrite ^/api/(.*) $1 break;
return 400;
proxy_pass http://127.0.0.1:82/$uri;
}
就这样,伙计们
这是完整的证据
nginx/1.2.1的配置文件:
server {
listen 81;
#first, the solution
location /api/ {
rewrite ^ $request_uri;
rewrite ^/api/(.*) $1 break;
return 400; #if the second rewrite won't match
proxy_pass http://127.0.0.1:82/$uri;
}
#next, a few control groups
location /dec/ {
proxy_pass http://127.0.0.1:82/;
}
location /mec/ {
rewrite ^/mec(/.*) $1 break;
proxy_pass http://127.0.0.1:82;
}
location /nod/ {
proxy_pass http://127.0.0.1:82;
}
}
server {
listen 82;
return 200 $request_uri\n;
}
以下是对每个位置运行查询的结果:
% echo localhost:81/{api,dec,mec,nod}/save/http%3A%2F%2Fexample.com | xargs -n1 curl
/save/http%3A%2F%2Fexample.com
/save/http:/example.com
/save/http:/example.com
/nod/save/http%3A%2F%2Fexample.com
%
注意,有额外的返回400
非常重要-否则,您可能会遇到安全问题(通过//api
等进行文件访问),正如Maxim在您的trac记录单中简要提到的那样
另外,如果您认为将重写引擎用作有限状态自动机非常酷,您可能还想查看我的项目,或者。只要我们讨论前缀匹配与^ ~
或不使用修饰符,您所要做的就相当容易了
location /api/ {
# if you don't want to pass /api/ add a trailing slash to the proxy_pass
proxy_pass http://localhost:8080/;
...
}
所有内容都将在不解码的情况下传递,您不必传递$uri
此外,在使用代理传递时,还应设置这些标头
# pass headers and body along
proxy_pass_request_headers on;
proxy_pass_request_body on;
# set some headers to make sure the reverse proxy is passing along everything necessary
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
你可以和lua一起试试。但首先,您不应该需要这个,根据http规范,这些URL是相同的,可以使用子域而不是subdirectory@AlexeyTen在http://abcd.com
正在以不同的方式处理这些请求,我无法控制它。你知道那个http规范摘录的链接吗?我找不到itRFC 2616第3.2节。3@AlexeyTen它说,除了“保留”和“不安全”集合中的字符(参见RFC 2396[42])之外的其他字符等同于它们的“%”十六进制编码。我不知道RFC 2396中的[42]
是什么,但是RFC中的第2.2节说那些字符是保留的-“;”/“|”?“|”:“|”@“|”&“|”=“|”+“|”$”,“
真的。。谢谢你。真正的哇,当它真的像预期的那样工作的时候。考虑到与现有规则的相似性,神奇之处显然在于$request_uri捕获;重写^/api(/.*)$1中断;返回400;代用通行证;答案应该被接受。非常感谢您在事情突然开始奇怪地工作时给予的帮助!喜欢返回200$request\u uri\n你救了我一天。谢谢!:-)“一切都将被传递”:True,直到用变量替换localhost
上游。
location /api/ {
# if you don't want to pass /api/ add a trailing slash to the proxy_pass
proxy_pass http://localhost:8080/;
...
}
# pass headers and body along
proxy_pass_request_headers on;
proxy_pass_request_body on;
# set some headers to make sure the reverse proxy is passing along everything necessary
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;