为什么使用 content_by_lua_block 可以让 nginx 的 location 指令通过?

我正在使用 openresty/1.15.8.2 作为代理,对一个有时需要接受较大文件的应用程序进行代理。

我想有条件地设置 client_max_body_size 200M,只有期望文件的 URL 才接受大的正文大小。我尝试的第一件事是把 URL 检查放在 if 语句中,如下所示:

if ($url ~ /path/to/file/upload) {
    content_max_body_size 200M;
}

这并不起作用,因为 nginx 说“content_max_body_size”指令不允许出现在这里。

接下来我尝试了一个嵌套的位置块,如下所示:

location ~ ^(mypatterns)$ {
    # 做一些事情

    location ~ ^/path/for/file/upload$ {
        client_max_body_size 200M;
    }

    # 做一些事情
    proxy_pass whatever;
}

但是这并不起作用。我得到了一个错误,如下所示:

*14941 open() "/.../path/for/file/upload" failed (2: No such file or directory), ...

这意味着嵌套的位置尝试查找要提供的文件,而不是通过到外部位置块的其余部分。

然而,如果在嵌套的位置中设置一个空的 content_by_lua_block {} 指令,它就可以正常工作:

location ~ ^(mypatterns)$ {
    # 做一些事情

    location ~ ^/path/for/file/upload$ {
        client_max_body_size 200M;
        content_by_lua_block {}
    }

    # 做一些事情
    proxy_pass whatever;
}

现在:

  1. 只有 /path/for/file/uploads 允许使用大型正文大小
  2. 匹配该路径的请求也会“穿过”到其余的东西和 proxy_pass

它做到了我想要的,但是为什么?调用 content_by_lua_block 指令有什么特别之处,使其通过?如何在普通 nginx 中使其通过,而不需要 content_by_lua_block

请注意,如果我将其拆分为两个单独的非嵌套位置指令,它仍然可以正常工作。

点赞