使用变量配置 proxy_pass 失败。为什么?

使用变量配置 proxy_pass 失败。为什么?

我对 nginx 变量以及它们的工作原理有哪些误解?

第一个位置 /atlas/ 无法将请求发送到上游服务器,并出现以下 nginx 错误:

backoffice  | 2024/03/12 22:10:19 [error] 17#17: *9 invalid URL prefix in "", client: 192.168.247.15, server: ~^(backoffice\.)(?<domain>.+)$, request: "GET /atlas/assets/main.css HTTP/1.1", host: "backoffice.local.upowr.io", referrer: "https://backoffice.local.upowr.io/atlas/?latitude=-32.912492&longitude=151.314799&roof_id=c0876d8d-8712-464e-8815-b963d675e8ea&phase_num=1&task_mode=true"

但是几乎等效的位置定义 /atlas-og/ 确实使用变量但不使用第二级间接来配置 proxy_pass 指令,也可以正常工作。

为什么?

 location /atlas/ {
        rewrite ^/atlas/(.*)$ /$1 break;

        set $proxy_pass $ATLAS_UI_ENDPOINT$uri$is_args$args;
        proxy_pass $proxy_pass;
    }

    location /atlas-og/ {
        rewrite ^/atlas-og/(.*)$ /$1 break;

        proxy_pass $ATLAS_UI_ENDPOINT$uri$is_args$args;
    }

更新

location /atlas/ {
    rewrite ^/atlas/(.*)$ /$1 break;

    proxy_pass $ATLAS_UI_ENDPOINT;
}

set $proxy_pass_outer $ATLAS_UI_ENDPOINT;

location /atlas-outer/ {
    rewrite ^/atlas-outer/(.*)$ /$1 break;

    proxy_pass $proxy_pass_outer;
}

location /atlas-inner/ {
    rewrite ^/atlas-inner/(.*)$ /$1 break;

    set $proxy_pass_inner $ATLAS_UI_ENDPOINT;
    proxy_pass $proxy_pass_inner;

}

因此,前两个可以工作,但第三个则不可以。

看起来 proxy_pass 不能使用 location 指令中定义的变量,事实上,nginx 对此发出警告:

backoffice  | 2024/03/13 00:53:32 [warn] 17#17: *23 using uninitialized "proxy_pass_inner" variable, client: 192.168.247.15, server: ~^(backoffice\.)(?<domain>.+)$, request: "GET /atlas-inner/?latitude=-32.912492&longitude=151.314799&roof_id=c0876d8d-8712-464e-8815-b963d675e8ea&phase_num=1&task_mode=true HTTP/1.1", host: "backoffice.local.upowr.io"

所以问题归结为:为什么 proxy_pass 尊重在服务器范围内设置的变量,而不尊重在位置范围内设置的变量?

答案1

好的,我终于搞定了。

set 指令相对于 rewrite 指令的顺序很重要。

location /atlas-fixed/ {
        set $proxy_pass_inner $ATLAS_UI_ENDPOINT;
        rewrite ^/atlas-inner/(.*)$ /$1 break;

        proxy_pass $proxy_pass_inner;

        include includes/location/backoffice.conf;
        include includes/policy/do-not-preserve-host-header.conf;
}

然而这是错误的:

location /atlas-broken/ {
        rewrite ^/atlas-inner/(.*)$ /$1 break;
        set $proxy_pass_inner $ATLAS_UI_ENDPOINT;

        proxy_pass $proxy_pass_inner;

        include includes/location/backoffice.conf;
        include includes/policy/do-not-preserve-host-header.conf;
}

当我看到这条评论时我恍然大悟:

请注意,nginx 配置是声明性的,而不是命令性的,并且 set ... 实际上是在处理重写模块指令期间发生的。这发生在选择适当位置之后和访问检查(尤其是 auth_request)之前。

https://trac.nginx.org/nginx/ticket/2294

相关内容