NGINX:给定自定义子域,与$ http_user_agent条件匹配的位置正则表达式不起作用

时间:2012-06-04 04:15:34

标签: configuration nginx

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

2 个答案:

答案 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)

请参阅thisthis, 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;
    }
}