如何在ngx_http_lua_module里面传递给Nginx fastcgi_pass?

How to pass to Nginx fastcgi_pass inside ngx_http_lua_module?

我需要使用出色的库 https://github.com/openresty/lua-nginx-module

将 Nginx 变量传递到我的 PHP 7.0 后端

我更喜欢使用 content_by_lua_block 而不是 set_by_lua_block,因为 'set' 函数的文档指出 "This directive is designed to execute short, fast running code blocks as the Nginx event loop is blocked during code execution. Time consuming code sequences should therefore be avoided."。 https://github.com/openresty/lua-nginx-module#set_by_lua

但是,由于'content_...'函数是非阻塞的,所以下面的代码没有及时return,传递给PHP时$hello是未设置的:

location ~ \.php{
    set $hello '';

    content_by_lua_block {
        ngx.var.hello = "hello there.";
    }

    fastcgi_param HELLO $hello;
    include fastcgi_params;
    ...
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}

问题是,如果采用某些代码路径,例如使用加密,我的 Lua 代码有可能成为 "time consuming code sequences"。

以下 Nginx 位置工作得很好,但那是因为 set_by_lua_block() 是一个阻塞函数调用:

location ~ \.php {
    set $hello '';

    set_by_lua_block $hello {
        return "hello there.";
    }

    fastcgi_param HELLO $hello;
    include fastcgi_params;
    ...
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}

我的问题是,最好的方法是什么?只有在设置了我的变量后,才有办法从 content_by_lua_block() 中调用 Nginx 指令 fastcgi_pass 和相关指令吗?

是的,ngx.location.capture 是可能的。写一个单独的位置块,例如:

    location /lua-subrequest-fastcgi {
        internal;   # this location block can only be seen by Nginx subrequests

        # Need to transform the %2F back into '/'.  Do this with set_unescape_uri()
        # Nginx appends '$arg_' to arguments passed to another location block.
        set_unescape_uri $r_uri $arg_r_uri;
        set_unescape_uri $r_hello $arg_hello;

        fastcgi_param HELLO $r_hello;

        try_files $r_uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index index.php;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

你可以这样称呼:

    location ~ \.php {
        set $hello '';

        content_by_lua_block {
            ngx.var.hello = "hello, friend."

            -- Send the URI from here (index.php) through the args list to the subrequest location.
            -- Pass it from here because the URI in that location will change to "/lua-subrequest-fastcgi"
            local res = ngx.location.capture ("/lua-subrequest-fastcgi", {args = {hello = ngx.var.hello, r_uri = ngx.var.uri}})

            if res.status == ngx.HTTP_OK then
                ngx.say(res.body)
            else
                ngx.say(res.status)
            end
        }
    }