我遇到了Nginx的一个奇怪的问题。 这是一个重现错误的最小configuration:
server { server_name mydomain.com; listen 111.111.111.111:80; root /some/path; set $some_var $sent_http_content_type; add_header "X-Debug" $sent_http_content_type; }
在这种情况下, X-Debug头文件在响应中从不显示。 但是,如果我评论这一行:
set $some_var $sent_http_content_type;
一切正常。 这对我来说似乎很奇怪,因为这行不会重新分配$sent_http_content_type var,但只能读取。
它看起来像只属于$sent_http_variables。
我也尝试了"${sent_http_content_type}"而不是$sent_http_content_type ,结果相同。
more_set_headers指令不能解决这个问题。
为什么Nginx的行为如此呢? 这是一个错误?
编辑:
我提供的例子只是最简单的情况,其中$sent_http_ vars消失。 其实我想做这样的事情:
if ($sent_http_access_control_allow_origin ~ "^(https?)://([^/]+)") { set $new_cors http://$1.$2.proxy.mydomain.com; } more_set_headers "Access-Control-Allow-Origin: $new_cors";
我写了一个代理服务器,我需要replaceAccess-Control-Allow-Origin响应头,因为否则代理的网站不能按预期工作。
在上面的例子中, if条件(在server部分)永远不会成true ,即使有这样的头,它适合我的正则expression式。
这可以解决吗? 感谢你的帮助!
Nginx的rewrite模块(variables和set指令所在的地方)是非常直观和脆弱的。 但实际上
set $some_var $sent_http_content_type;
无论如何,因为set指令是在请求开始时执行的,并且没有$sent_http_*variables可用。
你可以做什么(如果你真的想用$sent_http_*variables)是使用map指令。
map $sent_http_content_type $some_var { default $sent_http_content_type; } ... server { ... add_header "X-Debug" $sent_http_content_type; add_header "X-Debug2" $some_var; }
编辑:你的问题可以用更多的map解决,但如果你可以使用Lua模块,会更容易。
这里怎么可以用map完成:(很难读,不可维护)
map $sent_http_access_control_allow_origin $__proto { default "NONE"; "~^(?<_>https?):" "$_"; } map $sent_http_access_control_allow_origin $__host { default ""; "~^https?://(?<_>[^/]+)" "$_"; } map "http://$__proto.$__host.proxy.mydomain.com" $new_cors { default ""; "~^http://NONE" ""; "~^(?<_>.+)$" "$_"; }