Skip to content

Latest commit

 

History

History
149 lines (97 loc) · 4.52 KB

access_by_lua.md

File metadata and controls

149 lines (97 loc) · 4.52 KB

access_by_lua

语法: access_by_lua <lua-script-str>

环境: http, server, location, location if

阶段: access tail

扮演 access 阶段处理,对每次请求执行在<lua-script-str>中指名的 Lua 代码。

这些 Lua 代码可以调用全部 API,并作为一个新的协程,在一个独立的全局环境中执行(就像一个沙盒)。

注意:本指令的处理总是在标准ngx_http_access_module面。所以下面的示例可以按照预期工作:

 location / {
     deny    192.168.1.1;
     allow   192.168.1.0/24;
     allow   10.1.1.0/16;
     deny    all;

     access_by_lua '
         local res = ngx.location.capture("/mysql", { ... })
         ...
     ';

     # proxy_pass/fastcgi_pass/...
 }

换句话说,如果一个客户端 IP 地址在黑名单中,它将在 access_by_lua中的 Mysql 复杂认证请求之前被拒绝。

注意,ngx_auth_request模块可以近似的被access_by_lua实现:

 location / {
     auth_request /auth;

     # proxy_pass/fastcgi_pass/postgres_pass/...
 }

使用 ngx_lua 是这样:

 location / {
     access_by_lua '
         local res = ngx.location.capture("/auth")

         if res.status == ngx.HTTP_OK then
             return
         end

         if res.status == ngx.HTTP_FORBIDDEN then
             ngx.exit(res.status)
         end

         ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
     ';

     # proxy_pass/fastcgi_pass/postgres_pass/...
 }

和其他access阶段处理实现,access_by_lua能运行在子请求中。

注意,在access_by_lua处理内部,当调用ngx.exit(ngx.OK)时,nginx请求将继续下一阶段的内容处理。要在access_by_lua处理中终结当前请求,调用ngx.exit,成功的请求设定 status >= 200 (ngx.HTTP_OK) 并 status < 300 (ngx.HTTP_SPECIAL_RESPONSE),失败的请求设定ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (或其他相关的)。

返回目录

English source:

access_by_lua

syntax: access_by_lua <lua-script-str>

context: http, server, location, location if

phase: access tail

Acts as an access phase handler and executes Lua code string specified in <lua-script-str> for every request. The Lua code may make API calls and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).

Note that this handler always runs after the standard ngx_http_access_module. So the following will work as expected:

 location / {
     deny    192.168.1.1;
     allow   192.168.1.0/24;
     allow   10.1.1.0/16;
     deny    all;

     access_by_lua '
         local res = ngx.location.capture("/mysql", { ... })
         ...
     ';

     # proxy_pass/fastcgi_pass/...
 }

That is, if a client IP address is in the blacklist, it will be denied before the MySQL query for more complex authentication is executed by access_by_lua.

Note that the ngx_auth_request module can be approximated by using access_by_lua:

 location / {
     auth_request /auth;

     # proxy_pass/fastcgi_pass/postgres_pass/...
 }

can be implemented in ngx_lua as:

 location / {
     access_by_lua '
         local res = ngx.location.capture("/auth")

         if res.status == ngx.HTTP_OK then
             return
         end

         if res.status == ngx.HTTP_FORBIDDEN then
             ngx.exit(res.status)
         end

         ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
     ';

     # proxy_pass/fastcgi_pass/postgres_pass/...
 }

As with other access phase handlers, access_by_lua will not run in subrequests.

Note that when calling ngx.exit(ngx.OK) within a access_by_lua handler, the nginx request processing control flow will still continue to the content handler. To terminate the current request from within a access_by_lua handler, calling ngx.exit with status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (or its friends) for failures.

Back to TOC