server {
listen 80;
server_name ~^(?<custom>.+)\.(test)?website\.com$;
location ~ ^/event/(\d+)$ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_intercept_errors on;
# This is the problematic block
# This conditional breaks the whole location block.
# If I commented the if statement, the default proxy_pass works.
if ($http_user_agent ~* iphone|android) {
# the proxy_pass indeed works, tested on development machine
proxy_pass http://frontends/userland/mobile/event/$1;
break;
}
# When above if conditional is enabled, this fails.
proxy_pass http://frontends/userland/event/$1;
}
}
注意到server_name中的子域匹配器几乎是通配符。
为什么if条件不起作用?如果我所做的是错的,那么重写它的最佳方法是什么?
Nginx版本:1.2.0
答案 0 :(得分:2)
通过评估^/event/(\d+)$
条件中的iphone|android
,您可以从if
覆盖PCRE捕获。因此,在执行重写规则后,$1
变量为空。
尝试这样的事情:
set $num $1;
if ($http_user_agent ~* iphone|android) {
proxy_pass http://frontends/userland/mobile/event/$num;
}
proxy_pass http://frontends/userland/event/$num;
答案 1 :(得分:0)
请参阅this和this, in particular,了解为什么“如果”在Nginx中可能是邪恶的。
事物的继承方式往往不能遵循预期的形式和指令,例如“return”和“rewrite”(带有“last”)是在Nginx“if”块中使用的唯一真正可靠的。
我会尝试这样的事情:
server {
listen 80;
server_name ~^(?<custom>.+)\.(test)?website\.com$;
location ~ ^/event/(\d+)$ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_intercept_errors on;
if ($http_user_agent ~* iphone|android) {
return 302 http://frontends/userland/mobile/event/$1;
# Alternative syntax which should keep original url in browser
#rewrite ^ http://frontends/userland/mobile/event/$1 last;
}
proxy_pass http://frontends/userland/event/$1;
}
}