doufengsui7449
2016-08-02 01:03
浏览 181
已采纳

如何在ngx_http_lua_module中传递给Nginx fastcgi_pass?

I need to pass an Nginx variable to my PHP 7.0 backend using the excellent library https://github.com/openresty/lua-nginx-module

I prefer to use content_by_lua_block instead of set_by_lua_block, because the documentation for the 'set' function states "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

However, since the 'content_...' function is non-blocking, the following code does not return in time, and $hello is unset when passed to PHP:

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;
}

The problem is, my Lua code has the potential to be "time consuming code sequences" if certain code paths are taken, using crypto for example.

The following Nginx location works just fine, but that's because set_by_lua_block() is a blocking function call:

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;
}

My question is, what is the best approach here? Is there a way to call the Nginx directive fastcgi_pass and related directives from within a content_by_lua_block() only after my variables have been set?

图片转代码服务由CSDN问答提供 功能建议

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

I 更喜欢使用 content_by_lua_block 而不是 set_by_lua_block ,因为'set'函数的文档声明“此指令旨在执行短的,快速运行的代码块作为Nginx事件循环 在代码执行期间被阻止。因此应该避免耗费时间的代码序列。“。 https: //github.com/openresty/lua-nginx-module#set_by_lua

但是,由于'content _...'函数是非阻塞的,因此以下代码执行此操作 不能及时返回,并且传递给PHP时未设置$ hello:

  location~ \ .php {
 set $ hello''; 
 
 content_by_lua_block {\  n ngx.va  r.hello =“你好。”; 
} 
 
 fastcgi_param HELLO $ hello; 
包括fastcgi_params; 
 ... 
 fastcgi_pass unix:/run/php/php7.0-fpm.sock;  
} 
   
 
 

问题是,如果采用某些代码路径,我的Lua代码有可能成为“耗时的代码序列”,例如使用加密。

以下Nginx位置工作正常,但这是因为set_by_lua_block()是一个阻塞函数调用:

  location~ \ .php  {
 set $ hello''; 
 
 set_by_lua_block $ hello {
 return“hello there。”; 
} 
 
 fastcgi_param HELLO $ hello; 
包括fastcgi_params; 
 ... 
  fastcgi_pass unix:/run/php/php7.0-fpm.sock; 
} 
   
 
 

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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dtyqflrr775518 2016-08-03 11:10
    已采纳

    Yes, it's possible with ngx.location.capture. Write a separate location block, example:

        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;
        }
    

    Which you can then call thusly:

        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
            }
        }
    
    点赞 评论

相关推荐 更多相似问题