使用 ngx.location.capture() 方法对预定义的位置块执行子请求。然后,从 location 块中,执行外部的 FastCGI 请求。因为子请求本身实际上并不是网络操作,而是纯粹在基于 Nginx C 的环境中执行,所以开销很小。此外,因为 FastCGI 请求和其他“proxy_pass”类型的请求是基于事件的,所以 nginx 可以作为一个有效的中介。
例如,您可以拥有以下内容:
location / {
access_by_lua '
response = ngx.location.capture("/my-subrequest-handler")
if response.status == 404 then
return ngx.exit(401) -- can't find/authenticate user, refuse request
end
ngx.say(response.status)
';
# other nginx config stuff here as necessary--perhaps another fastcgi_pass
# depending upon the status code of the response above...
}
location = /my-subrequest-handler {
internal; # this location block can only be seen by nginx subrequests
fastcgi_pass localhost:9000; # or some named "upstream"
fastcgi_pass_request_body off; # send client request body upstream?
fastcgi_pass_request_headers off; # send client request headers upstream?
fastcgi_connect_timeout 100ms; # optional; control backend timeouts
fastcgi_send_timeout 100ms; # same
fastcgi_read_timeout 100ms; # same
fastcgi_keep_conn on; # keep request alive
include fastcgi_params;
}
在上面的示例中,即使我正在对“/my-subrequest-handler”执行子请求,传递给 FastCGI 进程的实际 URL 也是 HTTP 客户端首先调用 nginx 请求的 URL。
请注意,ngx.location.capture 是一个同步但非阻塞的操作,这意味着您的代码执行将停止,直到收到响应,但 nginx 工作人员在此期间可以自由地执行其他操作。
你可以用 Lua 做一些很酷的事情来修改 nginx 管道中的任何点的请求和响应。例如,您可以通过添加标头、删除标头甚至转换正文来更改原始请求。也许调用者想使用 XML,但上游应用程序只理解 JSON,我们可以在调用上游应用程序时转换为 JSON 或从 JSON 转换。
Lua 默认没有内置在 nginx 中。相反,它是一个必须编译的第 3 方模块。有一种称为OpenResty的 nginx ,它构建在 Lua+LuaJIT 以及一些您可能需要或可能不需要的其他模块中。