rack: 一个简单且可扩展的 HTTP 服务器框架,用于 nginx-module-lua
安装
如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。
CentOS/RHEL 7 或 Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-rack
CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-rack
要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua。
本文档描述了 lua-resty-rack v0.3,于 2012 年 7 月 12 日发布。
这是一个简单且可扩展的 HTTP 服务器框架,用于 OpenResty,提供了一种干净的方法将 Lua HTTP 应用程序(“resty”模块)加载到 Nginx 中。
受到 Rack 和 Connect 的启发,lua-resty-rack 允许您将应用程序作为中间件的一部分加载,与其他中间件一起使用。您的应用程序可以选择忽略当前请求、以某种方式修改请求或响应并传递给其他中间件,或者通过生成响应来承担请求的责任。
使用中间件
要为给定的 location 安装中间件,您只需按希望模块运行的顺序调用 rack.use(middleware),然后最后调用 rack.run()。
server {
location / {
content_by_lua '
local rack = require "resty.rack"
rack.use(rack.middleware.method_override)
rack.use(require "my.module")
rack.run()
';
}
}
rack.use(...)
语法: rack.use(route?, middleware, options?)
如果提供了 route,则中间件仅在请求的路径中包含 route 时运行。如果中间件需要选择任何选项,可以作为第三个参数提供,通常是一个表。
rack.use('/some/path', app, { foo = 'bar' })
对于简单情况,middleware 参数也可以是一个简单的函数,而不是 Lua 模块。您的函数应接受 req、res 和 next 作为参数。有关编写中间件的说明,请参见下文。
rack.use(function(req, res, next)
res.header["X-Homer"] = "Doh!"
next()
end)
rack.run()
语法: rack.run()
按顺序运行每个中间件,直到其中一个选择处理响应。因此,调用 rack.use() 的顺序很重要。
捆绑的中间件
method_override
rack.use(rack.middleware.method_override, { key = "METHOD" })
使用查询字符串值覆盖 HTTP 方法。默认参数名称为 "_method",但可以通过设置选项 "key" 来覆盖。
read_request_headers
rack.use(rack.middleware.read_request_headers, { max = 50 })
仅在您希望遍历 HTTP 请求头时需要。它们将在通过 req.header 访问时懒加载。
您可以指定要读取的请求头的数量限制,默认为 100。通过指定最大值为 0 可以移除限制,但 强烈不建议。
read_body
rack.use(rack.middleware.read_body)
显式读取请求体(原始)。
创建中间件
中间件应用程序只是使用 HTTP 请求和响应作为最小接口的 Lua 模块。它们必须实现函数 call(options),该函数返回一个函数。参数 (req, res, next) 定义如下。
module("resty.rack.method_override", package.seeall)
_VERSION = '0.01'
function call(options)
return function(req, res, next)
local key = options['key'] or '_method'
req.method = string.upper(req.args[key] or req.method)
next()
end
end
API
req.method
HTTP 方法,例如 GET,由 ngx.var.request_method 设置。
req.scheme
协议方案 http|https,由 ngx.var.scheme 设置。
req.uri
例如 /my/uri,由 ngx.var.uri 设置。
req.host
主机名,例如 example.com,由 ngx.var.host 设置。
req.query
查询字符串,例如 var1=1&var2=2,由 ngx.var.query_string 设置。
req.args
查询参数,以 table 形式设置,来自 ngx.req.get_uri_args()。
req.header
一个包含请求头的表。键不区分大小写,并且可以选择用下划线代替连字符。例如:
req.header["X-Foo"] = "bar"
res.body = req.header.x_foo
--> "bar"
HTTP 请求头是按需读取的,因此除非使用 read_request_headers 中间件,否则无法遍历。
req.body
在使用 read_body 中间件读取之前为空字符串。
res.status
要返回的 HTTP 状态码。常见状态的 常量已定义。
res.header
一个响应头的表,可以不区分大小写地匹配,并且可以选择用下划线代替连字符(见上面的 req.header)。
res.body
响应体。
next
此参数是提供给中间件的一个函数,可以调用它以指示 rack 应该尝试下一个中间件。如果您的应用程序不打算将响应发送到浏览器,则必须调用此函数。然而,如果您的应用程序负责响应,则只需返回而不调用 next。
示例仅修改请求。
function call(options)
return function(req, res, next)
local key = options['key'] or '_method'
req.method = string.upper(req.args[key] or req.method)
next()
end
end
示例生成响应。
function call(options)
return function(req, res)
res.status = 200
res.header['Content-Type'] = "text/plain"
res.body = "Hello World"
end
end
增强 req / res
您的应用程序可以在适当的情况下向 req / res 表添加新字段或甚至函数,这些字段或函数可以被其他中间件使用,只要依赖关系清晰(并且按正确的顺序调用 use())。
GitHub
您可以在 nginx-module-rack 的 GitHub 仓库 中找到有关此模块的其他配置提示和文档。